bitkeeper revision 1.1476 (428d0d8esmCTqdrDnpEQ1XlfV6CWGg)
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 19 May 2005 22:05:02 +0000 (22:05 +0000)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 19 May 2005 22:05:02 +0000 (22:05 +0000)
New qemu-based ioemu for fully virtualised guests.
Signed-off-by: Arun Sharma <arun.sharma@intel.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
317 files changed:
.rootkeys
tools/Makefile
tools/ioemu/COPYING [new file with mode: 0644]
tools/ioemu/COPYING.LIB [new file with mode: 0644]
tools/ioemu/Changelog [new file with mode: 0644]
tools/ioemu/Makefile
tools/ioemu/Makefile.target [new file with mode: 0644]
tools/ioemu/README [new file with mode: 0644]
tools/ioemu/README.distrib [new file with mode: 0644]
tools/ioemu/TODO [new file with mode: 0644]
tools/ioemu/VERSION [new file with mode: 0644]
tools/ioemu/block-cloop.c [new file with mode: 0644]
tools/ioemu/block-cow.c [new file with mode: 0644]
tools/ioemu/block-qcow.c [new file with mode: 0644]
tools/ioemu/block-vmdk.c [new file with mode: 0644]
tools/ioemu/block.c [new file with mode: 0644]
tools/ioemu/block_int.h [new file with mode: 0644]
tools/ioemu/bswap.h [new file with mode: 0644]
tools/ioemu/configure [new file with mode: 0755]
tools/ioemu/console.c [new file with mode: 0644]
tools/ioemu/cpu-all.h [new file with mode: 0644]
tools/ioemu/cpu-defs.h [new file with mode: 0644]
tools/ioemu/cpu.h [new file with mode: 0644]
tools/ioemu/create_keysym_header.sh [new file with mode: 0644]
tools/ioemu/exec-all.h [new file with mode: 0644]
tools/ioemu/exec.c [new file with mode: 0644]
tools/ioemu/font/vga.bitmap.h [deleted file]
tools/ioemu/gui/Makefile [deleted file]
tools/ioemu/gui/Makefile.in [deleted file]
tools/ioemu/gui/bitmaps/cdromd.h [deleted file]
tools/ioemu/gui/bitmaps/cdromd.xpm [deleted file]
tools/ioemu/gui/bitmaps/configbutton.h [deleted file]
tools/ioemu/gui/bitmaps/configbutton.xpm [deleted file]
tools/ioemu/gui/bitmaps/copy.h [deleted file]
tools/ioemu/gui/bitmaps/copy.xpm [deleted file]
tools/ioemu/gui/bitmaps/floppya.h [deleted file]
tools/ioemu/gui/bitmaps/floppya.xpm [deleted file]
tools/ioemu/gui/bitmaps/floppyb.h [deleted file]
tools/ioemu/gui/bitmaps/floppyb.xpm [deleted file]
tools/ioemu/gui/bitmaps/mouse.h [deleted file]
tools/ioemu/gui/bitmaps/mouse.xpm [deleted file]
tools/ioemu/gui/bitmaps/paste.h [deleted file]
tools/ioemu/gui/bitmaps/paste.xpm [deleted file]
tools/ioemu/gui/bitmaps/power.h [deleted file]
tools/ioemu/gui/bitmaps/power.xpm [deleted file]
tools/ioemu/gui/bitmaps/reset.h [deleted file]
tools/ioemu/gui/bitmaps/reset.xpm [deleted file]
tools/ioemu/gui/bitmaps/snapshot.h [deleted file]
tools/ioemu/gui/bitmaps/snapshot.xpm [deleted file]
tools/ioemu/gui/bitmaps/userbutton.h [deleted file]
tools/ioemu/gui/bitmaps/userbutton.xpm [deleted file]
tools/ioemu/gui/gui.cc [deleted file]
tools/ioemu/gui/gui.h [deleted file]
tools/ioemu/gui/icon_bochs.h [deleted file]
tools/ioemu/gui/icon_bochs.xpm [deleted file]
tools/ioemu/gui/keymap.cc [deleted file]
tools/ioemu/gui/keymap.h [deleted file]
tools/ioemu/gui/keymaps/convertmap.pl [deleted file]
tools/ioemu/gui/keymaps/sdl-pc-de.map [deleted file]
tools/ioemu/gui/keymaps/sdl-pc-us.map [deleted file]
tools/ioemu/gui/keymaps/x11-pc-be.map [deleted file]
tools/ioemu/gui/keymaps/x11-pc-da.map [deleted file]
tools/ioemu/gui/keymaps/x11-pc-de.map [deleted file]
tools/ioemu/gui/keymaps/x11-pc-es.map [deleted file]
tools/ioemu/gui/keymaps/x11-pc-fr.map [deleted file]
tools/ioemu/gui/keymaps/x11-pc-it.map [deleted file]
tools/ioemu/gui/keymaps/x11-pc-se.map [deleted file]
tools/ioemu/gui/keymaps/x11-pc-uk.map [deleted file]
tools/ioemu/gui/keymaps/x11-pc-us.map [deleted file]
tools/ioemu/gui/nogui.cc [deleted file]
tools/ioemu/gui/rfb.cc [deleted file]
tools/ioemu/gui/rfb.h [deleted file]
tools/ioemu/gui/rfbproto.h [deleted file]
tools/ioemu/gui/sdl.h [deleted file]
tools/ioemu/gui/sdlkeys.h [deleted file]
tools/ioemu/gui/siminterface.cc [deleted file]
tools/ioemu/gui/siminterface.h [deleted file]
tools/ioemu/gui/svga.cc [deleted file]
tools/ioemu/gui/term.cc [deleted file]
tools/ioemu/gui/textconfig.cc [deleted file]
tools/ioemu/gui/textconfig.h [deleted file]
tools/ioemu/gui/x.cc [deleted file]
tools/ioemu/hw/adb.c [new file with mode: 0644]
tools/ioemu/hw/adlib.c [new file with mode: 0644]
tools/ioemu/hw/cirrus_vga.c [new file with mode: 0644]
tools/ioemu/hw/cirrus_vga_rop.h [new file with mode: 0644]
tools/ioemu/hw/cirrus_vga_rop2.h [new file with mode: 0644]
tools/ioemu/hw/cuda.c [new file with mode: 0644]
tools/ioemu/hw/dma.c [new file with mode: 0644]
tools/ioemu/hw/fdc.c [new file with mode: 0644]
tools/ioemu/hw/fmopl.c [new file with mode: 0644]
tools/ioemu/hw/fmopl.h [new file with mode: 0644]
tools/ioemu/hw/i8254.c [new file with mode: 0644]
tools/ioemu/hw/i8259.c [new file with mode: 0644]
tools/ioemu/hw/ide.c [new file with mode: 0644]
tools/ioemu/hw/iommu.c [new file with mode: 0644]
tools/ioemu/hw/lance.c [new file with mode: 0644]
tools/ioemu/hw/m48t08.c [new file with mode: 0644]
tools/ioemu/hw/m48t08.h [new file with mode: 0644]
tools/ioemu/hw/m48t59.c [new file with mode: 0644]
tools/ioemu/hw/m48t59.h [new file with mode: 0644]
tools/ioemu/hw/magic-load.c [new file with mode: 0644]
tools/ioemu/hw/mc146818rtc.c [new file with mode: 0644]
tools/ioemu/hw/ne2000.c [new file with mode: 0644]
tools/ioemu/hw/openpic.c [new file with mode: 0644]
tools/ioemu/hw/pc.c [new file with mode: 0644]
tools/ioemu/hw/pci.c [new file with mode: 0644]
tools/ioemu/hw/pckbd.c [new file with mode: 0644]
tools/ioemu/hw/ppc.c [new file with mode: 0644]
tools/ioemu/hw/ppc_chrp.c [new file with mode: 0644]
tools/ioemu/hw/ppc_prep.c [new file with mode: 0644]
tools/ioemu/hw/sb16.c [new file with mode: 0644]
tools/ioemu/hw/sched.c [new file with mode: 0644]
tools/ioemu/hw/serial.c [new file with mode: 0644]
tools/ioemu/hw/sun4m.c [new file with mode: 0644]
tools/ioemu/hw/tcx.c [new file with mode: 0644]
tools/ioemu/hw/timer.c [new file with mode: 0644]
tools/ioemu/hw/vga.c [new file with mode: 0644]
tools/ioemu/hw/vga_int.h [new file with mode: 0644]
tools/ioemu/hw/vga_template.h [new file with mode: 0644]
tools/ioemu/i386-vl.ld [new file with mode: 0644]
tools/ioemu/i386.ld [new file with mode: 0644]
tools/ioemu/include/bochs.h [deleted file]
tools/ioemu/include/bxversion.h [deleted file]
tools/ioemu/include/config.h [deleted file]
tools/ioemu/include/cpu/cpu.h [deleted file]
tools/ioemu/include/extplugin.h [deleted file]
tools/ioemu/include/instrument.h [deleted file]
tools/ioemu/include/ltdl.h [deleted file]
tools/ioemu/include/ltdlconf.h [deleted file]
tools/ioemu/include/osdep.h [deleted file]
tools/ioemu/include/pc_system.h [deleted file]
tools/ioemu/include/plugin.h [deleted file]
tools/ioemu/include/state_file.h [deleted file]
tools/ioemu/iodev/Makefile [deleted file]
tools/ioemu/iodev/aspi-win32.h [deleted file]
tools/ioemu/iodev/biosdev.cc [deleted file]
tools/ioemu/iodev/biosdev.h [deleted file]
tools/ioemu/iodev/cdrom.cc [deleted file]
tools/ioemu/iodev/cdrom.h [deleted file]
tools/ioemu/iodev/cdrom_beos.h [deleted file]
tools/ioemu/iodev/cmos.cc [deleted file]
tools/ioemu/iodev/cmos.h [deleted file]
tools/ioemu/iodev/cpu.cc [deleted file]
tools/ioemu/iodev/crc32.cc [deleted file]
tools/ioemu/iodev/crc32.h [deleted file]
tools/ioemu/iodev/devices.cc [deleted file]
tools/ioemu/iodev/dma.cc [deleted file]
tools/ioemu/iodev/dma.h [deleted file]
tools/ioemu/iodev/eth.cc [deleted file]
tools/ioemu/iodev/eth.h [deleted file]
tools/ioemu/iodev/eth_arpback.cc [deleted file]
tools/ioemu/iodev/eth_fbsd.cc [deleted file]
tools/ioemu/iodev/eth_linux.cc [deleted file]
tools/ioemu/iodev/eth_null.cc [deleted file]
tools/ioemu/iodev/eth_packetmaker.cc [deleted file]
tools/ioemu/iodev/eth_packetmaker.h [deleted file]
tools/ioemu/iodev/eth_tap.cc [deleted file]
tools/ioemu/iodev/eth_tuntap.cc [deleted file]
tools/ioemu/iodev/extfpuirq.cc [deleted file]
tools/ioemu/iodev/extfpuirq.h [deleted file]
tools/ioemu/iodev/floppy.cc [deleted file]
tools/ioemu/iodev/floppy.h [deleted file]
tools/ioemu/iodev/gameport.cc [deleted file]
tools/ioemu/iodev/gameport.h [deleted file]
tools/ioemu/iodev/guest2host.h [deleted file]
tools/ioemu/iodev/harddrv.cc [deleted file]
tools/ioemu/iodev/harddrv.h [deleted file]
tools/ioemu/iodev/ioapic.cc [deleted file]
tools/ioemu/iodev/ioapic.h [deleted file]
tools/ioemu/iodev/iodebug.cc [deleted file]
tools/ioemu/iodev/iodebug.h [deleted file]
tools/ioemu/iodev/iodev.h [deleted file]
tools/ioemu/iodev/keyboard.cc [deleted file]
tools/ioemu/iodev/keyboard.h [deleted file]
tools/ioemu/iodev/load32bitOShack.cc [deleted file]
tools/ioemu/iodev/logio.cc [deleted file]
tools/ioemu/iodev/main.cc [deleted file]
tools/ioemu/iodev/ne2k.cc [deleted file]
tools/ioemu/iodev/ne2k.h [deleted file]
tools/ioemu/iodev/osdep.cc [deleted file]
tools/ioemu/iodev/parallel.cc [deleted file]
tools/ioemu/iodev/parallel.h [deleted file]
tools/ioemu/iodev/pc_system.cc [deleted file]
tools/ioemu/iodev/pci.cc [deleted file]
tools/ioemu/iodev/pci.h [deleted file]
tools/ioemu/iodev/pci2isa.cc [deleted file]
tools/ioemu/iodev/pci2isa.h [deleted file]
tools/ioemu/iodev/pciusb.cc [deleted file]
tools/ioemu/iodev/pciusb.h [deleted file]
tools/ioemu/iodev/pcivga.cc [deleted file]
tools/ioemu/iodev/pcivga.h [deleted file]
tools/ioemu/iodev/pic.cc [deleted file]
tools/ioemu/iodev/pic.h [deleted file]
tools/ioemu/iodev/pit.cc [deleted file]
tools/ioemu/iodev/pit.h [deleted file]
tools/ioemu/iodev/pit82c54.cc [deleted file]
tools/ioemu/iodev/pit82c54.h [deleted file]
tools/ioemu/iodev/pit_wrap.cc [deleted file]
tools/ioemu/iodev/pit_wrap.h [deleted file]
tools/ioemu/iodev/plugin.cc [deleted file]
tools/ioemu/iodev/scancodes.cc [deleted file]
tools/ioemu/iodev/scancodes.h [deleted file]
tools/ioemu/iodev/scsi_commands.h [deleted file]
tools/ioemu/iodev/scsidefs.h [deleted file]
tools/ioemu/iodev/scsipt.h [deleted file]
tools/ioemu/iodev/serial.cc [deleted file]
tools/ioemu/iodev/serial.h [deleted file]
tools/ioemu/iodev/serial_raw.h [deleted file]
tools/ioemu/iodev/slowdown_timer.cc [deleted file]
tools/ioemu/iodev/slowdown_timer.h [deleted file]
tools/ioemu/iodev/soundlnx.cc [deleted file]
tools/ioemu/iodev/soundlnx.h [deleted file]
tools/ioemu/iodev/soundwin.cc [deleted file]
tools/ioemu/iodev/soundwin.h [deleted file]
tools/ioemu/iodev/state_file.cc [deleted file]
tools/ioemu/iodev/unmapped.cc [deleted file]
tools/ioemu/iodev/unmapped.h [deleted file]
tools/ioemu/iodev/vga.cc [deleted file]
tools/ioemu/iodev/vga.h [deleted file]
tools/ioemu/iodev/virt_timer.cc [deleted file]
tools/ioemu/iodev/virt_timer.h [deleted file]
tools/ioemu/keyboard_rdesktop.c [new file with mode: 0644]
tools/ioemu/keymaps/ar [new file with mode: 0644]
tools/ioemu/keymaps/common [new file with mode: 0644]
tools/ioemu/keymaps/convert-map [new file with mode: 0644]
tools/ioemu/keymaps/da [new file with mode: 0644]
tools/ioemu/keymaps/de [new file with mode: 0644]
tools/ioemu/keymaps/de-ch [new file with mode: 0644]
tools/ioemu/keymaps/en-gb [new file with mode: 0644]
tools/ioemu/keymaps/en-us [new file with mode: 0644]
tools/ioemu/keymaps/es [new file with mode: 0644]
tools/ioemu/keymaps/et [new file with mode: 0644]
tools/ioemu/keymaps/fi [new file with mode: 0644]
tools/ioemu/keymaps/fo [new file with mode: 0644]
tools/ioemu/keymaps/fr [new file with mode: 0644]
tools/ioemu/keymaps/fr-be [new file with mode: 0644]
tools/ioemu/keymaps/fr-ca [new file with mode: 0644]
tools/ioemu/keymaps/fr-ch [new file with mode: 0644]
tools/ioemu/keymaps/hr [new file with mode: 0644]
tools/ioemu/keymaps/hu [new file with mode: 0644]
tools/ioemu/keymaps/is [new file with mode: 0644]
tools/ioemu/keymaps/it [new file with mode: 0644]
tools/ioemu/keymaps/ja [new file with mode: 0644]
tools/ioemu/keymaps/lt [new file with mode: 0644]
tools/ioemu/keymaps/lv [new file with mode: 0644]
tools/ioemu/keymaps/mk [new file with mode: 0644]
tools/ioemu/keymaps/modifiers [new file with mode: 0644]
tools/ioemu/keymaps/nl [new file with mode: 0644]
tools/ioemu/keymaps/nl-be [new file with mode: 0644]
tools/ioemu/keymaps/no [new file with mode: 0644]
tools/ioemu/keymaps/pl [new file with mode: 0644]
tools/ioemu/keymaps/pt [new file with mode: 0644]
tools/ioemu/keymaps/pt-br [new file with mode: 0644]
tools/ioemu/keymaps/ru [new file with mode: 0644]
tools/ioemu/keymaps/sl [new file with mode: 0644]
tools/ioemu/keymaps/sv [new file with mode: 0644]
tools/ioemu/keymaps/th [new file with mode: 0644]
tools/ioemu/keymaps/tr [new file with mode: 0644]
tools/ioemu/main.c [new file with mode: 0644]
tools/ioemu/memory/Makefile [deleted file]
tools/ioemu/memory/memory.cc [deleted file]
tools/ioemu/memory/memory.h [deleted file]
tools/ioemu/memory/misc_mem.cc [deleted file]
tools/ioemu/mk/helix.mk [deleted file]
tools/ioemu/monitor.c [new file with mode: 0644]
tools/ioemu/osdep.c [new file with mode: 0644]
tools/ioemu/osdep.h [new file with mode: 0644]
tools/ioemu/path.c [new file with mode: 0644]
tools/ioemu/pc-bios/Makefile [new file with mode: 0644]
tools/ioemu/pc-bios/README [new file with mode: 0644]
tools/ioemu/pc-bios/bios.bin [new file with mode: 0644]
tools/ioemu/pc-bios/bios.diff [new file with mode: 0644]
tools/ioemu/pc-bios/linux_boot.S [new file with mode: 0644]
tools/ioemu/pc-bios/linux_boot.bin [new file with mode: 0644]
tools/ioemu/pc-bios/ppc_rom.bin [new file with mode: 0644]
tools/ioemu/pc-bios/proll.bin [new file with mode: 0644]
tools/ioemu/pc-bios/proll.patch [new file with mode: 0644]
tools/ioemu/pc-bios/vgabios-cirrus.bin [new file with mode: 0644]
tools/ioemu/pc-bios/vgabios.bin [new file with mode: 0644]
tools/ioemu/qemu-binfmt-conf.sh [new file with mode: 0644]
tools/ioemu/qemu-doc.html [new file with mode: 0644]
tools/ioemu/qemu-doc.texi [new file with mode: 0644]
tools/ioemu/qemu-img.c [new file with mode: 0644]
tools/ioemu/qemu-mkcow.1 [new file with mode: 0644]
tools/ioemu/qemu-tech.html [new file with mode: 0644]
tools/ioemu/qemu-tech.texi [new file with mode: 0644]
tools/ioemu/qemu.1 [new file with mode: 0644]
tools/ioemu/readline.c [new file with mode: 0644]
tools/ioemu/sdl.c [new file with mode: 0644]
tools/ioemu/target-i386-dm/device-model [new file with mode: 0755]
tools/ioemu/target-i386-dm/helper2.c [new file with mode: 0644]
tools/ioemu/target-i386-dm/qemu-ifup [new file with mode: 0755]
tools/ioemu/target-i386-dm/qemu-vgaram-bin.gz [new file with mode: 0644]
tools/ioemu/tests/Makefile [new file with mode: 0644]
tools/ioemu/tests/hello-arm.c [new file with mode: 0644]
tools/ioemu/tests/hello-i386.c [new file with mode: 0644]
tools/ioemu/tests/linux-test.c [new file with mode: 0644]
tools/ioemu/tests/pi_10.com [new file with mode: 0644]
tools/ioemu/tests/qruncom.c [new file with mode: 0644]
tools/ioemu/tests/runcom.c [new file with mode: 0644]
tools/ioemu/tests/sha1.c [new file with mode: 0644]
tools/ioemu/tests/test-i386-code16.S [new file with mode: 0644]
tools/ioemu/tests/test-i386-muldiv.h [new file with mode: 0644]
tools/ioemu/tests/test-i386-shift.h [new file with mode: 0644]
tools/ioemu/tests/test-i386-vm86.S [new file with mode: 0644]
tools/ioemu/tests/test-i386.c [new file with mode: 0644]
tools/ioemu/tests/test-i386.h [new file with mode: 0644]
tools/ioemu/tests/test_path.c [new file with mode: 0644]
tools/ioemu/tests/testthread.c [new file with mode: 0644]
tools/ioemu/texi2pod.pl [new file with mode: 0755]
tools/ioemu/thunk.c [new file with mode: 0644]
tools/ioemu/thunk.h [new file with mode: 0644]
tools/ioemu/vgafont.h [new file with mode: 0644]
tools/ioemu/vl.c [new file with mode: 0644]
tools/ioemu/vl.h [new file with mode: 0644]
tools/ioemu/vnc.c [new file with mode: 0644]

index a4eeac0c72d093d85b377cdde7932bc5a5bfe392..61030860b5e51c0cccd5719a36de19c875e1baba 100644 (file)
--- a/.rootkeys
+++ b/.rootkeys
 4273458dYPghQKVnj_xu5-fC38CcOg tools/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/server.c
 423d3a7b2ENk2IskDZYZ98pe5NsvIA tools/gdb/gdb-6.2.1-xen-sparse/mkbuildtree
 423d3a7buANO_q-kgxIRffUu7lMnUw tools/gdb/gdbbuild
-41e2ff6dNPgvIrdIF6dC1azdex1U3A tools/ioemu/Makefile
-41e2ff6aoF5fgddZi0QpEWqFr89E5g tools/ioemu/font/vga.bitmap.h
-41e2ff6avgnBNvZRiL4ynyGGq2UKlw tools/ioemu/gui/Makefile
-41e2ff6a30Xuw7pDX3SlVBx3ssOMDQ tools/ioemu/gui/Makefile.in
-41e2ff6aGGn5D3-Yh856G7xWJ5ZJsA tools/ioemu/gui/bitmaps/cdromd.h
-41e2ff6abNiWU34DwftxJ30sI6TQmw tools/ioemu/gui/bitmaps/cdromd.xpm
-41e2ff6adSUYHlvyVpz7q1Izcx5_gQ tools/ioemu/gui/bitmaps/configbutton.h
-41e2ff6aLWWXfMqIH2jSCNUzuc4_Yg tools/ioemu/gui/bitmaps/configbutton.xpm
-41e2ff6ahsqMjwuhpbqfrFHCBqYhEA tools/ioemu/gui/bitmaps/copy.h
-41e2ff6ajL41CnUeGefMrNijudQlCg tools/ioemu/gui/bitmaps/copy.xpm
-41e2ff6aXn5GhkDNOGqUcfCLbDZf3w tools/ioemu/gui/bitmaps/floppya.h
-41e2ff6agOpnECodSZ62L-Uijy5fsQ tools/ioemu/gui/bitmaps/floppya.xpm
-41e2ff6akrHp6jG_Y2BmFpEcaswUqg tools/ioemu/gui/bitmaps/floppyb.h
-41e2ff6aGbvPO1cQLMLduGl16rntbg tools/ioemu/gui/bitmaps/floppyb.xpm
-41e2ff6aEcsgeBHQZ_5e3rfgo0USMA tools/ioemu/gui/bitmaps/mouse.h
-41e2ff6aO8pXESvDVxMG7TgZL7UvFA tools/ioemu/gui/bitmaps/mouse.xpm
-41e2ff6aSd1H6Z0dUVUYLsW-6EDrYw tools/ioemu/gui/bitmaps/paste.h
-41e2ff6aRGfY6Jd2TThqWtXoh2CHuQ tools/ioemu/gui/bitmaps/paste.xpm
-41e2ff6aKDap56ifPVgdBVPc9yfmvw tools/ioemu/gui/bitmaps/power.h
-41e2ff6aDLfEO8dFUd9IpsfUpMk-Vg tools/ioemu/gui/bitmaps/power.xpm
-41e2ff6aKWtTsWCds4vL2azV3w-XtQ tools/ioemu/gui/bitmaps/reset.h
-41e2ff6a_AU4_ytzHU0Btr3trcbVmA tools/ioemu/gui/bitmaps/reset.xpm
-41e2ff6a-hGpcXEChJQDo-xRyH5oGQ tools/ioemu/gui/bitmaps/snapshot.h
-41e2ff6aRoGi5nKyQFtcUzK0-9dRDA tools/ioemu/gui/bitmaps/snapshot.xpm
-41e2ff6aZdTp9lSJjyUI7YoXqQnCng tools/ioemu/gui/bitmaps/userbutton.h
-41e2ff6aWc4p23rAKngLMu8eLZiXlw tools/ioemu/gui/bitmaps/userbutton.xpm
-41e2ff6a7gMd57Q5DL0kRD-mR7JzZg tools/ioemu/gui/gui.cc
-41e2ff6a-USvofVXiSpY76RT4C0IVw tools/ioemu/gui/gui.h
-41e2ff6aYAuOb0x4zTVB7cWYIFIdOA tools/ioemu/gui/icon_bochs.h
-41e2ff6aZbFf-Djysg393N4vCEJ7ig tools/ioemu/gui/icon_bochs.xpm
-41e2ff6ai-vJcSE9hfz4SHZ20rK5QA tools/ioemu/gui/keymap.cc
-41e2ff6a_TY9EJnCcbr5EKV_pi90kg tools/ioemu/gui/keymap.h
-41e2ff6aP0co3DAK04MrugZCkp0roQ tools/ioemu/gui/keymaps/convertmap.pl
-41e2ff6a-GiP9bzqtVXEjxmxiYgzeg tools/ioemu/gui/keymaps/sdl-pc-de.map
-41e2ff6aa5xj7jyze5bcPnj-UHYgTQ tools/ioemu/gui/keymaps/sdl-pc-us.map
-41e2ff6ahemkf0kG8SzDXq8g2qp9Pg tools/ioemu/gui/keymaps/x11-pc-be.map
-41e2ff6ajdaBBS85yriZ3S9ecy5Odg tools/ioemu/gui/keymaps/x11-pc-da.map
-41e2ff6aGkLyRvwOTZnDqvobziAoiQ tools/ioemu/gui/keymaps/x11-pc-de.map
-41e2ff6aWcqOK6RjpY28Y4bVjMy9yg tools/ioemu/gui/keymaps/x11-pc-es.map
-41e2ff6aF46Uu09XOmmkcGDotToSxw tools/ioemu/gui/keymaps/x11-pc-fr.map
-41e2ff6aHM040MYLmOeW_PKIx1TWWg tools/ioemu/gui/keymaps/x11-pc-it.map
-41e2ff6aCa-6fHjBOoPWP8hDweZ1Fw tools/ioemu/gui/keymaps/x11-pc-se.map
-41e2ff6aUH4wvnqRwo91dJBnhxEYUg tools/ioemu/gui/keymaps/x11-pc-uk.map
-41e2ff6aF7b08llRJQBLgNAEfyn9wQ tools/ioemu/gui/keymaps/x11-pc-us.map
-41e2ff6a2gbWdoaE7X9vtizvQ4QqdQ tools/ioemu/gui/nogui.cc
-41e2ff6a_rWAWre2toEtNUMKliCJPA tools/ioemu/gui/rfb.cc
-41e2ff6aQfuugiO3YE07l03L6ASP9g tools/ioemu/gui/rfb.h
-41e2ff6aTWFzmW0sjxXpQq7ulaj_Pw tools/ioemu/gui/rfbproto.h
-41e2ff6bf4pfJkZTN5vA6HbiJJqeNA tools/ioemu/gui/sdl.h
-41e2ff6bVnojmIqKJCbhVUKtMcUWJg tools/ioemu/gui/sdlkeys.h
-41e2ff6bKVx97oSdGGToXQXvbQgkZA tools/ioemu/gui/siminterface.cc
-41e2ff6bDB5XABCVAA7nMolZPe5ZoA tools/ioemu/gui/siminterface.h
-41e2ff6benMg1o7HQ2C5PGS3KFHFow tools/ioemu/gui/svga.cc
-41e2ff6bz3XZGzzwvXGqFadb3QqWWQ tools/ioemu/gui/term.cc
-41e2ff6b8jzKgyKu2gNVlRWepPNA0A tools/ioemu/gui/textconfig.cc
-41e2ff6bUKaJhGtIDqUYzAesLg1MGA tools/ioemu/gui/textconfig.h
-41e2ff6b__Pd6Q2aYDZ5vB9bGJEMNA tools/ioemu/gui/x.cc
-41e2ff6bp96y5NyMIFjH-HpCRcGBPg tools/ioemu/include/bochs.h
-41e2ff6bqIMIJlitAnubjNjf70s3dw tools/ioemu/include/bxversion.h
-41e2ff6bTfksDlUXSWC_wC_g30r1cQ tools/ioemu/include/config.h
-41e2ff6bwDEGCUwYTf1oo9ZCva2nkw tools/ioemu/include/cpu/cpu.h
-41e2ff6bH1PTh2iMScpOn9v9R3SDag tools/ioemu/include/extplugin.h
-41e2ff6bFS9XP8ndI6IhGFitzsvTtw tools/ioemu/include/instrument.h
-41e2ff6bz71jKff_NUdmI279ArbMgw tools/ioemu/include/ltdl.h
-41e2ff6bYayW_YSVmb1sJCvk9z9-ug tools/ioemu/include/ltdlconf.h
-41e2ff6b_MdkIIjsFYTFMIKIt7Royw tools/ioemu/include/osdep.h
-41e2ff6bPJNSITgePniKtvlujrmcLA tools/ioemu/include/pc_system.h
-41e2ff6bmHZyZrzF7iHpD212GeAT-w tools/ioemu/include/plugin.h
-41e2ff6bHgstm2ZhCIdsag_c3_dVjA tools/ioemu/include/state_file.h
-41e2ff6bJjm8-4K6Cu2k6zoanQ8Yyg tools/ioemu/iodev/Makefile
-41e2ff6bKj9bQ4ELP2msSYoT7XrxHQ tools/ioemu/iodev/aspi-win32.h
-41e2ff6b95DLt3iA-okw7D4NJcaDCg tools/ioemu/iodev/biosdev.cc
-41e2ff6b1ra22hFnE6Tm9lxVaH4Mjw tools/ioemu/iodev/biosdev.h
-41e2ff6bftET40KQA19RAisCxyDHVQ tools/ioemu/iodev/cdrom.cc
-41e2ff6buuSLUZPj9EtlGA3tufslNQ tools/ioemu/iodev/cdrom.h
-41e2ff6bvD6jE2JHKP0wd7I_mB7MJg tools/ioemu/iodev/cdrom_beos.h
-41e2ff6b99qviTPyKLjy0-D5DIqACw tools/ioemu/iodev/cmos.cc
-41e2ff6bpeZbWqQfuwM_Xj-kElElAA tools/ioemu/iodev/cmos.h
-41e2ff6bRf7QN_i1c7BAzkQha8AFUg tools/ioemu/iodev/cpu.cc
-41e2ff6byVHp6G3fxAlly1u1sx_DEg tools/ioemu/iodev/crc32.cc
-41e2ff6bHWz28hOKgLKRizX9UjsyOQ tools/ioemu/iodev/crc32.h
-41e2ff6b3tvq7uKSC9DWkOswq0Re8w tools/ioemu/iodev/devices.cc
-41e2ff6bO-SYXzx1RB-1If_FNkyjLg tools/ioemu/iodev/dma.cc
-41e2ff6bdI7Ri1mVb1MzkvBKlNSx6Q tools/ioemu/iodev/dma.h
-41e2ff6bfnGRrb25sneyvOXxSi8pLg tools/ioemu/iodev/eth.cc
-41e2ff6bteOXqvNO1FIR5iFHUwqUuA tools/ioemu/iodev/eth.h
-41e2ff6bTQxXrfWSsDCISUAdzlAe9w tools/ioemu/iodev/eth_arpback.cc
-41e2ff6brorlh9N9Myd1_g7ktKcIfQ tools/ioemu/iodev/eth_fbsd.cc
-41e2ff6b5xRFy8_OISEtd2UrHEUdfw tools/ioemu/iodev/eth_linux.cc
-41e2ff6biySiByowEn40XP_yx_lxKg tools/ioemu/iodev/eth_null.cc
-41e2ff6bFAVD0UO_ob40usJOnEPAZg tools/ioemu/iodev/eth_packetmaker.cc
-41e2ff6bsR-mjksFNRC9HiDDVUfI2w tools/ioemu/iodev/eth_packetmaker.h
-41e2ff6bMnzZ7cpqVPQY0_0smpqjHw tools/ioemu/iodev/eth_tap.cc
-41e2ff6bGa18jj0cqoOAqBPDzk2Aog tools/ioemu/iodev/eth_tuntap.cc
-41e2ff6bY1u244mkTGfttym3HoLo5Q tools/ioemu/iodev/extfpuirq.cc
-41e2ff6b_wh3dgYBx38KIJ00Qv4XUA tools/ioemu/iodev/extfpuirq.h
-41e2ff6b3uiKo02slxJn11bvZKsF3g tools/ioemu/iodev/floppy.cc
-41e2ff6bKba0nlJHGy2kWUr_3e_nvw tools/ioemu/iodev/floppy.h
-41e2ff6bC1KaCAEBYYTkJJ5_pBydkQ tools/ioemu/iodev/gameport.cc
-41e2ff6bePGww4K0p8vTLphdE_zdig tools/ioemu/iodev/gameport.h
-41e2ff6biLQpMiiiKokz7qUXpBn5cg tools/ioemu/iodev/guest2host.h
-41e2ff6bji1Iix0CzQTeh9yB-Ao14Q tools/ioemu/iodev/harddrv.cc
-41e2ff6bcSDALK1SdvKvTCxemzpWwQ tools/ioemu/iodev/harddrv.h
-41e2ff6b36hFBfV06tX0a5CRjFpuxA tools/ioemu/iodev/ioapic.cc
-41e2ff6brajF6a0a7RkLHiX0M9oH7w tools/ioemu/iodev/ioapic.h
-41e2ff6btDX2IfOnC_LkP08ZlKxjJw tools/ioemu/iodev/iodebug.cc
-41e2ff6b-__Z4ECo9pHWVM-Rz-0ehw tools/ioemu/iodev/iodebug.h
-41e2ff6btRbGfsUt5k4MClieCZ-EBQ tools/ioemu/iodev/iodev.h
-41e2ff6bH5C9aG3f2QhoD6zCdShJYQ tools/ioemu/iodev/keyboard.cc
-41e2ff6bUOmeloSf5s9Gkdffo1bEyA tools/ioemu/iodev/keyboard.h
-41e2ff6b55oybF1yhInYSZX2bxiJSw tools/ioemu/iodev/load32bitOShack.cc
-41e2ff6b5WcmfYXaREzUm0KQu7pKCQ tools/ioemu/iodev/logio.cc
-41e2ff6bqqHfrDtizlRKA-_oPRbGAw tools/ioemu/iodev/main.cc
-41e2ff6cWAAGa6Pt6eE4URbCOq8wQA tools/ioemu/iodev/ne2k.cc
-41e2ff6cap6qrVL42AgTpxjav0QMQg tools/ioemu/iodev/ne2k.h
-41e2ff6cHH0UoJW74RKZFnPBSt1jUw tools/ioemu/iodev/osdep.cc
-41e2ff6ckuFNtxuAQDMVwJtYwL2QCg tools/ioemu/iodev/parallel.cc
-41e2ff6cbqWnJwLAQ9NDZJwUyGiIww tools/ioemu/iodev/parallel.h
-41e2ff6cAdkxmfzVhbQn9Plq3X4S_w tools/ioemu/iodev/pc_system.cc
-41e2ff6csu1e9S_rywWOq9B85IaZzA tools/ioemu/iodev/pci.cc
-41e2ff6cjcmNZLD17naGuKj_Qon6Ow tools/ioemu/iodev/pci.h
-41e2ff6c91zYiAb9XulXkl2vLERo-w tools/ioemu/iodev/pci2isa.cc
-41e2ff6cV7IdLNbFXwlWvdcOz4F1Aw tools/ioemu/iodev/pci2isa.h
-41e2ff6cviwF37ZllnYtHA3MEHRMWw tools/ioemu/iodev/pciusb.cc
-41e2ff6ceFmfyqr1MgYhEoRM1s6icQ tools/ioemu/iodev/pciusb.h
-41e2ff6cd-1VHyISVo789tv3ImNgLw tools/ioemu/iodev/pcivga.cc
-41e2ff6cVkXDlrNUTdt7D6BULEp1Tg tools/ioemu/iodev/pcivga.h
-41e2ff6c3xjAFB8X5OLFz_8Of62v2Q tools/ioemu/iodev/pic.cc
-41e2ff6c4UHzse5_N0Mx6u5dqKrVkw tools/ioemu/iodev/pic.h
-41e2ff6cdD9yovRmQNNJu8QVtZg7Iw tools/ioemu/iodev/pit.cc
-41e2ff6cXtvewmYJyoxrWGic2sOayg tools/ioemu/iodev/pit.h
-41e2ff6cXaqNRxMagdpNiT1kTWJJUA tools/ioemu/iodev/pit82c54.cc
-41e2ff6cHAkpKzMwyz3diMZWTswxmg tools/ioemu/iodev/pit82c54.h
-41e2ff6cMK9E2gjqHoWV9ZQfz-cP1Q tools/ioemu/iodev/pit_wrap.cc
-41e2ff6cbie7fPpQMgBImJ885GAPdw tools/ioemu/iodev/pit_wrap.h
-41e2ff6c0wLrWtBHxxboIzHsrZzkRA tools/ioemu/iodev/plugin.cc
-41e2ff6cN4Z6pnguPQaqiCkWp42MOQ tools/ioemu/iodev/scancodes.cc
-41e2ff6chK1sqb78l1sqhF3fJhjzBw tools/ioemu/iodev/scancodes.h
-41e2ff6cIyPvY7hNE5rP_PMZELhyVw tools/ioemu/iodev/scsi_commands.h
-41e2ff6cF3wH8A_66_yG92Wk7I2IWQ tools/ioemu/iodev/scsidefs.h
-41e2ff6cbAin6eD3Gfz2CozOS4_bwA tools/ioemu/iodev/scsipt.h
-41e2ff6cce6mNXZPGmlQ1bg_I0ef8Q tools/ioemu/iodev/serial.cc
-41e2ff6cxsITO-ikpd4vBYZUYO3qSw tools/ioemu/iodev/serial.h
-41e2ff6cbaCEgMJ92UELiRE2wEYe3g tools/ioemu/iodev/serial_raw.h
-41e2ff6cwDKTU8OukKNBNMDiAYUWvQ tools/ioemu/iodev/slowdown_timer.cc
-41e2ff6cM5XYdcgL417IBOzW-QipFg tools/ioemu/iodev/slowdown_timer.h
-41e2ff6c5X0WxdBPUyZlNmW6Zv_LRQ tools/ioemu/iodev/soundlnx.cc
-41e2ff6cIuE1VxGF_L6rdBtD6rZ_aA tools/ioemu/iodev/soundlnx.h
-41e2ff6cDIv87LKamP0Y-yjrdqALzQ tools/ioemu/iodev/soundwin.cc
-41e2ff6cB55j_uYIqYh-UiLS4wlm_g tools/ioemu/iodev/soundwin.h
-41e2ff6dRPBmtxjFbEM5WYuilnSSZg tools/ioemu/iodev/state_file.cc
-41e2ff6dMwkI1Dpa-UHSEzHCvjpOyw tools/ioemu/iodev/unmapped.cc
-41e2ff6d_yJMFHYPENtVmJz6wyldQA tools/ioemu/iodev/unmapped.h
-41e2ff6dU5hJI6Kn70mFingJo4cHUw tools/ioemu/iodev/vga.cc
-41e2ff6dh8xDcCXkZzpSqnFP-OXggw tools/ioemu/iodev/vga.h
-41e2ff6dayXwb5dxf0K5pd3q4QppRA tools/ioemu/iodev/virt_timer.cc
-41e2ff6dI_rNgBwki594UAWN337-zw tools/ioemu/iodev/virt_timer.h
-41e2ff6dCCtE_btrlEopLaCsLO3JDA tools/ioemu/memory/Makefile
-41e2ff6dZtwsTW8s-Gqv7bqObdvaXw tools/ioemu/memory/memory.cc
-41e2ff6dpk6EFzlHlsAsFEFdyG4wrA tools/ioemu/memory/memory.h
-41e2ff6d2i-wqgCe4iAXdckUc1GD-A tools/ioemu/memory/misc_mem.cc
-41e2ff6dCYuZgf6pxRmphkh5yeuA9Q tools/ioemu/mk/helix.mk
+428d0d82yOaUzYQuYQxH7VzQytKo-g tools/ioemu/COPYING
+428d0d82EdPp1TqJBembLgyB1y413w tools/ioemu/COPYING.LIB
+428d0d82fd6-QydvFfHmeQBGrKnrrA tools/ioemu/Changelog
+428d0d82xvTj4yzPYiurazyGj1PaEw tools/ioemu/Makefile
+428d0d82dUmXkgIy11G-hoKTkhvkfQ tools/ioemu/Makefile.target
+428d0d82HvgRPoyU3f60_u_t1L28Ag tools/ioemu/README
+428d0d820gXmfIVHub7p9VbT7bQcMw tools/ioemu/README.distrib
+428d0d82aoWewa_6Z5kNUTgkRw0wNg tools/ioemu/TODO
+428d0d82WYi8vrG7RKKyIJw01DAnGg tools/ioemu/VERSION
+428d0d82wB05ibBxTCSsAhz3qRO7Gg tools/ioemu/block-cloop.c
+428d0d82cucBBZFks3aMSL0-C3L9Nw tools/ioemu/block-cow.c
+428d0d82s5FM7xmnj1XLAMlt_DdRIA tools/ioemu/block-qcow.c
+428d0d83yWYa6mIH2mplo1L_3Cqadw tools/ioemu/block-vmdk.c
+428d0d83nfcgHvu37hviRYwAAAAxSQ tools/ioemu/block.c
+428d0d83LrXLfgm9h2RPNBRM_vkqsA tools/ioemu/block_int.h
+428d0d83zt7CgVsTa-CIorpIGVWe7g tools/ioemu/bswap.h
+428d0d83-I9bQJ8EduVO0OmP_YMtVg tools/ioemu/configure
+428d0d83sUjdDRZnfykBaWd_uGjVQQ tools/ioemu/console.c
+428d0d83Rsv-Pq8iGrvA0ChVTD-KEQ tools/ioemu/cpu-all.h
+428d0d830tCm2-QC3iLTo-yS2D7azQ tools/ioemu/cpu-defs.h
+428d0d83bOFEAX7Kc_lt7pm_ItnYOg tools/ioemu/cpu.h
+428d0d83wJqNCht75GfVfWqGzaDBGA tools/ioemu/create_keysym_header.sh
+428d0d83warJp9F3aKU4moRRVfTmFg tools/ioemu/exec-all.h
+428d0d83m3Kwp8vJKycK1n5a_LygfA tools/ioemu/exec.c
+428d0d83G-F1mvFyzCEMNhiU6ts8lQ tools/ioemu/hw/adb.c
+428d0d83EE1hpyfMfr667s4aFK42hg tools/ioemu/hw/adlib.c
+428d0d83AoBht7yFAmAUWoi-ZZS2Tw tools/ioemu/hw/cirrus_vga.c
+428d0d83lD5ovmJG_Q1VfIIjw1Fm-A tools/ioemu/hw/cirrus_vga_rop.h
+428d0d83SCwX65BPgonBcgYCxdKDNA tools/ioemu/hw/cirrus_vga_rop2.h
+428d0d83zAKLZ8JX7_D6RMGcml3jRA tools/ioemu/hw/cuda.c
+428d0d83OLV-aQor-LfByakKvo-1-g tools/ioemu/hw/dma.c
+428d0d83P1VkKtXn90RMN8eBsvPFQA tools/ioemu/hw/fdc.c
+428d0d849AqxX6FsPHv0ovjaFyNMVg tools/ioemu/hw/fmopl.c
+428d0d84-hHRu7PVXjfc7oLfrDxY6g tools/ioemu/hw/fmopl.h
+428d0d84zbtT2C8Xci_SqMP5bZ-wcQ tools/ioemu/hw/i8254.c
+428d0d84KlR61OwSzjF0-L4iz58dfQ tools/ioemu/hw/i8259.c
+428d0d84auhZx6c5Kv3WrfM2UZvqHA tools/ioemu/hw/ide.c
+428d0d84WSlhNzdrcb-f-Lg-W9dniQ tools/ioemu/hw/iommu.c
+428d0d84ri8ZtvhB6RJr1YNejjNWIQ tools/ioemu/hw/lance.c
+428d0d84cxFFgDv5fBFrlxGoCiy6Nw tools/ioemu/hw/m48t08.c
+428d0d84MQYDhAOLnBnag1BZWcW6JA tools/ioemu/hw/m48t08.h
+428d0d84sE4ghX33RQ5kDSuyoLdhFg tools/ioemu/hw/m48t59.c
+428d0d8465kZWTT4mVgf-VonglDOxw tools/ioemu/hw/m48t59.h
+428d0d84OY7tvE-PKrBfjf2vEQXyMA tools/ioemu/hw/magic-load.c
+428d0d84U-PYPR_GMVJoQsbCAVAQow tools/ioemu/hw/mc146818rtc.c
+428d0d84jtSXGjQYKd_xvSiMM4C_7Q tools/ioemu/hw/ne2000.c
+428d0d84SMHPk0cRnrZgUYkMxFXMMQ tools/ioemu/hw/openpic.c
+428d0d84lyG0XDg5MxLMSee3MWgq3g tools/ioemu/hw/pc.c
+428d0d84HWR3Q7dEESycfJ7hSWdGig tools/ioemu/hw/pci.c
+428d0d84Noyn4ik0UX1E7OdfuFdrIw tools/ioemu/hw/pckbd.c
+428d0d840SMURRjsz9V96rwt-naynw tools/ioemu/hw/ppc.c
+428d0d84MI7kZftH_c0FK1qiiyQBZg tools/ioemu/hw/ppc_chrp.c
+428d0d859-xwA89jmzFk6x9UyXjAeA tools/ioemu/hw/ppc_prep.c
+428d0d85YS1n4Fr_EK7B01EWSmrYRg tools/ioemu/hw/sb16.c
+428d0d85GrUXL_p0ppOUIfWf8--hvw tools/ioemu/hw/sched.c
+428d0d85wP3aLdHYJ-hDAImDP2sj_g tools/ioemu/hw/serial.c
+428d0d85mOfwFqDCO76K6bc4IQOxQA tools/ioemu/hw/sun4m.c
+428d0d852OCpAsfS1PNoJOfnHhFPSQ tools/ioemu/hw/tcx.c
+428d0d85gCUCX0nbuRAt28QJgQ5P8w tools/ioemu/hw/timer.c
+428d0d85hp-zgN40hVYXWRjhInkUkg tools/ioemu/hw/vga.c
+428d0d85G_4S-hpRyrhV4yGjSrS-cQ tools/ioemu/hw/vga_int.h
+428d0d85oWl1ONX_gIZWS1fXjeXGlA tools/ioemu/hw/vga_template.h
+428d0d85-wAtLF5FYFHCUAxXKNbEkA tools/ioemu/i386-vl.ld
+428d0d85d831iQvvCD3LcaOD9rYGkg tools/ioemu/i386.ld
+428d0d85_mNnFPE8hnoC3VvBD9CCuA tools/ioemu/keyboard_rdesktop.c
+428d0d85SyOIeDg3SoxH2BiBpXWWkA tools/ioemu/keymaps/ar
+428d0d85ToGTVvPrl8hKAi2QxCzp2w tools/ioemu/keymaps/common
+428d0d85fmdxRplWI5Jp54NNZy5Mmw tools/ioemu/keymaps/convert-map
+428d0d85t5IBwlnttPreCS0UX3nbOw tools/ioemu/keymaps/da
+428d0d85XRNojuUlkCgvea0I_fdJEg tools/ioemu/keymaps/de
+428d0d85QPup3ixECEpa7Pzr9lLEyw tools/ioemu/keymaps/de-ch
+428d0d86r5UpNhOSALGJUUDaGv-vnQ tools/ioemu/keymaps/en-gb
+428d0d86ylUT-4Skjnwa27vxIeBqYw tools/ioemu/keymaps/en-us
+428d0d86vcHusn3XzWTLjKLDdNhZxw tools/ioemu/keymaps/es
+428d0d86UVS0Km-9J94RAQM7iAbBzw tools/ioemu/keymaps/et
+428d0d86hS47OlX4USgPPWk6RFWKLQ tools/ioemu/keymaps/fi
+428d0d86kOcjaVVZqDgV2JDGcXQ8rg tools/ioemu/keymaps/fo
+428d0d86c4GgMp1hDU2MFxiZ1Pz9Lg tools/ioemu/keymaps/fr
+428d0d86BdbSM5PxuMaSf8vBv6rXQg tools/ioemu/keymaps/fr-be
+428d0d86dQk_p9io2QdI9SGC6FVidg tools/ioemu/keymaps/fr-ca
+428d0d86JpfLBZmnrv7Yp0tuezgzng tools/ioemu/keymaps/fr-ch
+428d0d861RURctgJ3cgtnq0chW6JOA tools/ioemu/keymaps/hr
+428d0d86mqzqw70FkLHZFzIkvTJBpw tools/ioemu/keymaps/hu
+428d0d86O3ruSBL8ZyRBeLF7Ow67Og tools/ioemu/keymaps/is
+428d0d87pcCatuZLYpVWtUu2Da9sgw tools/ioemu/keymaps/it
+428d0d87M3Hy7ubCu27ZO-zWDk-YhQ tools/ioemu/keymaps/ja
+428d0d87CqrbJBUI28UxJCIduSJ4rQ tools/ioemu/keymaps/lt
+428d0d87jIV_V1YwET59i-Py3h0ILA tools/ioemu/keymaps/lv
+428d0d87T3KIxrywXSAkRu-AiQQgIQ tools/ioemu/keymaps/mk
+428d0d87_wmWi_IBHfpmZzhCKU-Baw tools/ioemu/keymaps/modifiers
+428d0d87GgUuEd4Mz9p3mUGkdMdOsg tools/ioemu/keymaps/nl
+428d0d87E1NtUwguKl72ifCTjDQ5rQ tools/ioemu/keymaps/nl-be
+428d0d87lKhQOfn5yQ0tq3u7hfIgpw tools/ioemu/keymaps/no
+428d0d87iD3aff-LOlaA4CmOUVct3Q tools/ioemu/keymaps/pl
+428d0d870CMCzI7c6gcGZMNuIYGbnQ tools/ioemu/keymaps/pt
+428d0d87gCs2M4A4P1ITzW86lm_-JA tools/ioemu/keymaps/pt-br
+428d0d87nzQ8eK1b9_Zs1Z82dOuX1Q tools/ioemu/keymaps/ru
+428d0d87uHdsh15a5mAD-HyWni8QDw tools/ioemu/keymaps/sl
+428d0d87gsUMIP42oFecYrdZAJDAuw tools/ioemu/keymaps/sv
+428d0d87OcfLjKuhg6p2uuiAPvJBqQ tools/ioemu/keymaps/th
+428d0d87QbRtHJUft9qBkNXcl4pbzw tools/ioemu/keymaps/tr
+428d0d88CJoMejkmBh6pWaqKMvQF8A tools/ioemu/main.c
+428d0d88Fcan7gQZ6axXOmokBDLe7g tools/ioemu/monitor.c
+428d0d88lVaOC64YBZ1Wzt-WV4JaSw tools/ioemu/osdep.c
+428d0d885W7r27CDEJCW6Jlbxggc9g tools/ioemu/osdep.h
+428d0d88CiP9tVdIdLWAzOnCOSdafg tools/ioemu/path.c
+428d0d88jzHltLAzyhV1lpFckzy8CA tools/ioemu/pc-bios/Makefile
+428d0d889pv_iPNBFn6cNRzQfJMC3A tools/ioemu/pc-bios/README
+428d0d88mhWW8SQFNfp-NaH3c8QQkg tools/ioemu/pc-bios/bios.bin
+428d0d88LMSMDbTFG1-sS8LL90hExw tools/ioemu/pc-bios/bios.diff
+428d0d89SHpdZE1S-ywjJCulIWs4Ag tools/ioemu/pc-bios/linux_boot.S
+428d0d89hiL0UgU71ero86GEu1loaA tools/ioemu/pc-bios/linux_boot.bin
+428d0d894MKpOb385vcoB_s_4q0QOA tools/ioemu/pc-bios/ppc_rom.bin
+428d0d896uo6qr-ONYkpleolayT4zw tools/ioemu/pc-bios/proll.bin
+428d0d893gsF8AcCadeYXcKM-aqssA tools/ioemu/pc-bios/proll.patch
+428d0d89GgbrVx4Ov3Zg-SFX_0BRdw tools/ioemu/pc-bios/vgabios-cirrus.bin
+428d0d89h9nqxPIgDpPMXZIWkdosNw tools/ioemu/pc-bios/vgabios.bin
+428d0d8908B65zMmhdGVME3jv7gpww tools/ioemu/qemu-binfmt-conf.sh
+428d0d89eKfKJmNEURTxLUtIjclvDw tools/ioemu/qemu-doc.html
+428d0d89jF9HlGboO7nLco-tqjLJqQ tools/ioemu/qemu-doc.texi
+428d0d89taY6NPlnIyOAMQd_Ww5qUw tools/ioemu/qemu-img.c
+428d0d89uGqd5VkBf5j3HFIkQMxsNA tools/ioemu/qemu-mkcow.1
+428d0d8941iGGM85zXzn4wSj6zgbQg tools/ioemu/qemu-tech.html
+428d0d89IkHVfdVTilpTpxDvOCOiIw tools/ioemu/qemu-tech.texi
+428d0d89ME4klwpFGjbiKXQrj2KF7A tools/ioemu/qemu.1
+428d0d89FY-g4UPH-ZW7t5ZCqvQVTQ tools/ioemu/readline.c
+428d0d89dLURbktZFufDKSHan01GFg tools/ioemu/sdl.c
+428d0d8atdIE_8ACJPPii5_asQNafw tools/ioemu/target-i386-dm/device-model
+428d0d8ahpRAYl6s_itBxnTcxyMHaQ tools/ioemu/target-i386-dm/helper2.c
+428d0d8aU3Moaq4zNW5QMV_NxD-4XA tools/ioemu/target-i386-dm/qemu-ifup
+428d0d8aqidj8n5H2_2qhBV0mIIJzA tools/ioemu/target-i386-dm/qemu-vgaram-bin.gz
+428d0d8ahJ-jctJYDXyAMh91-ifrmg tools/ioemu/tests/Makefile
+428d0d8ax12h3Jd3Vhw4nh-eG99-iQ tools/ioemu/tests/hello-arm.c
+428d0d8acsBcsGQPd0qQllU-4c9fXw tools/ioemu/tests/hello-i386.c
+428d0d8aSEf5Q4wB3iaEThUssfFH8w tools/ioemu/tests/linux-test.c
+428d0d8a_orWq4Mg5EasDj2l6f4a0w tools/ioemu/tests/pi_10.com
+428d0d8aBv9VBjblSU8iAaVojF4qqw tools/ioemu/tests/qruncom.c
+428d0d8az-0qSZDA45Mt6y2SdsqF4w tools/ioemu/tests/runcom.c
+428d0d8aSf3jnF_aFvwAemDeROZcKQ tools/ioemu/tests/sha1.c
+428d0d8aBZGfRZ662SQIuXLdpmih0w tools/ioemu/tests/test-i386-code16.S
+428d0d8a8DbLZWzSyVQ_wX1RGr9SVQ tools/ioemu/tests/test-i386-muldiv.h
+428d0d8aaMQbnc_vqyQyOcUzyVrXyg tools/ioemu/tests/test-i386-shift.h
+428d0d8aKYkFtFSCFHFUivErvx0iqg tools/ioemu/tests/test-i386-vm86.S
+428d0d8aHx2CzT77VEsXouep7lZaYQ tools/ioemu/tests/test-i386.c
+428d0d8aDSIoqxC4_zr2z8vxMKrmeA tools/ioemu/tests/test-i386.h
+428d0d8ajPT5QfGuunOvjNibmURtqQ tools/ioemu/tests/test_path.c
+428d0d8bPccWrah4Y_zICBNZ5exhDw tools/ioemu/tests/testthread.c
+428d0d8b5F7EB4JnUbdTi_SZvF2wXg tools/ioemu/texi2pod.pl
+428d0d8bMq0ZpccpHb1iVvSNbJjRxg tools/ioemu/thunk.c
+428d0d8b2PYfwKLLShlnWcM3VWq9ag tools/ioemu/thunk.h
+428d0d8bfvbYQwj6MgDr958m4_SfRA tools/ioemu/vgafont.h
+428d0d8bgAojEQcAcTV2gj2E_eG4Lw tools/ioemu/vl.c
+428d0d8bXiCY4iTjoSPxGry8jXdAtg tools/ioemu/vl.h
+428d0d8bQVKedvN5EIPm39s33TXkpA tools/ioemu/vnc.c
 3fbba6dbDfYvJSsw9500b4SZyUhxjQ tools/libxc/Makefile
 41dde8afKYRKxS4XtLv1KUegGQy_bg tools/libxc/linux_boot_params.h
 41cc934abX-QLXJXW_clV_wRjM0zYg tools/libxc/plan9a.out.h
index 08a045383d5f39ac881144f6e1a91179aecc7b7a..733f9dc1f51218a6cc9cef9e05ba687227a1eccc 100644 (file)
@@ -10,30 +10,36 @@ SUBDIRS += xentrace
 SUBDIRS += python
 SUBDIRS += xfrd
 SUBDIRS += xcs
-ifndef XEN_NO_IOEMU
-SUBDIRS += ioemu
-endif
 SUBDIRS += pygrub
 
-.PHONY: all install clean check check_clean
+.PHONY: all install clean check check_clean ioemu eioemuinstall ioemuclean
+
+ifndef XEN_NO_IOEMU
+ioemu ioemuinstall ioemuclean:
+       [ -f ioemu/config-host.h ] || \
+       (cd ioemu; ./configure --prefix=$(DESTDIR)/usr)
+       $(MAKE) -C ioemu $(patsubst ioemu%,%,$@)
+else
+ioemu ioemuinstall ioemuclean:
+endif
 
 all: check
        @set -e; for subdir in $(SUBDIRS); do \
-                if [ -f $$subdir/configure ]; then \
-                        (cd $$subdir; ./configure --prefix=$(DESTDIR)/usr) \
-                fi; \
                $(MAKE) -C $$subdir $@; \
        done
+       $(MAKE) ioemu
 
 install: check
        @set -e; for subdir in $(SUBDIRS); do \
                $(MAKE) -C $$subdir $@; \
        done
+       $(MAKE) ioemuinstall
 
 clean: check_clean
        @set -e; for subdir in $(SUBDIRS); do \
                $(MAKE) -C $$subdir $@; \
        done
+       $(MAKE) ioemuclean
 
 check:
        $(MAKE) -C check
diff --git a/tools/ioemu/COPYING b/tools/ioemu/COPYING
new file mode 100644 (file)
index 0000000..e77696a
--- /dev/null
@@ -0,0 +1,339 @@
+                   GNU GENERAL PUBLIC LICENSE
+                      Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                          675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+\f
+                   GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+\f
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+\f
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+\f
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                           NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                    END OF TERMS AND CONDITIONS
+\f
+           How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) 19yy  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) 19yy name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/tools/ioemu/COPYING.LIB b/tools/ioemu/COPYING.LIB
new file mode 100644 (file)
index 0000000..223ede7
--- /dev/null
@@ -0,0 +1,504 @@
+                 GNU LESSER GENERAL PUBLIC LICENSE
+                      Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+\f
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+\f
+                 GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+\f
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+\f
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                           NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                    END OF TERMS AND CONDITIONS
+\f
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/tools/ioemu/Changelog b/tools/ioemu/Changelog
new file mode 100644 (file)
index 0000000..cebbbc8
--- /dev/null
@@ -0,0 +1,295 @@
+version 0.6.1:
+
+  - Mac OS X port (Pierre d'Herbemont)
+  - Virtual console support
+  - Better monitor line edition
+  - New block device layer 
+  - New 'qcow' growable disk image support with AES encryption and
+    transparent decompression
+  - VMware 3 and 4 read-only disk image support (untested)
+  - Support for up to 4 serial ports
+  - TFTP server support (Magnus Damm)
+  - Port redirection support in user mode networking
+  - Support for not executable data sections
+  - Compressed loop disk image support (Johannes Schindelin)
+  - Level triggered IRQ fix (aka NE2000 PCI performance fix) (Steve
+    Wormley)
+  - Fixed Fedora Core 2 problems (now you can run qemu without any
+    LD_ASSUME_KERNEL tricks on FC2)
+  - DHCP fix for Windows (accept DHCPREQUEST alone)
+  - SPARC system emulation (Blue Swirl)
+  - Automatic Samba configuration for host file access from Windows.
+  - '-loadvm' and '-full-screen' options
+  - ne2000 savevm support (Johannes Schindelin)
+  - Ctrl-Alt is now the default grab key. Ctrl-Alt-[0-9] switches to
+    the virtual consoles.
+  - BIOS floppy fix for NT4 (Mike Nordell, Derek Fawcus, Volker Ruppert)
+  - Floppy fixes for NT4 and NT5 (Mike Nordell)
+  - NT4 IDE fixes (Ben Pfaf, Mike Nordell)
+  - SDL Audio support and SB16 fixes (malc)
+  - ENTER instruction bug fix (initial patch by Stefan Kisdaroczi)
+  - VGA font change fix
+  - VGA read-only CRTC register fix
+
+version 0.6.0:
+
+  - minimalist FPU exception support (NetBSD FPU probe fix)
+  - cr0.ET fix (Win95 boot)
+  - *BSD port (Markus Niemisto)
+  - I/O access fix (signaled by Mark Jonckheere)
+  - IDE drives serial number fix (Mike Nordell)
+  - int13 CDROM BIOS fix (aka Solaris x86 install CD fix)
+  - int15, ah=86 BIOS fix (aka Solaris x86 hardware probe hang up fix)
+  - BSR/BSF "undefined behaviour" fix
+  - vmdk2raw: convert VMware disk images to raw images
+  - PCI support
+  - NE2K PCI support
+  - dummy VGA PCI support
+  - VGA font selection fix (Daniel Serpell)
+  - PIC reset fix (Hidemi KAWAI)
+  - PIC spurious irq support (aka Solaris install bug)
+  - added '-localtime' option
+  - Cirrus CL-GD54xx VGA support (initial patch by Makoto Suzuki (suzu))
+  - APM and system shutdown support
+  - Fixed system reset
+  - Support for other PC BIOSes
+  - Initial PowerMac hardware emulation
+  - PowerMac/PREP OpenFirmware compatible BIOS (Jocelyn Mayer)
+  - initial IDE BMDMA support (needed for Darwin x86)
+  - Set the default memory size for PC emulation to 128 MB
+
+version 0.5.5:
+
+  - SDL full screen support (initial patch by malc)
+  - VGA support on PowerPC PREP
+  - VBE fixes (Matthew Mastracci)
+  - PIT fixes (aka Win98 hardware probe and "VGA slowness" bug)
+  - IDE master only fixes (aka Win98 CD-ROM probe bug)
+  - ARM load/store half word fix (Ulrich Hecht)
+  - FDC fixes for Win98
+
+version 0.5.4:
+  
+  - qemu-fast fixes
+  - BIOS area protection fix (aka EMM386.EXE fix) (Mike Nordell)
+  - keyboard/mouse fix (Mike Nordell)
+  - IDE fixes (Linux did not recognized slave drivers)
+  - VM86 EIP masking fix (aka NT5 install fix) (Mike Nordell)
+  - QEMU can now boot a PowerPC Linux kernel (Jocelyn Mayer)
+  - User mode network stack
+  - imul imm8 fix + 0x82 opcode support (Hidemi KAWAI)
+  - precise self modifying code (aka BeOS install bug)
+
+version 0.5.3:
+
+  - added Bochs VESA VBE support
+  - VGA memory map mode 3 access fix (OS/2 install fix)
+  - IDE fixes (Jens Axboe)
+  - CPU interrupt fixes
+  - fixed various TLB invalidation cases (NT install)
+  - fixed cr0.WP semantics (XP install)
+  - direct chaining support for SPARC and PowerPC (faster)
+  - ARM NWFPE support (initial patch by Ulrich Hecht)
+  - added specific x86 to x86 translator (close to native performance
+    in qemu-i386 and qemu-fast)
+  - shm syscalls support (Paul McKerras)
+  - added accurate CR0.MP/ME/TS emulation
+  - fixed DMA memory write access (Win95 boot floppy fix)
+  - graphical x86 linux loader
+  - command line monitor 
+  - generic removable device support
+  - support of CD-ROM change
+  - multiple network interface support
+  - initial x86-64 host support (Gwenole Beauchesne)
+  - lret to outer priviledge fix (OS/2 install fix)
+  - task switch fixes (SkyOS boot)
+  - VM save/restore commands
+  - new timer API
+  - more precise RTC emulation (periodic timers + time updates)
+  - Win32 port (initial patch by Kazu)
+
+version 0.5.2:
+
+  - improved soft MMU speed (assembly functions and specializing)
+  - improved multitasking speed by avoiding flushing TBs when
+    switching tasks
+  - improved qemu-fast speed
+  - improved self modifying code handling (big performance gain in
+    softmmu mode).
+  - fixed IO checking
+  - fixed CD-ROM detection (win98 install CD)
+  - fixed addseg real mode bug (GRUB boot fix)
+  - added ROM memory support (win98 boot)
+  - fixed 'call Ev' in case of paging exception
+  - updated the script 'qemu-binfmt-conf.sh' to use QEMU automagically
+    when launching executables for the supported target CPUs.
+  - PowerPC system emulation update (Jocelyn Mayer)
+  - PC floppy emulation and DMA fixes (Jocelyn Mayer)
+  - polled mode for PIC (Jocelyn Mayer)
+  - fixed PTE dirty bit handling
+  - fixed xadd same reg bug
+  - fixed cmpxchg exception safeness
+  - access to virtual memory in gdb stub
+  - task gate and NT flag fixes
+  - eflags optimisation fix for string operations
+
+version 0.5.1:
+  
+  - float access fixes when using soft mmu
+  - PC emulation support on PowerPC
+  - A20 support
+  - IDE CD-ROM emulation
+  - ARM fixes (Ulrich Hecht)
+  - SB16 emulation (malc)
+  - IRET and INT fixes in VM86 mode with IOPL=3
+  - Port I/Os use TSS io map
+  - Full task switching/task gate support
+  - added verr, verw, arpl, fcmovxx
+  - PowerPC target support (Jocelyn Mayer)
+  - Major SPARC target fixes (dynamically linked programs begin to work)
+
+version 0.5.0:
+  
+  - full hardware level VGA emulation
+  - graphical display with SDL
+  - added PS/2 mouse and keyboard emulation
+  - popw (%esp) fix
+  - mov to/from segment data width fix
+  - added real mode support
+  - added Bochs BIOS and LGPL'ed VGA BIOS loader in qemu
+  - m68k host port (Richard Zidlicky)
+  - partial soft MMU support for memory mapped I/Os
+  - multi-target build
+  - fixed: no error code in hardware interrupts
+  - fixed: pop ss, mov ss, x and sti disable hardware irqs for the next insn
+  - correct single stepping thru string operations
+  - preliminary SPARC target support (Thomas M. Ogrisegg)
+  - tun-fd option (Rusty Russell)
+  - automatic IDE geometry detection
+  - renamed 'vl' to qemu[-fast] and user qemu to qemu-{cpu}.
+  - added man page
+  - added full soft mmu mode to launch unpatched OSes.
+
+version 0.4.3:
+
+  - x86 exception fix in case of nop instruction.
+  - gcc 3.2.2 bug workaround (RedHat 9 fix)
+  - sparc and Alpha host fixes
+  - many ARM target fixes: 'ls' and 'bash' can be launched.
+
+version 0.4.2:
+
+ - many exception handling fixes (can compile a Linux kernel inside vl)
+ - IDE emulation support
+ - initial GDB stub support
+ - deferred update support for disk images (Rusty Russell)
+ - accept User Mode Linux Copy On Write disk images
+ - SMP kernels can at least be booted
+
+version 0.4.1:
+  
+ - more accurate timer support in vl.
+ - more reliable NE2000 probe in vl.
+ - added 2.5.66 kernel in vl-test.
+ - added VLTMPDIR environment variable in vl.
+
+version 0.4:
+
+ - initial support for ring 0 x86 processor emulation
+ - fixed signal handling for correct dosemu DPMI emulation
+ - fast x86 MMU emulation with mmap()
+ - fixed popl (%esp) case
+ - Linux kernel can be executed by QEMU with the 'vl' command.
+
+version 0.3:
+
+ - initial support for ARM emulation
+ - added fnsave, frstor, fnstenv, fldenv FPU instructions
+ - added FPU register save in signal emulation
+ - initial ARM port
+ - Sparc and Alpha ports work on the regression test
+ - generic ioctl number conversion
+ - fixed ioctl type conversion
+
+version 0.2:
+
+ - PowerPC disassembly and ELF symbols output (Rusty Russell)
+ - flock support (Rusty Russell)
+ - ugetrlimit support (Rusty Russell)
+ - fstat64 fix (Rusty Russell)
+ - initial Alpha port (Falk Hueffner)
+ - initial IA64 port (Matt Wilson)
+ - initial Sparc and Sparc64 port (David S. Miller)
+ - added HLT instruction
+ - LRET instruction fix.
+ - added GPF generation for I/Os.
+ - added INT3 and TF flag support.
+ - SHL instruction C flag fix.
+ - mmap emulation for host page size > 4KB
+ - self-modifying code support
+ - better VM86 support (dosemu works on non trivial programs)
+ - precise exception support (EIP is computed correctly in most cases)
+ - more precise LDT/GDT/IDT emulation
+ - faster segment load in vm86 mode
+ - direct chaining of basic blocks (faster emulation)
+
+version 0.1.6:
+
+ - automatic library search system. QEMU can now work with unpatched
+   ELF dynamic loader and libc (Rusty Russell).
+ - ISO C warning fixes (Alistair Strachan)
+ - first self-virtualizable version (works only as long as the
+   translation cache is not flushed)
+ - RH9 fixes
+
+version 0.1.5:
+
+ - ppc64 support + personality() patch (Rusty Russell)
+ - first Alpha CPU patches (Falk Hueffner)
+ - removed bfd.h dependancy
+ - fixed shrd, shld, idivl and divl on PowerPC.
+ - fixed buggy glibc PowerPC rint() function (test-i386 passes now on PowerPC).
+
+version 0.1.4:
+
+ - more accurate VM86 emulation (can launch small DOS 16 bit
+   executables in wine).
+ - fixed push/pop fs/gs
+ - added iret instruction.
+ - added times() syscall and SIOCATMARK ioctl.
+
+version 0.1.3:
+
+ - S390 support (Ulrich Weigand)
+ - glibc 2.3.x compile fix (Ulrich Weigand)
+ - socketcall endian fix (Ulrich Weigand)
+ - struct sockaddr endian fix (Ulrich Weigand)
+ - sendmsg/recvmsg endian fix (Ulrich Weigand)
+ - execve endian fix (Ulrich Weigand)
+ - fdset endian fix (Ulrich Weigand)
+ - partial setsockopt syscall support (Ulrich Weigand)
+ - more accurate pushf/popf emulation
+ - first partial vm86() syscall support (can be used with runcom example).
+ - added bound, cmpxchg8b, cpuid instructions
+ - added 16 bit addressing support/override for string operations
+ - poll() fix
+version 0.1.2:
+
+ - compile fixes
+ - xlat instruction
+ - xchg instruction memory lock
+ - added simple vm86 example (not working with QEMU yet). The 54 byte
+   DOS executable 'pi_10.com' program was released by Bertram
+   Felgenhauer (more information at http://www.boo.net/~jasonp/pipage.html).
+
+version 0.1.1:
+
+ - glibc 2.2 compilation fixes
+ - added -s and -L options
+ - binary distribution of x86 glibc and wine
+ - big endian fixes in ELF loader and getdents.
+
+version 0.1:
+
+ - initial public release.
index 24215c5a6f4ce4b02d2d395fa565fd2e529e9afe..fc38fde186a591ee5e7075f496b35e0deead703c 100644 (file)
-# Order is important!
-SUBDIRS=gui memory iodev
+-include config-host.mak
 
-.PHONY: all clean install
+CFLAGS=-Wall -O2 -g -fno-strict-aliasing 
+ifdef CONFIG_DARWIN
+CFLAGS+= -mdynamic-no-pic
+endif
+ifdef CONFIG_WIN32
+CFLAGS+=-fpack-struct 
+endif
+LDFLAGS=-g
+LIBS=
+DEFINES+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
+TOOLS=qemu-img
+ifdef CONFIG_STATIC
+LDFLAGS+=-static
+endif
+DOCS=qemu-doc.html qemu-tech.html qemu.1
 
-all:
-       @for subdir in $(SUBDIRS); do                           \
-               $(MAKE) -C $$subdir $(MAKEDEFS) $@ || exit -1;  \
-       done
+all: $(DOCS) HEADERS
+       for d in $(TARGET_DIRS); do \
+       $(MAKE) -C $$d $@ || exit 1 ; \
+        done
+
+qemu-img: qemu-img.c block.c block-cow.c block-qcow.c aes.c block-vmdk.c block-cloop.c
+       $(CC) -DQEMU_TOOL $(CFLAGS) $(LDFLAGS) $(DEFINES) -o $@ $^ -lz $(LIBS)
+
+dyngen$(EXESUF): dyngen.c
+       $(HOST_CC) $(CFLAGS) $(DEFINES) -o $@ $^
 
 clean:
-       @for subdir in $(SUBDIRS); do                           \
-               $(MAKE) -C $$subdir $(MAKEDEFS) $@ || exit -1;  \
-       done
-
-install:
-       @for subdir in $(SUBDIRS); do                           \
-               $(MAKE) -C $$subdir $(MAKEDEFS) $@ || exit -1;  \
-       done
+# avoid old build problems by removing potentially incorrect old files
+       rm -f config.mak config.h op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h gen-op-arm.h 
+       rm -f *.o *.a $(TOOLS) dyngen$(EXESUF) TAGS qemu.pod *~ */*~
+       $(MAKE) -C tests clean
+       for d in $(TARGET_DIRS); do \
+       $(MAKE) -C $$d $@ || exit 1 ; \
+        done
+
+distclean: clean
+       rm -f config-host.mak config-host.h
+       rm -f keysym_adapter_sdl.h keysym_adapter_vnc.h
+       for d in $(TARGET_DIRS); do \
+       rm -rf $$d || exit 1 ; \
+        done
+
+KEYMAPS=da     en-gb  et  fr     fr-ch  is  lt  modifiers  no  pt-br  sv \
+ar      de     en-us  fi  fr-be  hr     it  lv  nl         pl  ru     th \
+common  de-ch  es     fo  fr-ca  hu     ja  mk  nl-be      pt  sl     tr
+
+install: all 
+       mkdir -p "$(bindir)"
+ifndef CONFIG_WIN32
+#      install -m 755 -s $(TOOLS) "$(bindir)"
+endif
+       mkdir -p "$(DESTDIR)/$(datadir)"
+       install -m 644 pc-bios/bios.bin pc-bios/vgabios.bin \
+                       pc-bios/vgabios-cirrus.bin \
+                       pc-bios/ppc_rom.bin \
+                       pc-bios/proll.bin \
+                       pc-bios/linux_boot.bin "$(DESTDIR)/$(datadir)"
+       mkdir -p "$(DESTDIR)/$(docdir)"
+       install -m 644 qemu-doc.html  qemu-tech.html "$(DESTDIR)/$(docdir)"
+ifndef CONFIG_WIN32
+       mkdir -p "$(DESTDIR)/$(mandir)/man1"
+       install qemu.1 qemu-mkcow.1 "$(DESTDIR)/$(mandir)/man1"
+       mkdir -p "$(DESTDIR)/$(datadir)/keymaps"
+       install -m 644 $(addprefix keymaps/,$(KEYMAPS)) "$(DESTDIR)/$(datadir)/keymaps"
+endif
+       for d in $(TARGET_DIRS); do \
+       $(MAKE) -C $$d $@ || exit 1 ; \
+        done
+
+# various test targets
+test speed test2: all
+       $(MAKE) -C tests $@
+
+TAGS: 
+       etags *.[ch] tests/*.[ch]
+
+# documentation
+%.html: %.texi
+       texi2html -monolithic -number $<
+
+qemu.1: qemu-doc.texi
+       ./texi2pod.pl $< qemu.pod
+       pod2man --section=1 --center=" " --release=" " qemu.pod > $@
+
+FILE=qemu-$(shell cat VERSION)
+
+# tar release (use 'make -k tar' on a checkouted tree)
+tar:
+       rm -rf /tmp/$(FILE)
+       cp -r . /tmp/$(FILE)
+       ( cd /tmp ; tar zcvf ~/$(FILE).tar.gz $(FILE) --exclude CVS )
+       rm -rf /tmp/$(FILE)
+
+# generate a binary distribution
+tarbin:
+       ( cd $(DESTDIR) ; tar zcvf ~/qemu-$(VERSION)-i386.tar.gz \
+       $(DESTDIR)/$(bindir)/qemu $(DESTDIR)/$(bindir)/qemu-fast \
+       $(DESTDIR)/$(bindir)/qemu-system-ppc \
+       $(DESTDIR)/$(bindir)/qemu-i386 \
+        $(DESTDIR)/$(bindir)/qemu-arm \
+        $(DESTDIR)/$(bindir)/qemu-sparc \
+        $(DESTDIR)/$(bindir)/qemu-ppc \
+       $(DESTDIR)/$(datadir)/bios.bin \
+       $(DESTDIR)/$(datadir)/vgabios.bin \
+       $(DESTDIR)/$(datadir)/vgabios-cirrus.bin \
+       $(DESTDIR)/$(datadir)/ppc_rom.bin \
+       $(DESTDIR)/$(datadir)/proll.bin \
+       $(DESTDIR)/$(datadir)/linux_boot.bin \
+       $(DESTDIR)/$(docdir)/qemu-doc.html \
+       $(DESTDIR)/$(docdir)/qemu-tech.html \
+       $(DESTDIR)/$(mandir)/man1/qemu.1 $(DESTDIR)/$(mandir)/man1/qemu-mkcow.1 )
+
+ifneq ($(wildcard .depend),)
+include .depend
+endif
+
+HEADERS:
+
+ifdef CONFIG_SDL
+HEADERS: keysym_adapter_sdl.h
+endif
+
+ifdef CONFIG_VNC
+HEADERS: keysym_adapter_vnc.h
+endif
+
+keysym_adapter_sdl.h: Makefile create_keysym_header.sh
+       sh create_keysym_header.sh sdl "$(SDL_CFLAGS)"
+
+keysym_adapter_vnc.h: Makefile create_keysym_header.sh
+       sh create_keysym_header.sh vnc "$(VNC_CFLAGS)"
+
+
diff --git a/tools/ioemu/Makefile.target b/tools/ioemu/Makefile.target
new file mode 100644 (file)
index 0000000..933e624
--- /dev/null
@@ -0,0 +1,392 @@
+include config.mak
+
+#assume we directly put qemu code in tools/, same level as bochs dm(ioemu)
+XEN_PATH=../../..
+TARGET_PATH=$(SRC_PATH)/target-$(TARGET_ARCH)
+VPATH=$(SRC_PATH):$(TARGET_PATH):$(SRC_PATH)/hw:$(SRC_PATH)/audio
+DEFINES=-I. -I$(TARGET_PATH) -I$(SRC_PATH) -I$(XEN_PATH)/xen/include/public
+DEFINES+= -I$(XEN_PATH)/tools/libxc
+ifdef CONFIG_USER_ONLY
+VPATH+=:$(SRC_PATH)/linux-user
+DEFINES+=-I$(SRC_PATH)/linux-user -I$(SRC_PATH)/linux-user/$(TARGET_ARCH)
+endif
+CFLAGS=-Wall -O2 -g -fno-strict-aliasing
+LDFLAGS=-g
+LIBS=
+HELPER_CFLAGS=$(CFLAGS)
+DYNGEN=../dyngen$(EXESUF)
+# user emulator name
+QEMU_USER=qemu-$(TARGET_ARCH)
+# system emulator name
+ifdef CONFIG_SOFTMMU
+ifeq ($(TARGET_ARCH), i386)
+QEMU_SYSTEM=qemu$(EXESUF)
+else
+QEMU_SYSTEM=qemu-system-$(TARGET_ARCH)$(EXESUF)
+endif
+else
+QEMU_SYSTEM=qemu-fast
+endif
+
+QEMU_SYSTEM=qemu-dm
+PROGS=$(QEMU_SYSTEM)
+
+ifdef CONFIG_USER_ONLY
+PROGS=$(QEMU_USER)
+else
+ifeq ($(TARGET_ARCH), i386)
+
+ifeq ($(ARCH), i386)
+PROGS+=$(QEMU_SYSTEM)
+ifndef CONFIG_SOFTMMU
+CONFIG_STATIC=y
+endif
+else
+# the system emulator using soft mmu is portable
+ifdef CONFIG_SOFTMMU
+PROGS+=$(QEMU_SYSTEM)
+endif
+endif # ARCH != i386
+
+endif # TARGET_ARCH = i386
+
+ifeq ($(TARGET_ARCH), ppc)
+
+ifeq ($(ARCH), ppc)
+PROGS+=$(QEMU_SYSTEM)
+endif
+
+ifeq ($(ARCH), i386)
+ifdef CONFIG_SOFTMMU
+PROGS+=$(QEMU_SYSTEM)
+endif
+endif # ARCH = i386
+
+ifeq ($(ARCH), amd64)
+ifdef CONFIG_SOFTMMU
+PROGS+=$(QEMU_SYSTEM)
+endif
+endif # ARCH = amd64
+
+endif # TARGET_ARCH = ppc
+
+ifeq ($(TARGET_ARCH), sparc)
+
+ifeq ($(ARCH), ppc)
+PROGS+=$(QEMU_SYSTEM)
+endif
+
+ifeq ($(ARCH), i386)
+ifdef CONFIG_SOFTMMU
+PROGS+=$(QEMU_SYSTEM)
+endif
+endif # ARCH = i386
+
+ifeq ($(ARCH), amd64)
+ifdef CONFIG_SOFTMMU
+PROGS+=$(QEMU_SYSTEM)
+endif
+endif # ARCH = amd64
+
+endif # TARGET_ARCH = sparc
+endif # !CONFIG_USER_ONLY
+
+ifdef CONFIG_STATIC
+LDFLAGS+=-static
+endif
+
+ifeq ($(ARCH),i386)
+CFLAGS+=-fomit-frame-pointer
+OP_CFLAGS=$(CFLAGS) -mpreferred-stack-boundary=2
+ifeq ($(HAVE_GCC3_OPTIONS),yes)
+OP_CFLAGS+= -falign-functions=0 -fno-gcse
+else
+OP_CFLAGS+= -malign-functions=0
+endif
+
+ifdef TARGET_GPROF
+USE_I386_LD=y
+endif
+ifdef CONFIG_STATIC
+USE_I386_LD=y
+endif
+ifdef USE_I386_LD
+LDFLAGS+=-Wl,-T,$(SRC_PATH)/i386.ld
+else
+# WARNING: this LDFLAGS is _very_ tricky : qemu is an ELF shared object
+# that the kernel ELF loader considers as an executable. I think this
+# is the simplest way to make it self virtualizable!
+LDFLAGS+=-Wl,-shared
+endif
+endif
+
+ifeq ($(ARCH),amd64)
+OP_CFLAGS=$(CFLAGS) -falign-functions=0
+LDFLAGS+=-Wl,-T,$(SRC_PATH)/amd64.ld
+endif
+
+ifeq ($(ARCH),ppc)
+CFLAGS+= -D__powerpc__
+OP_CFLAGS=$(CFLAGS)
+LDFLAGS+=-Wl,-T,$(SRC_PATH)/ppc.ld
+endif
+
+ifeq ($(ARCH),s390)
+OP_CFLAGS=$(CFLAGS)
+LDFLAGS+=-Wl,-T,$(SRC_PATH)/s390.ld
+endif
+
+ifeq ($(ARCH),sparc)
+CFLAGS+=-m32 -ffixed-g1 -ffixed-g2 -ffixed-g3 -ffixed-g6
+LDFLAGS+=-m32
+OP_CFLAGS=$(CFLAGS) -fno-delayed-branch -ffixed-i0
+HELPER_CFLAGS=$(CFLAGS) -ffixed-i0 -mflat
+# -static is used to avoid g1/g3 usage by the dynamic linker
+LDFLAGS+=-Wl,-T,$(SRC_PATH)/sparc.ld -static
+endif
+
+ifeq ($(ARCH),sparc64)
+CFLAGS+=-m64 -ffixed-g1 -ffixed-g2 -ffixed-g3 -ffixed-g6
+LDFLAGS+=-m64
+OP_CFLAGS=$(CFLAGS) -fno-delayed-branch -ffixed-i0
+endif
+
+ifeq ($(ARCH),alpha)
+# -msmall-data is not used because we want two-instruction relocations
+# for the constant constructions
+OP_CFLAGS=-Wall -O2 -g
+# Ensure there's only a single GP
+CFLAGS += -msmall-data
+LDFLAGS+=-Wl,-T,$(SRC_PATH)/alpha.ld
+endif
+
+ifeq ($(ARCH),ia64)
+OP_CFLAGS=$(CFLAGS)
+endif
+
+ifeq ($(ARCH),arm)
+OP_CFLAGS=$(CFLAGS) -mno-sched-prolog
+LDFLAGS+=-Wl,-T,$(SRC_PATH)/arm.ld
+endif
+
+ifeq ($(ARCH),m68k)
+OP_CFLAGS=$(CFLAGS) -fomit-frame-pointer
+LDFLAGS+=-Wl,-T,m68k.ld
+endif
+
+ifeq ($(HAVE_GCC3_OPTIONS),yes)
+# very important to generate a return at the end of every operation
+OP_CFLAGS+=-fno-reorder-blocks -fno-optimize-sibling-calls
+endif
+
+ifeq ($(CONFIG_DARWIN),yes)
+OP_CFLAGS+= -mdynamic-no-pic
+endif
+
+#########################################################
+
+DEFINES+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
+LIBS+=-lm -L$(XEN_PATH)/dist/install/usr/$(LIBDIR) -lxc -lxutil
+ifndef CONFIG_USER_ONLY
+LIBS+=-lz
+endif
+ifdef CONFIG_WIN32
+LIBS+=-lwinmm -lws2_32 -liphlpapi
+endif
+
+# profiling code
+ifdef TARGET_GPROF
+LDFLAGS+=-p
+main.o: CFLAGS+=-p
+endif
+
+OBJS= elfload.o main.o syscall.o mmap.o signal.o path.o osdep.o thunk.o 
+ifeq ($(TARGET_ARCH), i386)
+OBJS+= vm86.o
+endif
+ifeq ($(TARGET_ARCH), arm)
+OBJS+=nwfpe/softfloat.o nwfpe/fpa11.o nwfpe/fpa11_cpdo.o \
+nwfpe/fpa11_cpdt.o nwfpe/fpa11_cprt.o nwfpe/fpopcode.o nwfpe/single_cpdo.o \
+ nwfpe/double_cpdo.o nwfpe/extended_cpdo.o
+endif
+SRCS:= $(OBJS:.o=.c)
+OBJS+= libqemu.a
+
+# cpu emulator library
+LIBOBJS=
+
+ifeq ($(TARGET_ARCH), i386)
+LIBOBJS+= helper2.o
+ifeq ($(ARCH), i386)
+LIBOBJS+=translate-copy.o
+endif
+endif
+
+ifeq ($(TARGET_ARCH), ppc)
+LIBOBJS+= op_helper.o helper.o
+endif
+
+ifeq ($(TARGET_ARCH), sparc)
+LIBOBJS+= op_helper.o helper.o
+endif
+
+all: $(PROGS)
+
+$(QEMU_USER): $(OBJS)
+       $(CC) $(LDFLAGS) -o $@ $^  $(LIBS)
+ifeq ($(ARCH),alpha)
+# Mark as 32 bit binary, i. e. it will be mapped into the low 31 bit of
+# the address space (31 bit so sign extending doesn't matter)
+       echo -ne '\001\000\000\000' | dd of=qemu bs=1 seek=48 count=4 conv=notrunc
+endif
+
+# must use static linking to avoid leaving stuff in virtual address space
+VL_OBJS=vl.o exec.o monitor.o osdep.o block.o readline.o pci.o console.o 
+#VL_OBJS+=block-cow.o block-qcow.o block-vmdk.o block-cloop.o
+VL_OBJS+= block-cloop.o
+
+SOUND_HW = sb16.o
+AUDIODRV = audio.o noaudio.o wavaudio.o
+ifdef CONFIG_SDL
+AUDIODRV += sdlaudio.o
+endif
+ifdef CONFIG_OSS
+AUDIODRV += ossaudio.o
+endif
+
+pc.o: DEFINES := -DUSE_SB16 $(DEFINES)
+
+ifdef CONFIG_ADLIB
+SOUND_HW += fmopl.o adlib.o
+endif
+
+ifdef CONFIG_FMOD
+AUDIODRV += fmodaudio.o
+audio.o fmodaudio.o: DEFINES := -I$(CONFIG_FMOD_INC) $(DEFINES)
+LIBS += $(CONFIG_FMOD_LIB)
+endif
+
+# Hardware support
+VL_OBJS+= ide.o ne2000.o pckbd.o vga.o dma.o
+VL_OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pc.o
+
+ifeq ($(TARGET_ARCH), ppc)
+VL_OBJS+= ppc.o ide.o ne2000.o pckbd.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
+VL_OBJS+= mc146818rtc.o serial.o i8259.o i8254.o fdc.o m48t59.o
+VL_OBJS+= ppc_prep.o ppc_chrp.o cuda.o adb.o openpic.o mixeng.o
+endif
+ifeq ($(TARGET_ARCH), sparc)
+VL_OBJS+= sun4m.o tcx.o lance.o iommu.o sched.o m48t08.o magic-load.o timer.o
+endif
+ifdef CONFIG_GDBSTUB
+VL_OBJS+=gdbstub.o 
+endif
+ifdef CONFIG_VNC
+VL_OBJS+=vnc.o
+endif
+ifdef CONFIG_SDL
+VL_OBJS+=sdl.o
+endif
+ifdef CONFIG_SLIRP
+DEFINES+=-I$(SRC_PATH)/slirp
+SLIRP_OBJS=cksum.o if.o ip_icmp.o ip_input.o ip_output.o \
+slirp.o mbuf.o misc.o sbuf.o socket.o tcp_input.o tcp_output.o \
+tcp_subr.o tcp_timer.o udp.o bootp.o debug.o tftp.o
+VL_OBJS+=$(addprefix slirp/, $(SLIRP_OBJS))
+endif
+
+VL_LDFLAGS=
+# specific flags are needed for non soft mmu emulator
+ifdef CONFIG_STATIC
+VL_LDFLAGS+=-static
+endif
+ifndef CONFIG_SOFTMMU
+VL_LDFLAGS+=-Wl,-T,$(SRC_PATH)/i386-vl.ld
+endif
+ifndef CONFIG_DARWIN
+ifndef CONFIG_WIN32
+VL_LIBS=-lutil
+endif
+endif
+
+$(QEMU_SYSTEM): $(VL_OBJS) libqemu.a
+       $(CC) $(VL_LDFLAGS) -o $@ $^ $(LIBS) $(SDL_LIBS) $(VNC_LIBS) $(VL_LIBS)
+
+vnc.o: vnc.c keyboard_rdesktop.c
+       $(CC) $(CFLAGS) $(DEFINES) $(VNC_CFLAGS) -c -o $@ $<
+
+sdl.o: sdl.c keyboard_rdesktop.c
+       $(CC) $(CFLAGS) $(DEFINES) $(SDL_CFLAGS) -c -o $@ $<
+
+sdlaudio.o: sdlaudio.c
+       $(CC) $(CFLAGS) $(DEFINES) $(SDL_CFLAGS) -c -o $@ $<
+
+depend: $(SRCS)
+       $(CC) -MM $(CFLAGS) $(DEFINES) $^ 1>.depend
+
+# libqemu 
+
+libqemu.a: $(LIBOBJS)
+       rm -f $@
+       $(AR) rcs $@ $(LIBOBJS)
+
+translate.o: translate.c gen-op.h opc.h cpu.h
+
+translate-all.o: translate-all.c op.h opc.h cpu.h
+
+op.h: op.o $(DYNGEN)
+       $(DYNGEN) -o $@ $<
+
+opc.h: op.o $(DYNGEN)
+       $(DYNGEN) -c -o $@ $<
+
+gen-op.h: op.o $(DYNGEN)
+       $(DYNGEN) -g -o $@ $<
+
+op.o: op.c
+       $(CC) $(OP_CFLAGS) $(DEFINES) -c -o $@ $<
+
+helper.o: helper.c
+       $(CC) $(HELPER_CFLAGS) $(DEFINES) -c -o $@ $<
+
+ifeq ($(TARGET_ARCH), i386)
+op.o: op.c opreg_template.h ops_template.h ops_template_mem.h ops_mem.h
+endif
+
+ifeq ($(TARGET_ARCH), arm)
+op.o: op.c op_template.h
+endif
+
+ifeq ($(TARGET_ARCH), sparc)
+op.o: op.c op_template.h op_mem.h
+endif
+
+ifeq ($(TARGET_ARCH), ppc)
+op.o: op.c op_template.h op_mem.h
+op_helper.o: op_helper_mem.h
+endif
+
+mixeng.o: mixeng.c mixeng.h mixeng_template.h
+
+%.o: %.c
+       $(CC) $(CFLAGS) $(DEFINES) -c -o $@ $<
+
+%.o: %.S
+       $(CC) $(DEFINES) -c -o $@ $<
+
+clean:
+       rm -rf *.o  *.a *~ $(PROGS) gen-op.h opc.h op.h nwfpe slirp qemu-vgaram-bin
+
+install: all 
+       if [ ! -d $(DESTDIR)$(bindir) ];then mkdir -p $(DESTDIR)$(bindir);fi
+       if [ ! -d $(DESTDIR)$(configdir) ];then mkdir -p $(DESTDIR)$(configdir);fi
+ifneq ($(PROGS),)
+       install -m 755 -s $(PROGS) "$(DESTDIR)$(bindir)"
+endif
+       install -m 755 device-model "$(DESTDIR)$(bindir)"
+       install -m 755 qemu-ifup "$(DESTDIR)$(configdir)"
+       gunzip -c qemu-vgaram-bin.gz >qemu-vgaram-bin 
+       install -m 755 qemu-vgaram-bin "$(DESTDIR)$(configdir)"
+ifneq ($(wildcard .depend),)
+include .depend
+endif
diff --git a/tools/ioemu/README b/tools/ioemu/README
new file mode 100644 (file)
index 0000000..0303067
--- /dev/null
@@ -0,0 +1,61 @@
+The QEMU x86 emulator
+---------------------
+
+INSTALLATION
+------------
+
+Type 
+
+    ./configure
+    make
+
+to build qemu, qemu-CPU and libqemu.a (CPU is the name of the various
+supported target CPUs).
+
+Type
+
+    make install
+
+to install QEMU in /usr/local
+
+Tested tool versions
+--------------------
+
+In order to compile QEMU succesfully, it is very important that you
+have the right tools. The most important one is gcc. I cannot guaranty
+that QEMU works if you do not use a tested gcc version. Look at
+'configure' and 'Makefile' if you want to make a different gcc
+version work.
+
+host      gcc      binutils      glibc    linux       distribution
+----------------------------------------------------------------------
+x86       2.95.2   2.13.2        2.1.3    2.4.18           
+          3.2      2.13.2        2.1.3    2.4.18
+          2.96     2.11.93.0.2   2.2.5    2.4.18      Red Hat 7.3
+          3.2.2    2.13.90.0.18  2.3.2    2.4.20      Red Hat 9
+
+PowerPC   3.3 [4]  2.13.90.0.18  2.3.1    2.4.20briq
+          3.2
+
+Alpha     3.3 [1]  2.14.90.0.4   2.2.5    2.2.20 [2]  Debian 3.0
+
+Sparc32   2.95.4   2.12.90.0.1   2.2.5    2.4.18      Debian 3.0
+
+ARM       2.95.4   2.12.90.0.1   2.2.5    2.4.9 [3]   Debian 3.0
+
+[1] On Alpha, QEMU needs the gcc 'visibility' attribute only available
+    for gcc version >= 3.3.
+[2] Linux >= 2.4.20 is necessary for precise exception support
+    (untested).
+[3] 2.4.9-ac10-rmk2-np1-cerf2
+
+[4] gcc 2.95.x generates invalid code when using too many register
+variables. You must use gcc 3.x on PowerPC.
+
+Documentation
+-------------
+
+Read the documentation in qemu-doc.html.
+
+
+Fabrice Bellard.
\ No newline at end of file
diff --git a/tools/ioemu/README.distrib b/tools/ioemu/README.distrib
new file mode 100644 (file)
index 0000000..a1598a2
--- /dev/null
@@ -0,0 +1,16 @@
+Information about the various packages used to build the current qemu
+x86 binary distribution:
+
+* gcc 2.95.2 was used for the build. A glibc 2.1.3 Debian distribution
+  was used to get most of the binary packages.
+
+* wine-20020411 tarball
+
+  ./configure --prefix=/usr/local/wine-i386
+  
+  All exe and libs were stripped. Some compile time tools and the
+  includes were deleted.
+
+* ldconfig was launched to build the library links:
+
+  qemu-i386 /usr/gnemul/qemu-i386/bin/ldconfig-i386 -C /usr/gnemul/qemu-i386/etc/ld.so.cache
diff --git a/tools/ioemu/TODO b/tools/ioemu/TODO
new file mode 100644 (file)
index 0000000..b8e973c
--- /dev/null
@@ -0,0 +1,66 @@
+short term:
+----------
+- debug option in 'configure' script + disable -fomit-frame-pointer
+- Solaris display error with Cirrus VGA
+  (http://lists.gnu.org/archive/html/qemu-devel/2004-10/msg00390.html).
+- Precise VGA timings for old games/demos (malc patch)
+- merge PIC spurious interrupt patch
+- merge VNC keyboard patch
+- merge Solaris patch
+- merge ARM patches + self modifying code patch (Paul Brook)
+- warning for OS/2: must not use 128 MB memory
+- config file (at least for windows/Mac OS X)
+- commit message if execution of code in IO memory
+- update doc: PCI infos.
+- VNC patch + Synaptic patch.
+- basic VGA optimizations
+- test sysenter/sysexit and fxsr for L4 pistachio 686
+- physical memory cache (reduce qemu-fast address space size to about 32 MB)
+- better code fetch (different exception handling + CS.limit support)
+- do not resize vga if invalid size.
+- avoid looping if only exceptions
+- cycle counter for all archs
+- TLB code protection support for PPC
+- see openMosix Doc 
+- disable SMC handling for ARM/SPARC/PPC (not finished)
+- see undefined flags for BTx insn
+- user/kernel PUSHL/POPL in helper.c
+- keyboard output buffer filling timing emulation
+- return UD exception if LOCK prefix incorrectly used
+- test ldt limit < 7 ?
+- tests for each target CPU
+- fix CCOP optimisation
+- fix all remaining thread lock issues (must put TBs in a specific invalid
+  state, find a solution for tb_flush()).
+- fix arm fpu rounding (at least for float->integer conversions)
+- SMP support
+
+ppc specific:
+------------
+- TLB invalidate not needed if msr_pr changes
+- endianness bugs in do_load_fpscr and do_store_fpscr
+- SPR_ENCODE() not useful
+- enable shift optimizations ?
+
+lower priority:
+--------------
+- more friendly BIOS (logo)
+- int15 ah=86: use better timing
+- HDD geometry in CMOS (not used except for very old DOS programs)
+- suppress shift_mem ops
+- fix some 16 bit sp push/pop overflow (pusha/popa, lcall lret)
+- sysenter/sysexit emulation
+- optimize FPU operations (evaluate x87 stack pointer statically)
+- add IPC syscalls
+- use -msoft-float on ARM
+- use kernel traps for unaligned accesses on ARM ?
+- handle rare page fault cases (in particular if page fault in helpers or
+  in syscall emulation code).
+- fix thread stack freeing (use kernel 2.5.x CLONE_CHILD_CLEARTID)
+- more syscalls (in particular all 64 bit ones, IPCs, fix 64 bit
+  issues, fix 16 bit uid issues)
+- use page_unprotect_range in every suitable syscall to handle all
+  cases of self modifying code.
+- use gcc as a backend to generate better code (easy to do by using
+  op-i386.c operations as local inline functions).
+- add SSE2/MMX operations
diff --git a/tools/ioemu/VERSION b/tools/ioemu/VERSION
new file mode 100644 (file)
index 0000000..7ceb040
--- /dev/null
@@ -0,0 +1 @@
+0.6.1
\ No newline at end of file
diff --git a/tools/ioemu/block-cloop.c b/tools/ioemu/block-cloop.c
new file mode 100644 (file)
index 0000000..f22253d
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * QEMU System Emulator block driver
+ * 
+ * Copyright (c) 2004 Johannes E. Schindelin
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+#include "block_int.h"
+#include <zlib.h>
+
+typedef struct BDRVCloopState {
+    int fd;
+    uint32_t block_size;
+    uint32_t n_blocks;
+    uint64_t* offsets;
+    uint32_t sectors_per_block;
+    uint32_t current_block;
+    char* compressed_block;
+    char* uncompressed_block;
+    z_stream zstream;
+} BDRVCloopState;
+
+static int cloop_probe(const uint8_t *buf, int buf_size, const char *filename)
+{
+    const char* magic_version_2_0="#!/bin/sh\n"
+       "#V2.0 Format\n"
+       "modprobe cloop file=$0 && mount -r -t iso9660 /dev/cloop $1\n";
+    int length=strlen(magic_version_2_0);
+    if(length>buf_size)
+       length=buf_size;
+    if(!memcmp(magic_version_2_0,buf,length))
+       return 2;
+    return 0;
+}
+
+static int cloop_open(BlockDriverState *bs, const char *filename)
+{
+    BDRVCloopState *s = bs->opaque;
+    uint32_t offsets_size,max_compressed_block_size=1,i;
+
+    s->fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE);
+    if (s->fd < 0)
+        return -1;
+    bs->read_only = 1;
+
+    /* read header */
+    if(lseek(s->fd,128,SEEK_SET)<0) {
+cloop_close:
+       close(s->fd);
+       return -1;
+    }
+    if(read(s->fd,&s->block_size,4)<4)
+       goto cloop_close;
+    s->block_size=be32_to_cpu(s->block_size);
+    if(read(s->fd,&s->n_blocks,4)<4)
+       goto cloop_close;
+    s->n_blocks=be32_to_cpu(s->n_blocks);
+
+    /* read offsets */
+    offsets_size=s->n_blocks*sizeof(uint64_t);
+    if(!(s->offsets=(uint64_t*)malloc(offsets_size)))
+       goto cloop_close;
+    if(read(s->fd,s->offsets,offsets_size)<offsets_size)
+       goto cloop_close;
+    for(i=0;i<s->n_blocks;i++) {
+       s->offsets[i]=be64_to_cpu(s->offsets[i]);
+       if(i>0) {
+           uint32_t size=s->offsets[i]-s->offsets[i-1];
+           if(size>max_compressed_block_size)
+               max_compressed_block_size=size;
+       }
+    }
+
+    /* initialize zlib engine */
+    if(!(s->compressed_block=(char*)malloc(max_compressed_block_size+1)))
+       goto cloop_close;
+    if(!(s->uncompressed_block=(char*)malloc(s->block_size)))
+       goto cloop_close;
+    if(inflateInit(&s->zstream) != Z_OK)
+       goto cloop_close;
+    s->current_block=s->n_blocks;
+    
+    s->sectors_per_block = s->block_size/512;
+    bs->total_sectors = s->n_blocks*s->sectors_per_block;
+    return 0;
+}
+
+static inline int cloop_read_block(BDRVCloopState *s,int block_num)
+{
+    if(s->current_block != block_num) {
+       int ret;
+        uint32_t bytes = s->offsets[block_num+1]-s->offsets[block_num];
+           
+       lseek(s->fd, s->offsets[block_num], SEEK_SET);
+        ret = read(s->fd, s->compressed_block, bytes);
+        if (ret != bytes) 
+            return -1;
+       
+       s->zstream.next_in = s->compressed_block;
+       s->zstream.avail_in = bytes;
+       s->zstream.next_out = s->uncompressed_block;
+       s->zstream.avail_out = s->block_size;
+       ret = inflateReset(&s->zstream);
+       if(ret != Z_OK)
+           return -1;
+       ret = inflate(&s->zstream, Z_FINISH);
+       if(ret != Z_STREAM_END || s->zstream.total_out != s->block_size)
+           return -1;
+       
+       s->current_block = block_num;
+    }
+    return 0;
+}
+
+static int cloop_read(BlockDriverState *bs, int64_t sector_num, 
+                    uint8_t *buf, int nb_sectors)
+{
+    BDRVCloopState *s = bs->opaque;
+    int i;
+
+    for(i=0;i<nb_sectors;i++) {
+       uint32_t sector_offset_in_block=((sector_num+i)%s->sectors_per_block),
+           block_num=(sector_num+i)/s->sectors_per_block;
+       if(cloop_read_block(s, block_num) != 0)
+           return -1;
+       memcpy(buf+i*512,s->uncompressed_block+sector_offset_in_block*512,512);
+    }
+    return 0;
+}
+
+static void cloop_close(BlockDriverState *bs)
+{
+    BDRVCloopState *s = bs->opaque;
+    close(s->fd);
+    free(s->compressed_block);
+    free(s->uncompressed_block);
+    inflateEnd(&s->zstream);
+}
+
+BlockDriver bdrv_cloop = {
+    "cloop",
+    sizeof(BDRVCloopState),
+    cloop_probe,
+    cloop_open,
+    cloop_read,
+    NULL,
+    cloop_close,
+};
+
+
diff --git a/tools/ioemu/block-cow.c b/tools/ioemu/block-cow.c
new file mode 100644 (file)
index 0000000..81bd334
--- /dev/null
@@ -0,0 +1,263 @@
+/*
+ * Block driver for the COW format
+ * 
+ * Copyright (c) 2004 Fabrice Bellard
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#ifndef _WIN32
+#include "vl.h"
+#include "block_int.h"
+#include <sys/mman.h>
+
+/**************************************************************/
+/* COW block driver using file system holes */
+
+/* user mode linux compatible COW file */
+#define COW_MAGIC 0x4f4f4f4d  /* MOOO */
+#define COW_VERSION 2
+
+struct cow_header_v2 {
+    uint32_t magic;
+    uint32_t version;
+    char backing_file[1024];
+    int32_t mtime;
+    uint64_t size;
+    uint32_t sectorsize;
+};
+
+typedef struct BDRVCowState {
+    int fd;
+    uint8_t *cow_bitmap; /* if non NULL, COW mappings are used first */
+    uint8_t *cow_bitmap_addr; /* mmap address of cow_bitmap */
+    int cow_bitmap_size;
+    int64_t cow_sectors_offset;
+} BDRVCowState;
+
+static int cow_probe(const uint8_t *buf, int buf_size, const char *filename)
+{
+    const struct cow_header_v2 *cow_header = (const void *)buf;
+
+    if (be32_to_cpu(cow_header->magic) == COW_MAGIC &&
+        be32_to_cpu(cow_header->version) == COW_VERSION) 
+        return 100;
+    else
+        return 0;
+}
+
+static int cow_open(BlockDriverState *bs, const char *filename)
+{
+    BDRVCowState *s = bs->opaque;
+    int fd;
+    struct cow_header_v2 cow_header;
+    int64_t size;
+
+    fd = open(filename, O_RDWR | O_BINARY | O_LARGEFILE);
+    if (fd < 0) {
+        fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE);
+        if (fd < 0)
+            return -1;
+    }
+    s->fd = fd;
+    /* see if it is a cow image */
+    if (read(fd, &cow_header, sizeof(cow_header)) != sizeof(cow_header)) {
+        goto fail;
+    }
+
+    if (be32_to_cpu(cow_header.magic) != COW_MAGIC ||
+        be32_to_cpu(cow_header.version) != COW_VERSION) {
+        goto fail;
+    }
+        
+    /* cow image found */
+    size = be64_to_cpu(cow_header.size);
+    bs->total_sectors = size / 512;
+
+    pstrcpy(bs->backing_file, sizeof(bs->backing_file), 
+            cow_header.backing_file);
+    
+#if 0
+    if (cow_header.backing_file[0] != '\0') {
+        if (stat(cow_header.backing_file, &st) != 0) {
+            fprintf(stderr, "%s: could not find original disk image '%s'\n", filename, cow_header.backing_file);
+            goto fail;
+        }
+        if (st.st_mtime != be32_to_cpu(cow_header.mtime)) {
+            fprintf(stderr, "%s: original raw disk image '%s' does not match saved timestamp\n", filename, cow_header.backing_file);
+            goto fail;
+            }
+        fd = open(cow_header.backing_file, O_RDONLY | O_LARGEFILE);
+        if (fd < 0)
+            goto fail;
+        bs->fd = fd;
+    }
+#endif
+    /* mmap the bitmap */
+    s->cow_bitmap_size = ((bs->total_sectors + 7) >> 3) + sizeof(cow_header);
+    s->cow_bitmap_addr = mmap(get_mmap_addr(s->cow_bitmap_size), 
+                              s->cow_bitmap_size, 
+                              PROT_READ | PROT_WRITE,
+                              MAP_SHARED, s->fd, 0);
+    if (s->cow_bitmap_addr == MAP_FAILED)
+        goto fail;
+    s->cow_bitmap = s->cow_bitmap_addr + sizeof(cow_header);
+    s->cow_sectors_offset = (s->cow_bitmap_size + 511) & ~511;
+    return 0;
+ fail:
+    close(fd);
+    return -1;
+}
+
+static inline void set_bit(uint8_t *bitmap, int64_t bitnum)
+{
+    bitmap[bitnum / 8] |= (1 << (bitnum%8));
+}
+
+static inline int is_bit_set(const uint8_t *bitmap, int64_t bitnum)
+{
+    return !!(bitmap[bitnum / 8] & (1 << (bitnum%8)));
+}
+
+
+/* Return true if first block has been changed (ie. current version is
+ * in COW file).  Set the number of continuous blocks for which that
+ * is true. */
+static inline int is_changed(uint8_t *bitmap,
+                             int64_t sector_num, int nb_sectors,
+                             int *num_same)
+{
+    int changed;
+
+    if (!bitmap || nb_sectors == 0) {
+       *num_same = nb_sectors;
+       return 0;
+    }
+
+    changed = is_bit_set(bitmap, sector_num);
+    for (*num_same = 1; *num_same < nb_sectors; (*num_same)++) {
+       if (is_bit_set(bitmap, sector_num + *num_same) != changed)
+           break;
+    }
+
+    return changed;
+}
+
+static int cow_is_allocated(BlockDriverState *bs, int64_t sector_num, 
+                            int nb_sectors, int *pnum)
+{
+    BDRVCowState *s = bs->opaque;
+    return is_changed(s->cow_bitmap, sector_num, nb_sectors, pnum);
+}
+
+static int cow_read(BlockDriverState *bs, int64_t sector_num, 
+                    uint8_t *buf, int nb_sectors)
+{
+    BDRVCowState *s = bs->opaque;
+    int ret, n;
+    
+    while (nb_sectors > 0) {
+        if (is_changed(s->cow_bitmap, sector_num, nb_sectors, &n)) {
+            lseek(s->fd, s->cow_sectors_offset + sector_num * 512, SEEK_SET);
+            ret = read(s->fd, buf, n * 512);
+            if (ret != n * 512) 
+                return -1;
+        } else {
+            memset(buf, 0, n * 512);
+        }
+        nb_sectors -= n;
+        sector_num += n;
+        buf += n * 512;
+    }
+    return 0;
+}
+
+static int cow_write(BlockDriverState *bs, int64_t sector_num, 
+                     const uint8_t *buf, int nb_sectors)
+{
+    BDRVCowState *s = bs->opaque;
+    int ret, i;
+    
+    lseek(s->fd, s->cow_sectors_offset + sector_num * 512, SEEK_SET);
+    ret = write(s->fd, buf, nb_sectors * 512);
+    if (ret != nb_sectors * 512) 
+        return -1;
+    for (i = 0; i < nb_sectors; i++)
+        set_bit(s->cow_bitmap, sector_num + i);
+    return 0;
+}
+
+static void cow_close(BlockDriverState *bs)
+{
+    BDRVCowState *s = bs->opaque;
+    munmap(s->cow_bitmap_addr, s->cow_bitmap_size);
+    close(s->fd);
+}
+
+static int cow_create(const char *filename, int64_t image_sectors,
+                      const char *image_filename, int flags)
+{
+    int fd, cow_fd;
+    struct cow_header_v2 cow_header;
+    struct stat st;
+
+    if (flags)
+        return -ENOTSUP;
+
+    cow_fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE, 
+              0644);
+    if (cow_fd < 0)
+        return -1;
+    memset(&cow_header, 0, sizeof(cow_header));
+    cow_header.magic = cpu_to_be32(COW_MAGIC);
+    cow_header.version = cpu_to_be32(COW_VERSION);
+    if (image_filename) {
+        fd = open(image_filename, O_RDONLY | O_BINARY);
+        if (fd < 0) {
+            close(cow_fd);
+            return -1;
+        }
+        if (fstat(fd, &st) != 0) {
+            close(fd);
+            return -1;
+        }
+        close(fd);
+        cow_header.mtime = cpu_to_be32(st.st_mtime);
+        realpath(image_filename, cow_header.backing_file);
+    }
+    cow_header.sectorsize = cpu_to_be32(512);
+    cow_header.size = cpu_to_be64(image_sectors * 512);
+    write(cow_fd, &cow_header, sizeof(cow_header));
+    /* resize to include at least all the bitmap */
+    ftruncate(cow_fd, sizeof(cow_header) + ((image_sectors + 7) >> 3));
+    close(cow_fd);
+    return 0;
+}
+
+BlockDriver bdrv_cow = {
+    "cow",
+    sizeof(BDRVCowState),
+    cow_probe,
+    cow_open,
+    cow_read,
+    cow_write,
+    cow_close,
+    cow_create,
+    cow_is_allocated,
+};
+#endif
diff --git a/tools/ioemu/block-qcow.c b/tools/ioemu/block-qcow.c
new file mode 100644 (file)
index 0000000..a473298
--- /dev/null
@@ -0,0 +1,677 @@
+/*
+ * Block driver for the QCOW format
+ * 
+ * Copyright (c) 2004 Fabrice Bellard
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+#include "block_int.h"
+#include <zlib.h>
+#include "aes.h"
+
+/**************************************************************/
+/* QEMU COW block driver with compression and encryption support */
+
+#define QCOW_MAGIC (('Q' << 24) | ('F' << 16) | ('I' << 8) | 0xfb)
+#define QCOW_VERSION 1
+
+#define QCOW_CRYPT_NONE 0
+#define QCOW_CRYPT_AES  1
+
+#define QCOW_OFLAG_COMPRESSED (1LL << 63)
+
+typedef struct QCowHeader {
+    uint32_t magic;
+    uint32_t version;
+    uint64_t backing_file_offset;
+    uint32_t backing_file_size;
+    uint32_t mtime;
+    uint64_t size; /* in bytes */
+    uint8_t cluster_bits;
+    uint8_t l2_bits;
+    uint32_t crypt_method;
+    uint64_t l1_table_offset;
+} QCowHeader;
+
+#define L2_CACHE_SIZE 16
+
+typedef struct BDRVQcowState {
+    int fd;
+    int cluster_bits;
+    int cluster_size;
+    int cluster_sectors;
+    int l2_bits;
+    int l2_size;
+    int l1_size;
+    uint64_t cluster_offset_mask;
+    uint64_t l1_table_offset;
+    uint64_t *l1_table;
+    uint64_t *l2_cache;
+    uint64_t l2_cache_offsets[L2_CACHE_SIZE];
+    uint32_t l2_cache_counts[L2_CACHE_SIZE];
+    uint8_t *cluster_cache;
+    uint8_t *cluster_data;
+    uint64_t cluster_cache_offset;
+    uint32_t crypt_method; /* current crypt method, 0 if no key yet */
+    uint32_t crypt_method_header;
+    AES_KEY aes_encrypt_key;
+    AES_KEY aes_decrypt_key;
+} BDRVQcowState;
+
+static int decompress_cluster(BDRVQcowState *s, uint64_t cluster_offset);
+
+static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename)
+{
+    const QCowHeader *cow_header = (const void *)buf;
+
+    if (be32_to_cpu(cow_header->magic) == QCOW_MAGIC &&
+        be32_to_cpu(cow_header->version) == QCOW_VERSION) 
+        return 100;
+    else
+        return 0;
+}
+
+static int qcow_open(BlockDriverState *bs, const char *filename)
+{
+    BDRVQcowState *s = bs->opaque;
+    int fd, len, i, shift;
+    QCowHeader header;
+    
+    fd = open(filename, O_RDWR | O_BINARY | O_LARGEFILE);
+    if (fd < 0) {
+        fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE);
+        if (fd < 0)
+            return -1;
+    }
+    s->fd = fd;
+    if (read(fd, &header, sizeof(header)) != sizeof(header))
+        goto fail;
+    be32_to_cpus(&header.magic);
+    be32_to_cpus(&header.version);
+    be64_to_cpus(&header.backing_file_offset);
+    be32_to_cpus(&header.backing_file_size);
+    be32_to_cpus(&header.mtime);
+    be64_to_cpus(&header.size);
+    be32_to_cpus(&header.crypt_method);
+    be64_to_cpus(&header.l1_table_offset);
+    
+    if (header.magic != QCOW_MAGIC || header.version != QCOW_VERSION)
+        goto fail;
+    if (header.size <= 1 || header.cluster_bits < 9)
+        goto fail;
+    if (header.crypt_method > QCOW_CRYPT_AES)
+        goto fail;
+    s->crypt_method_header = header.crypt_method;
+    if (s->crypt_method_header)
+        bs->encrypted = 1;
+    s->cluster_bits = header.cluster_bits;
+    s->cluster_size = 1 << s->cluster_bits;
+    s->cluster_sectors = 1 << (s->cluster_bits - 9);
+    s->l2_bits = header.l2_bits;
+    s->l2_size = 1 << s->l2_bits;
+    bs->total_sectors = header.size / 512;
+    s->cluster_offset_mask = (1LL << (63 - s->cluster_bits)) - 1;
+
+    /* read the level 1 table */
+    shift = s->cluster_bits + s->l2_bits;
+    s->l1_size = (header.size + (1LL << shift) - 1) >> shift;
+
+    s->l1_table_offset = header.l1_table_offset;
+    s->l1_table = qemu_malloc(s->l1_size * sizeof(uint64_t));
+    if (!s->l1_table)
+        goto fail;
+    lseek(fd, s->l1_table_offset, SEEK_SET);
+    if (read(fd, s->l1_table, s->l1_size * sizeof(uint64_t)) != 
+        s->l1_size * sizeof(uint64_t))
+        goto fail;
+    for(i = 0;i < s->l1_size; i++) {
+        be64_to_cpus(&s->l1_table[i]);
+    }
+    /* alloc L2 cache */
+    s->l2_cache = qemu_malloc(s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t));
+    if (!s->l2_cache)
+        goto fail;
+    s->cluster_cache = qemu_malloc(s->cluster_size);
+    if (!s->cluster_cache)
+        goto fail;
+    s->cluster_data = qemu_malloc(s->cluster_size);
+    if (!s->cluster_data)
+        goto fail;
+    s->cluster_cache_offset = -1;
+    
+    /* read the backing file name */
+    if (header.backing_file_offset != 0) {
+        len = header.backing_file_size;
+        if (len > 1023)
+            len = 1023;
+        lseek(fd, header.backing_file_offset, SEEK_SET);
+        if (read(fd, bs->backing_file, len) != len)
+            goto fail;
+        bs->backing_file[len] = '\0';
+    }
+    return 0;
+
+ fail:
+    qemu_free(s->l1_table);
+    qemu_free(s->l2_cache);
+    qemu_free(s->cluster_cache);
+    qemu_free(s->cluster_data);
+    close(fd);
+    return -1;
+}
+
+static int qcow_set_key(BlockDriverState *bs, const char *key)
+{
+    BDRVQcowState *s = bs->opaque;
+    uint8_t keybuf[16];
+    int len, i;
+    
+    memset(keybuf, 0, 16);
+    len = strlen(key);
+    if (len > 16)
+        len = 16;
+    /* XXX: we could compress the chars to 7 bits to increase
+       entropy */
+    for(i = 0;i < len;i++) {
+        keybuf[i] = key[i];
+    }
+    s->crypt_method = s->crypt_method_header;
+
+    if (AES_set_encrypt_key(keybuf, 128, &s->aes_encrypt_key) != 0)
+        return -1;
+    if (AES_set_decrypt_key(keybuf, 128, &s->aes_decrypt_key) != 0)
+        return -1;
+#if 0
+    /* test */
+    {
+        uint8_t in[16];
+        uint8_t out[16];
+        uint8_t tmp[16];
+        for(i=0;i<16;i++)
+            in[i] = i;
+        AES_encrypt(in, tmp, &s->aes_encrypt_key);
+        AES_decrypt(tmp, out, &s->aes_decrypt_key);
+        for(i = 0; i < 16; i++)
+            printf(" %02x", tmp[i]);
+        printf("\n");
+        for(i = 0; i < 16; i++)
+            printf(" %02x", out[i]);
+        printf("\n");
+    }
+#endif
+    return 0;
+}
+
+/* The crypt function is compatible with the linux cryptoloop
+   algorithm for < 4 GB images. NOTE: out_buf == in_buf is
+   supported */
+static void encrypt_sectors(BDRVQcowState *s, int64_t sector_num,
+                            uint8_t *out_buf, const uint8_t *in_buf,
+                            int nb_sectors, int enc,
+                            const AES_KEY *key)
+{
+    union {
+        uint64_t ll[2];
+        uint8_t b[16];
+    } ivec;
+    int i;
+
+    for(i = 0; i < nb_sectors; i++) {
+        ivec.ll[0] = cpu_to_le64(sector_num);
+        ivec.ll[1] = 0;
+        AES_cbc_encrypt(in_buf, out_buf, 512, key, 
+                        ivec.b, enc);
+        sector_num++;
+        in_buf += 512;
+        out_buf += 512;
+    }
+}
+
+/* 'allocate' is:
+ *
+ * 0 to not allocate.
+ *
+ * 1 to allocate a normal cluster (for sector indexes 'n_start' to
+ * 'n_end')
+ *
+ * 2 to allocate a compressed cluster of size
+ * 'compressed_size'. 'compressed_size' must be > 0 and <
+ * cluster_size 
+ *
+ * return 0 if not allocated.
+ */
+static uint64_t get_cluster_offset(BlockDriverState *bs,
+                                   uint64_t offset, int allocate,
+                                   int compressed_size,
+                                   int n_start, int n_end)
+{
+    BDRVQcowState *s = bs->opaque;
+    int min_index, i, j, l1_index, l2_index;
+    uint64_t l2_offset, *l2_table, cluster_offset, tmp;
+    uint32_t min_count;
+    int new_l2_table;
+    
+    l1_index = offset >> (s->l2_bits + s->cluster_bits);
+    l2_offset = s->l1_table[l1_index];
+    new_l2_table = 0;
+    if (!l2_offset) {
+        if (!allocate)
+            return 0;
+        /* allocate a new l2 entry */
+        l2_offset = lseek(s->fd, 0, SEEK_END);
+        /* round to cluster size */
+        l2_offset = (l2_offset + s->cluster_size - 1) & ~(s->cluster_size - 1);
+        /* update the L1 entry */
+        s->l1_table[l1_index] = l2_offset;
+        tmp = cpu_to_be64(l2_offset);
+        lseek(s->fd, s->l1_table_offset + l1_index * sizeof(tmp), SEEK_SET);
+        if (write(s->fd, &tmp, sizeof(tmp)) != sizeof(tmp))
+            return 0;
+        new_l2_table = 1;
+    }
+    for(i = 0; i < L2_CACHE_SIZE; i++) {
+        if (l2_offset == s->l2_cache_offsets[i]) {
+            /* increment the hit count */
+            if (++s->l2_cache_counts[i] == 0xffffffff) {
+                for(j = 0; j < L2_CACHE_SIZE; j++) {
+                    s->l2_cache_counts[j] >>= 1;
+                }
+            }
+            l2_table = s->l2_cache + (i << s->l2_bits);
+            goto found;
+        }
+    }
+    /* not found: load a new entry in the least used one */
+    min_index = 0;
+    min_count = 0xffffffff;
+    for(i = 0; i < L2_CACHE_SIZE; i++) {
+        if (s->l2_cache_counts[i] < min_count) {
+            min_count = s->l2_cache_counts[i];
+            min_index = i;
+        }
+    }
+    l2_table = s->l2_cache + (min_index << s->l2_bits);
+    lseek(s->fd, l2_offset, SEEK_SET);
+    if (new_l2_table) {
+        memset(l2_table, 0, s->l2_size * sizeof(uint64_t));
+        if (write(s->fd, l2_table, s->l2_size * sizeof(uint64_t)) !=
+            s->l2_size * sizeof(uint64_t))
+            return 0;
+    } else {
+        if (read(s->fd, l2_table, s->l2_size * sizeof(uint64_t)) != 
+            s->l2_size * sizeof(uint64_t))
+            return 0;
+    }
+    s->l2_cache_offsets[min_index] = l2_offset;
+    s->l2_cache_counts[min_index] = 1;
+ found:
+    l2_index = (offset >> s->cluster_bits) & (s->l2_size - 1);
+    cluster_offset = be64_to_cpu(l2_table[l2_index]);
+    if (!cluster_offset || 
+        ((cluster_offset & QCOW_OFLAG_COMPRESSED) && allocate == 1)) {
+        if (!allocate)
+            return 0;
+        /* allocate a new cluster */
+        if ((cluster_offset & QCOW_OFLAG_COMPRESSED) &&
+            (n_end - n_start) < s->cluster_sectors) {
+            /* if the cluster is already compressed, we must
+               decompress it in the case it is not completely
+               overwritten */
+            if (decompress_cluster(s, cluster_offset) < 0)
+                return 0;
+            cluster_offset = lseek(s->fd, 0, SEEK_END);
+            cluster_offset = (cluster_offset + s->cluster_size - 1) & 
+                ~(s->cluster_size - 1);
+            /* write the cluster content */
+            lseek(s->fd, cluster_offset, SEEK_SET);
+            if (write(s->fd, s->cluster_cache, s->cluster_size) != 
+                s->cluster_size)
+                return -1;
+        } else {
+            cluster_offset = lseek(s->fd, 0, SEEK_END);
+            if (allocate == 1) {
+                /* round to cluster size */
+                cluster_offset = (cluster_offset + s->cluster_size - 1) & 
+                    ~(s->cluster_size - 1);
+                ftruncate(s->fd, cluster_offset + s->cluster_size);
+                /* if encrypted, we must initialize the cluster
+                   content which won't be written */
+                if (s->crypt_method && 
+                    (n_end - n_start) < s->cluster_sectors) {
+                    uint64_t start_sect;
+                    start_sect = (offset & ~(s->cluster_size - 1)) >> 9;
+                    memset(s->cluster_data + 512, 0xaa, 512);
+                    for(i = 0; i < s->cluster_sectors; i++) {
+                        if (i < n_start || i >= n_end) {
+                            encrypt_sectors(s, start_sect + i, 
+                                            s->cluster_data, 
+                                            s->cluster_data + 512, 1, 1,
+                                            &s->aes_encrypt_key);
+                            lseek(s->fd, cluster_offset + i * 512, SEEK_SET);
+                            if (write(s->fd, s->cluster_data, 512) != 512)
+                                return -1;
+                        }
+                    }
+                }
+            } else {
+                cluster_offset |= QCOW_OFLAG_COMPRESSED | 
+                    (uint64_t)compressed_size << (63 - s->cluster_bits);
+            }
+        }
+        /* update L2 table */
+        tmp = cpu_to_be64(cluster_offset);
+        l2_table[l2_index] = tmp;
+        lseek(s->fd, l2_offset + l2_index * sizeof(tmp), SEEK_SET);
+        if (write(s->fd, &tmp, sizeof(tmp)) != sizeof(tmp))
+            return 0;
+    }
+    return cluster_offset;
+}
+
+static int qcow_is_allocated(BlockDriverState *bs, int64_t sector_num, 
+                             int nb_sectors, int *pnum)
+{
+    BDRVQcowState *s = bs->opaque;
+    int index_in_cluster, n;
+    uint64_t cluster_offset;
+
+    cluster_offset = get_cluster_offset(bs, sector_num << 9, 0, 0, 0, 0);
+    index_in_cluster = sector_num & (s->cluster_sectors - 1);
+    n = s->cluster_sectors - index_in_cluster;
+    if (n > nb_sectors)
+        n = nb_sectors;
+    *pnum = n;
+    return (cluster_offset != 0);
+}
+
+static int decompress_buffer(uint8_t *out_buf, int out_buf_size,
+                             const uint8_t *buf, int buf_size)
+{
+    z_stream strm1, *strm = &strm1;
+    int ret, out_len;
+
+    memset(strm, 0, sizeof(*strm));
+
+    strm->next_in = (uint8_t *)buf;
+    strm->avail_in = buf_size;
+    strm->next_out = out_buf;
+    strm->avail_out = out_buf_size;
+
+    ret = inflateInit2(strm, -12);
+    if (ret != Z_OK)
+        return -1;
+    ret = inflate(strm, Z_FINISH);
+    out_len = strm->next_out - out_buf;
+    if ((ret != Z_STREAM_END && ret != Z_BUF_ERROR) ||
+        out_len != out_buf_size) {
+        inflateEnd(strm);
+        return -1;
+    }
+    inflateEnd(strm);
+    return 0;
+}
+                              
+static int decompress_cluster(BDRVQcowState *s, uint64_t cluster_offset)
+{
+    int ret, csize;
+    uint64_t coffset;
+
+    coffset = cluster_offset & s->cluster_offset_mask;
+    if (s->cluster_cache_offset != coffset) {
+        csize = cluster_offset >> (63 - s->cluster_bits);
+        csize &= (s->cluster_size - 1);
+        lseek(s->fd, coffset, SEEK_SET);
+        ret = read(s->fd, s->cluster_data, csize);
+        if (ret != csize) 
+            return -1;
+        if (decompress_buffer(s->cluster_cache, s->cluster_size,
+                              s->cluster_data, csize) < 0) {
+            return -1;
+        }
+        s->cluster_cache_offset = coffset;
+    }
+    return 0;
+}
+
+static int qcow_read(BlockDriverState *bs, int64_t sector_num, 
+                     uint8_t *buf, int nb_sectors)
+{
+    BDRVQcowState *s = bs->opaque;
+    int ret, index_in_cluster, n;
+    uint64_t cluster_offset;
+    
+    while (nb_sectors > 0) {
+        cluster_offset = get_cluster_offset(bs, sector_num << 9, 0, 0, 0, 0);
+        index_in_cluster = sector_num & (s->cluster_sectors - 1);
+        n = s->cluster_sectors - index_in_cluster;
+        if (n > nb_sectors)
+            n = nb_sectors;
+        if (!cluster_offset) {
+            memset(buf, 0, 512 * n);
+        } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
+            if (decompress_cluster(s, cluster_offset) < 0)
+                return -1;
+            memcpy(buf, s->cluster_cache + index_in_cluster * 512, 512 * n);
+        } else {
+            lseek(s->fd, cluster_offset + index_in_cluster * 512, SEEK_SET);
+            ret = read(s->fd, buf, n * 512);
+            if (ret != n * 512) 
+                return -1;
+            if (s->crypt_method) {
+                encrypt_sectors(s, sector_num, buf, buf, n, 0, 
+                                &s->aes_decrypt_key);
+            }
+        }
+        nb_sectors -= n;
+        sector_num += n;
+        buf += n * 512;
+    }
+    return 0;
+}
+
+static int qcow_write(BlockDriverState *bs, int64_t sector_num, 
+                     const uint8_t *buf, int nb_sectors)
+{
+    BDRVQcowState *s = bs->opaque;
+    int ret, index_in_cluster, n;
+    uint64_t cluster_offset;
+    
+    while (nb_sectors > 0) {
+        index_in_cluster = sector_num & (s->cluster_sectors - 1);
+        n = s->cluster_sectors - index_in_cluster;
+        if (n > nb_sectors)
+            n = nb_sectors;
+        cluster_offset = get_cluster_offset(bs, sector_num << 9, 1, 0, 
+                                            index_in_cluster, 
+                                            index_in_cluster + n);
+        if (!cluster_offset)
+            return -1;
+        lseek(s->fd, cluster_offset + index_in_cluster * 512, SEEK_SET);
+        if (s->crypt_method) {
+            encrypt_sectors(s, sector_num, s->cluster_data, buf, n, 1,
+                            &s->aes_encrypt_key);
+            ret = write(s->fd, s->cluster_data, n * 512);
+        } else {
+            ret = write(s->fd, buf, n * 512);
+        }
+        if (ret != n * 512) 
+            return -1;
+        nb_sectors -= n;
+        sector_num += n;
+        buf += n * 512;
+    }
+    s->cluster_cache_offset = -1; /* disable compressed cache */
+    return 0;
+}
+
+static void qcow_close(BlockDriverState *bs)
+{
+    BDRVQcowState *s = bs->opaque;
+    qemu_free(s->l1_table);
+    qemu_free(s->l2_cache);
+    qemu_free(s->cluster_cache);
+    qemu_free(s->cluster_data);
+    close(s->fd);
+}
+
+static int qcow_create(const char *filename, int64_t total_size,
+                      const char *backing_file, int flags)
+{
+    int fd, header_size, backing_filename_len, l1_size, i, shift;
+    QCowHeader header;
+    char backing_filename[1024];
+    uint64_t tmp;
+    struct stat st;
+
+    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE, 
+              0644);
+    if (fd < 0)
+        return -1;
+    memset(&header, 0, sizeof(header));
+    header.magic = cpu_to_be32(QCOW_MAGIC);
+    header.version = cpu_to_be32(QCOW_VERSION);
+    header.size = cpu_to_be64(total_size * 512);
+    header_size = sizeof(header);
+    backing_filename_len = 0;
+    if (backing_file) {
+        realpath(backing_file, backing_filename);
+        if (stat(backing_filename, &st) != 0) {
+            return -1;
+        }
+        header.mtime = cpu_to_be32(st.st_mtime);
+        header.backing_file_offset = cpu_to_be64(header_size);
+        backing_filename_len = strlen(backing_filename);
+        header.backing_file_size = cpu_to_be32(backing_filename_len);
+        header_size += backing_filename_len;
+        header.cluster_bits = 9; /* 512 byte cluster to avoid copying
+                                    unmodifyed sectors */
+        header.l2_bits = 12; /* 32 KB L2 tables */
+    } else {
+        header.cluster_bits = 12; /* 4 KB clusters */
+        header.l2_bits = 9; /* 4 KB L2 tables */
+    }
+    header_size = (header_size + 7) & ~7;
+    shift = header.cluster_bits + header.l2_bits;
+    l1_size = ((total_size * 512) + (1LL << shift) - 1) >> shift;
+
+    header.l1_table_offset = cpu_to_be64(header_size);
+    if (flags) {
+        header.crypt_method = cpu_to_be32(QCOW_CRYPT_AES);
+    } else {
+        header.crypt_method = cpu_to_be32(QCOW_CRYPT_NONE);
+    }
+    
+    /* write all the data */
+    write(fd, &header, sizeof(header));
+    if (backing_file) {
+        write(fd, backing_filename, backing_filename_len);
+    }
+    lseek(fd, header_size, SEEK_SET);
+    tmp = 0;
+    for(i = 0;i < l1_size; i++) {
+        write(fd, &tmp, sizeof(tmp));
+    }
+    close(fd);
+    return 0;
+}
+
+int qcow_get_cluster_size(BlockDriverState *bs)
+{
+    BDRVQcowState *s = bs->opaque;
+    if (bs->drv != &bdrv_qcow)
+        return -1;
+    return s->cluster_size;
+}
+
+/* XXX: put compressed sectors first, then all the cluster aligned
+   tables to avoid losing bytes in alignment */
+int qcow_compress_cluster(BlockDriverState *bs, int64_t sector_num, 
+                          const uint8_t *buf)
+{
+    BDRVQcowState *s = bs->opaque;
+    z_stream strm;
+    int ret, out_len;
+    uint8_t *out_buf;
+    uint64_t cluster_offset;
+
+    if (bs->drv != &bdrv_qcow)
+        return -1;
+
+    out_buf = qemu_malloc(s->cluster_size + (s->cluster_size / 1000) + 128);
+    if (!out_buf)
+        return -1;
+
+    /* best compression, small window, no zlib header */
+    memset(&strm, 0, sizeof(strm));
+    ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION,
+                       Z_DEFLATED, -12, 
+                       9, Z_DEFAULT_STRATEGY);
+    if (ret != 0) {
+        qemu_free(out_buf);
+        return -1;
+    }
+
+    strm.avail_in = s->cluster_size;
+    strm.next_in = (uint8_t *)buf;
+    strm.avail_out = s->cluster_size;
+    strm.next_out = out_buf;
+
+    ret = deflate(&strm, Z_FINISH);
+    if (ret != Z_STREAM_END && ret != Z_OK) {
+        qemu_free(out_buf);
+        deflateEnd(&strm);
+        return -1;
+    }
+    out_len = strm.next_out - out_buf;
+
+    deflateEnd(&strm);
+
+    if (ret != Z_STREAM_END || out_len >= s->cluster_size) {
+        /* could not compress: write normal cluster */
+        qcow_write(bs, sector_num, buf, s->cluster_sectors);
+    } else {
+        cluster_offset = get_cluster_offset(bs, sector_num << 9, 2, 
+                                            out_len, 0, 0);
+        cluster_offset &= s->cluster_offset_mask;
+        lseek(s->fd, cluster_offset, SEEK_SET);
+        if (write(s->fd, out_buf, out_len) != out_len) {
+            qemu_free(out_buf);
+            return -1;
+        }
+    }
+    
+    qemu_free(out_buf);
+    return 0;
+}
+
+BlockDriver bdrv_qcow = {
+    "qcow",
+    sizeof(BDRVQcowState),
+    qcow_probe,
+    qcow_open,
+    qcow_read,
+    qcow_write,
+    qcow_close,
+    qcow_create,
+    qcow_is_allocated,
+    qcow_set_key,
+};
+
+
diff --git a/tools/ioemu/block-vmdk.c b/tools/ioemu/block-vmdk.c
new file mode 100644 (file)
index 0000000..1cc4988
--- /dev/null
@@ -0,0 +1,279 @@
+/*
+ * Block driver for the VMDK format
+ * 
+ * Copyright (c) 2004 Fabrice Bellard
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+#include "block_int.h"
+
+/* XXX: this code is untested */
+/* XXX: add write support */
+
+#define VMDK3_MAGIC (('C' << 24) | ('O' << 16) | ('W' << 8) | 'D')
+#define VMDK4_MAGIC (('K' << 24) | ('D' << 16) | ('M' << 8) | 'V')
+
+typedef struct {
+    uint32_t version;
+    uint32_t flags;
+    uint32_t disk_sectors;
+    uint32_t granularity;
+    uint32_t l1dir_offset;
+    uint32_t l1dir_size;
+    uint32_t file_sectors;
+    uint32_t cylinders;
+    uint32_t heads;
+    uint32_t sectors_per_track;
+} VMDK3Header;
+
+typedef struct {
+    uint32_t version;
+    uint32_t flags;
+    int64_t capacity;
+    int64_t granularity;
+    int64_t desc_offset;
+    int64_t desc_size;
+    int32_t num_gtes_per_gte;
+    int64_t rgd_offset;
+    int64_t gd_offset;
+    int64_t grain_offset;
+    char filler[1];
+    char check_bytes[4];
+} VMDK4Header;
+
+#define L2_CACHE_SIZE 16
+
+typedef struct BDRVVmdkState {
+    int fd;
+    int64_t l1_table_offset;
+    uint32_t *l1_table;
+    unsigned int l1_size;
+    uint32_t l1_entry_sectors;
+
+    unsigned int l2_size;
+    uint32_t *l2_cache;
+    uint32_t l2_cache_offsets[L2_CACHE_SIZE];
+    uint32_t l2_cache_counts[L2_CACHE_SIZE];
+
+    unsigned int cluster_sectors;
+} BDRVVmdkState;
+
+static int vmdk_probe(const uint8_t *buf, int buf_size, const char *filename)
+{
+    uint32_t magic;
+
+    if (buf_size < 4)
+        return 0;
+    magic = be32_to_cpu(*(uint32_t *)buf);
+    if (magic == VMDK3_MAGIC ||
+        magic == VMDK4_MAGIC)
+        return 100;
+    else
+        return 0;
+}
+
+static int vmdk_open(BlockDriverState *bs, const char *filename)
+{
+    BDRVVmdkState *s = bs->opaque;
+    int fd, i;
+    uint32_t magic;
+    int l1_size;
+
+    fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE);
+    if (fd < 0)
+        return -1;
+    if (read(fd, &magic, sizeof(magic)) != sizeof(magic))
+        goto fail;
+    magic = be32_to_cpu(magic);
+    if (magic == VMDK3_MAGIC) {
+        VMDK3Header header;
+        if (read(fd, &header, sizeof(header)) != 
+            sizeof(header))
+            goto fail;
+        s->cluster_sectors = le32_to_cpu(header.granularity);
+        s->l2_size = 1 << 9;
+        s->l1_size = 1 << 6;
+        bs->total_sectors = le32_to_cpu(header.disk_sectors);
+        s->l1_table_offset = le32_to_cpu(header.l1dir_offset) * 512;
+        s->l1_entry_sectors = s->l2_size * s->cluster_sectors;
+    } else if (magic == VMDK4_MAGIC) {
+        VMDK4Header header;
+        
+        if (read(fd, &header, sizeof(header)) != sizeof(header))
+            goto fail;
+        bs->total_sectors = le32_to_cpu(header.capacity);
+        s->cluster_sectors = le32_to_cpu(header.granularity);
+        s->l2_size = le32_to_cpu(header.num_gtes_per_gte);
+        s->l1_entry_sectors = s->l2_size * s->cluster_sectors;
+        if (s->l1_entry_sectors <= 0)
+            goto fail;
+        s->l1_size = (bs->total_sectors + s->l1_entry_sectors - 1) 
+            / s->l1_entry_sectors;
+        s->l1_table_offset = le64_to_cpu(header.rgd_offset) * 512;
+    } else {
+        goto fail;
+    }
+    /* read the L1 table */
+    l1_size = s->l1_size * sizeof(uint32_t);
+    s->l1_table = qemu_malloc(l1_size);
+    if (!s->l1_table)
+        goto fail;
+    if (lseek(fd, s->l1_table_offset, SEEK_SET) == -1)
+        goto fail;
+    if (read(fd, s->l1_table, l1_size) != l1_size)
+        goto fail;
+    for(i = 0; i < s->l1_size; i++) {
+        le32_to_cpus(&s->l1_table[i]);
+    }
+
+    s->l2_cache = qemu_malloc(s->l2_size * L2_CACHE_SIZE * sizeof(uint32_t));
+    if (!s->l2_cache)
+        goto fail;
+    s->fd = fd;
+    /* XXX: currently only read only */
+    bs->read_only = 1;
+    return 0;
+ fail:
+    qemu_free(s->l1_table);
+    qemu_free(s->l2_cache);
+    close(fd);
+    return -1;
+}
+
+static uint64_t get_cluster_offset(BlockDriverState *bs,
+                                   uint64_t offset)
+{
+    BDRVVmdkState *s = bs->opaque;
+    unsigned int l1_index, l2_offset, l2_index;
+    int min_index, i, j;
+    uint32_t min_count, *l2_table;
+    uint64_t cluster_offset;
+    
+    l1_index = (offset >> 9) / s->l1_entry_sectors;
+    if (l1_index >= s->l1_size)
+        return 0;
+    l2_offset = s->l1_table[l1_index];
+    if (!l2_offset)
+        return 0;
+    
+    for(i = 0; i < L2_CACHE_SIZE; i++) {
+        if (l2_offset == s->l2_cache_offsets[i]) {
+            /* increment the hit count */
+            if (++s->l2_cache_counts[i] == 0xffffffff) {
+                for(j = 0; j < L2_CACHE_SIZE; j++) {
+                    s->l2_cache_counts[j] >>= 1;
+                }
+            }
+            l2_table = s->l2_cache + (i * s->l2_size);
+            goto found;
+        }
+    }
+    /* not found: load a new entry in the least used one */
+    min_index = 0;
+    min_count = 0xffffffff;
+    for(i = 0; i < L2_CACHE_SIZE; i++) {
+        if (s->l2_cache_counts[i] < min_count) {
+            min_count = s->l2_cache_counts[i];
+            min_index = i;
+        }
+    }
+    l2_table = s->l2_cache + (min_index * s->l2_size);
+    lseek(s->fd, (int64_t)l2_offset * 512, SEEK_SET);
+    if (read(s->fd, l2_table, s->l2_size * sizeof(uint32_t)) != 
+        s->l2_size * sizeof(uint32_t))
+        return 0;
+    s->l2_cache_offsets[min_index] = l2_offset;
+    s->l2_cache_counts[min_index] = 1;
+ found:
+    l2_index = ((offset >> 9) / s->cluster_sectors) % s->l2_size;
+    cluster_offset = le32_to_cpu(l2_table[l2_index]);
+    cluster_offset <<= 9;
+    return cluster_offset;
+}
+
+static int vmdk_is_allocated(BlockDriverState *bs, int64_t sector_num, 
+                             int nb_sectors, int *pnum)
+{
+    BDRVVmdkState *s = bs->opaque;
+    int index_in_cluster, n;
+    uint64_t cluster_offset;
+
+    cluster_offset = get_cluster_offset(bs, sector_num << 9);
+    index_in_cluster = sector_num % s->cluster_sectors;
+    n = s->cluster_sectors - index_in_cluster;
+    if (n > nb_sectors)
+        n = nb_sectors;
+    *pnum = n;
+    return (cluster_offset != 0);
+}
+
+static int vmdk_read(BlockDriverState *bs, int64_t sector_num, 
+                    uint8_t *buf, int nb_sectors)
+{
+    BDRVVmdkState *s = bs->opaque;
+    int ret, index_in_cluster, n;
+    uint64_t cluster_offset;
+    
+    while (nb_sectors > 0) {
+        cluster_offset = get_cluster_offset(bs, sector_num << 9);
+        index_in_cluster = sector_num % s->cluster_sectors;
+        n = s->cluster_sectors - index_in_cluster;
+        if (n > nb_sectors)
+            n = nb_sectors;
+        if (!cluster_offset) {
+            memset(buf, 0, 512 * n);
+        } else {
+            lseek(s->fd, cluster_offset + index_in_cluster * 512, SEEK_SET);
+            ret = read(s->fd, buf, n * 512);
+            if (ret != n * 512) 
+                return -1;
+        }
+        nb_sectors -= n;
+        sector_num += n;
+        buf += n * 512;
+    }
+    return 0;
+}
+
+static int vmdk_write(BlockDriverState *bs, int64_t sector_num, 
+                     const uint8_t *buf, int nb_sectors)
+{
+    return -1;
+}
+
+static void vmdk_close(BlockDriverState *bs)
+{
+    BDRVVmdkState *s = bs->opaque;
+    qemu_free(s->l1_table);
+    qemu_free(s->l2_cache);
+    close(s->fd);
+}
+
+BlockDriver bdrv_vmdk = {
+    "vmdk",
+    sizeof(BDRVVmdkState),
+    vmdk_probe,
+    vmdk_open,
+    vmdk_read,
+    vmdk_write,
+    vmdk_close,
+    NULL, /* no create yet */
+    vmdk_is_allocated,
+};
diff --git a/tools/ioemu/block.c b/tools/ioemu/block.c
new file mode 100644 (file)
index 0000000..cff0d2a
--- /dev/null
@@ -0,0 +1,548 @@
+/*
+ * QEMU System Emulator block driver
+ * 
+ * Copyright (c) 2003 Fabrice Bellard
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+#include "block_int.h"
+
+static BlockDriverState *bdrv_first;
+static BlockDriver *first_drv;
+
+void bdrv_register(BlockDriver *bdrv)
+{
+    bdrv->next = first_drv;
+    first_drv = bdrv;
+}
+
+/* create a new block device (by default it is empty) */
+BlockDriverState *bdrv_new(const char *device_name)
+{
+    BlockDriverState **pbs, *bs;
+
+    bs = qemu_mallocz(sizeof(BlockDriverState));
+    if(!bs)
+        return NULL;
+    pstrcpy(bs->device_name, sizeof(bs->device_name), device_name);
+    if (device_name[0] != '\0') {
+        /* insert at the end */
+        pbs = &bdrv_first;
+        while (*pbs != NULL)
+            pbs = &(*pbs)->next;
+        *pbs = bs;
+    }
+    return bs;
+}
+
+BlockDriver *bdrv_find_format(const char *format_name)
+{
+    BlockDriver *drv1;
+    for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
+        if (!strcmp(drv1->format_name, format_name))
+            return drv1;
+    }
+    return NULL;
+}
+
+int bdrv_create(BlockDriver *drv, 
+                const char *filename, int64_t size_in_sectors,
+                const char *backing_file, int flags)
+{
+    if (!drv->bdrv_create)
+        return -ENOTSUP;
+    return drv->bdrv_create(filename, size_in_sectors, backing_file, flags);
+}
+
+static BlockDriver *find_image_format(const char *filename)
+{
+    int fd, ret, score, score_max;
+    BlockDriver *drv1, *drv;
+    uint8_t buf[1024];
+
+    fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE);
+    if (fd < 0)
+        return NULL;
+    ret = read(fd, buf, sizeof(buf));
+    if (ret < 0) {
+        close(fd);
+        return NULL;
+    }
+    close(fd);
+    
+    drv = NULL;
+    score_max = 0;
+    for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
+        score = drv1->bdrv_probe(buf, ret, filename);
+        if (score > score_max) {
+            score_max = score;
+            drv = drv1;
+        }
+    }
+    return drv;
+}
+
+int bdrv_open(BlockDriverState *bs, const char *filename, int snapshot)
+{
+    return bdrv_open2(bs, filename, snapshot, NULL);
+}
+
+int bdrv_open2(BlockDriverState *bs, const char *filename, int snapshot,
+               BlockDriver *drv)
+{
+    int ret;
+    
+    bs->read_only = 0;
+    bs->is_temporary = 0;
+    bs->encrypted = 0;
+    
+    pstrcpy(bs->filename, sizeof(bs->filename), filename);
+    if (!drv) {
+        drv = find_image_format(filename);
+        if (!drv)
+            return -1;
+    }
+    bs->drv = drv;
+    bs->opaque = qemu_mallocz(drv->instance_size);
+    if (bs->opaque == NULL && drv->instance_size > 0)
+        return -1;
+    
+    ret = drv->bdrv_open(bs, filename);
+    if (ret < 0) {
+        qemu_free(bs->opaque);
+        return -1;
+    }
+#ifndef _WIN32
+    if (bs->is_temporary) {
+        unlink(filename);
+    }
+#endif
+    if (bs->backing_file[0] != '\0' && drv->bdrv_is_allocated) {
+        /* if there is a backing file, use it */
+        bs->backing_hd = bdrv_new("");
+        if (!bs->backing_hd) {
+        fail:
+            bdrv_close(bs);
+            return -1;
+        }
+        if (bdrv_open(bs->backing_hd, bs->backing_file, 0) < 0)
+            goto fail;
+    }
+
+    bs->inserted = 1;
+
+    /* call the change callback */
+    if (bs->change_cb)
+        bs->change_cb(bs->change_opaque);
+
+    return 0;
+}
+
+void bdrv_close(BlockDriverState *bs)
+{
+    if (bs->inserted) {
+        if (bs->backing_hd)
+            bdrv_delete(bs->backing_hd);
+        bs->drv->bdrv_close(bs);
+        qemu_free(bs->opaque);
+#ifdef _WIN32
+        if (bs->is_temporary) {
+            unlink(bs->filename);
+        }
+#endif
+        bs->opaque = NULL;
+        bs->drv = NULL;
+        bs->inserted = 0;
+
+        /* call the change callback */
+        if (bs->change_cb)
+            bs->change_cb(bs->change_opaque);
+    }
+}
+
+void bdrv_delete(BlockDriverState *bs)
+{
+    /* XXX: remove the driver list */
+    bdrv_close(bs);
+    qemu_free(bs);
+}
+
+/* commit COW file into the raw image */
+int bdrv_commit(BlockDriverState *bs)
+{
+    int64_t i;
+    int n, j;
+    unsigned char sector[512];
+
+    if (!bs->inserted)
+        return -ENOENT;
+
+    if (bs->read_only) {
+       return -EACCES;
+    }
+
+    if (!bs->backing_hd) {
+       return -ENOTSUP;
+    }
+
+    for (i = 0; i < bs->total_sectors;) {
+        if (bs->drv->bdrv_is_allocated(bs, i, 65536, &n)) {
+            for(j = 0; j < n; j++) {
+                if (bdrv_read(bs, i, sector, 1) != 0) {
+                    return -EIO;
+                }
+
+                if (bdrv_write(bs->backing_hd, i, sector, 1) != 0) {
+                    return -EIO;
+                }
+                i++;
+           }
+       } else {
+            i += n;
+        }
+    }
+    return 0;
+}
+
+/* return -1 if error */
+int bdrv_read(BlockDriverState *bs, int64_t sector_num, 
+              uint8_t *buf, int nb_sectors)
+{
+    int ret, n;
+    BlockDriver *drv = bs->drv;
+
+    if (!bs->inserted)
+        return -1;
+
+    while (nb_sectors > 0) {
+        if (sector_num == 0 && bs->boot_sector_enabled) {
+            memcpy(buf, bs->boot_sector_data, 512);
+            n = 1;
+        } else if (bs->backing_hd) {
+            if (drv->bdrv_is_allocated(bs, sector_num, nb_sectors, &n)) {
+                ret = drv->bdrv_read(bs, sector_num, buf, n);
+                if (ret < 0)
+                    return -1;
+            } else {
+                /* read from the base image */
+                ret = bdrv_read(bs->backing_hd, sector_num, buf, n);
+                if (ret < 0)
+                    return -1;
+            }
+        } else {
+            ret = drv->bdrv_read(bs, sector_num, buf, nb_sectors);
+            if (ret < 0)
+                return -1;
+            /* no need to loop */
+            break;
+        }
+        nb_sectors -= n;
+        sector_num += n;
+        buf += n * 512;
+    }
+    return 0;
+}
+
+/* return -1 if error */
+int bdrv_write(BlockDriverState *bs, int64_t sector_num, 
+               const uint8_t *buf, int nb_sectors)
+{
+    if (!bs->inserted)
+        return -1;
+    if (bs->read_only)
+        return -1;
+    return bs->drv->bdrv_write(bs, sector_num, buf, nb_sectors);
+}
+
+void bdrv_get_geometry(BlockDriverState *bs, int64_t *nb_sectors_ptr)
+{
+    *nb_sectors_ptr = bs->total_sectors;
+}
+
+/* force a given boot sector. */
+void bdrv_set_boot_sector(BlockDriverState *bs, const uint8_t *data, int size)
+{
+    bs->boot_sector_enabled = 1;
+    if (size > 512)
+        size = 512;
+    memcpy(bs->boot_sector_data, data, size);
+    memset(bs->boot_sector_data + size, 0, 512 - size);
+}
+
+void bdrv_set_geometry_hint(BlockDriverState *bs, 
+                            int cyls, int heads, int secs)
+{
+    bs->cyls = cyls;
+    bs->heads = heads;
+    bs->secs = secs;
+}
+
+void bdrv_set_type_hint(BlockDriverState *bs, int type)
+{
+    bs->type = type;
+    bs->removable = ((type == BDRV_TYPE_CDROM ||
+                      type == BDRV_TYPE_FLOPPY));
+}
+
+void bdrv_get_geometry_hint(BlockDriverState *bs, 
+                            int *pcyls, int *pheads, int *psecs)
+{
+    *pcyls = bs->cyls;
+    *pheads = bs->heads;
+    *psecs = bs->secs;
+}
+
+int bdrv_get_type_hint(BlockDriverState *bs)
+{
+    return bs->type;
+}
+
+int bdrv_is_removable(BlockDriverState *bs)
+{
+    return bs->removable;
+}
+
+int bdrv_is_read_only(BlockDriverState *bs)
+{
+    return bs->read_only;
+}
+
+int bdrv_is_inserted(BlockDriverState *bs)
+{
+    return bs->inserted;
+}
+
+int bdrv_is_locked(BlockDriverState *bs)
+{
+    return bs->locked;
+}
+
+void bdrv_set_locked(BlockDriverState *bs, int locked)
+{
+    bs->locked = locked;
+}
+
+void bdrv_set_change_cb(BlockDriverState *bs, 
+                        void (*change_cb)(void *opaque), void *opaque)
+{
+    bs->change_cb = change_cb;
+    bs->change_opaque = opaque;
+}
+
+int bdrv_is_encrypted(BlockDriverState *bs)
+{
+    if (bs->backing_hd && bs->backing_hd->encrypted)
+        return 1;
+    return bs->encrypted;
+}
+
+int bdrv_set_key(BlockDriverState *bs, const char *key)
+{
+    int ret;
+    if (bs->backing_hd && bs->backing_hd->encrypted) {
+        ret = bdrv_set_key(bs->backing_hd, key);
+        if (ret < 0)
+            return ret;
+        if (!bs->encrypted)
+            return 0;
+    }
+    if (!bs->encrypted || !bs->drv || !bs->drv->bdrv_set_key)
+        return -1;
+    return bs->drv->bdrv_set_key(bs, key);
+}
+
+void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size)
+{
+    if (!bs->inserted || !bs->drv) {
+        buf[0] = '\0';
+    } else {
+        pstrcpy(buf, buf_size, bs->drv->format_name);
+    }
+}
+
+void bdrv_iterate_format(void (*it)(void *opaque, const char *name), 
+                         void *opaque)
+{
+    BlockDriver *drv;
+
+    for (drv = first_drv; drv != NULL; drv = drv->next) {
+        it(opaque, drv->format_name);
+    }
+}
+
+BlockDriverState *bdrv_find(const char *name)
+{
+    BlockDriverState *bs;
+
+    for (bs = bdrv_first; bs != NULL; bs = bs->next) {
+        if (!strcmp(name, bs->device_name))
+            return bs;
+    }
+    return NULL;
+}
+
+void bdrv_iterate(void (*it)(void *opaque, const char *name), void *opaque)
+{
+    BlockDriverState *bs;
+
+    for (bs = bdrv_first; bs != NULL; bs = bs->next) {
+        it(opaque, bs->device_name);
+    }
+}
+
+const char *bdrv_get_device_name(BlockDriverState *bs)
+{
+    return bs->device_name;
+}
+
+void bdrv_info(void)
+{
+    BlockDriverState *bs;
+
+    for (bs = bdrv_first; bs != NULL; bs = bs->next) {
+        term_printf("%s:", bs->device_name);
+        term_printf(" type=");
+        switch(bs->type) {
+        case BDRV_TYPE_HD:
+            term_printf("hd");
+            break;
+        case BDRV_TYPE_CDROM:
+            term_printf("cdrom");
+            break;
+        case BDRV_TYPE_FLOPPY:
+            term_printf("floppy");
+            break;
+        }
+        term_printf(" removable=%d", bs->removable);
+        if (bs->removable) {
+            term_printf(" locked=%d", bs->locked);
+        }
+        if (bs->inserted) {
+            term_printf(" file=%s", bs->filename);
+            if (bs->backing_file[0] != '\0')
+                term_printf(" backing_file=%s", bs->backing_file);
+            term_printf(" ro=%d", bs->read_only);
+            term_printf(" drv=%s", bs->drv->format_name);
+            if (bs->encrypted)
+                term_printf(" encrypted");
+        } else {
+            term_printf(" [not inserted]");
+        }
+        term_printf("\n");
+    }
+}
+
+
+/**************************************************************/
+/* RAW block driver */
+
+typedef struct BDRVRawState {
+    int fd;
+} BDRVRawState;
+
+static int raw_probe(const uint8_t *buf, int buf_size, const char *filename)
+{
+    return 1; /* maybe */
+}
+
+static int raw_open(BlockDriverState *bs, const char *filename)
+{
+    BDRVRawState *s = bs->opaque;
+    int fd;
+    int64_t size;
+
+    fd = open(filename, O_RDWR | O_BINARY | O_LARGEFILE);
+    if (fd < 0) {
+        fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE);
+        if (fd < 0)
+            return -1;
+        bs->read_only = 1;
+    }
+    size = lseek(fd, 0, SEEK_END);
+    bs->total_sectors = size / 512;
+    s->fd = fd;
+    return 0;
+}
+
+static int raw_read(BlockDriverState *bs, int64_t sector_num, 
+                    uint8_t *buf, int nb_sectors)
+{
+    BDRVRawState *s = bs->opaque;
+    int ret;
+    
+    lseek(s->fd, sector_num * 512, SEEK_SET);
+    ret = read(s->fd, buf, nb_sectors * 512);
+    if (ret != nb_sectors * 512) 
+        return -1;
+    return 0;
+}
+
+static int raw_write(BlockDriverState *bs, int64_t sector_num, 
+                     const uint8_t *buf, int nb_sectors)
+{
+    BDRVRawState *s = bs->opaque;
+    int ret;
+    
+    lseek(s->fd, sector_num * 512, SEEK_SET);
+    ret = write(s->fd, buf, nb_sectors * 512);
+    if (ret != nb_sectors * 512) 
+        return -1;
+    return 0;
+}
+
+static void raw_close(BlockDriverState *bs)
+{
+    BDRVRawState *s = bs->opaque;
+    close(s->fd);
+}
+
+static int raw_create(const char *filename, int64_t total_size,
+                      const char *backing_file, int flags)
+{
+    int fd;
+
+    if (flags || backing_file)
+        return -ENOTSUP;
+
+    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE, 
+              0644);
+    if (fd < 0)
+        return -EIO;
+    ftruncate(fd, total_size * 512);
+    close(fd);
+    return 0;
+}
+
+BlockDriver bdrv_raw = {
+    "raw",
+    sizeof(BDRVRawState),
+    raw_probe,
+    raw_open,
+    raw_read,
+    raw_write,
+    raw_close,
+    raw_create,
+};
+
+void bdrv_init(void)
+{
+    bdrv_register(&bdrv_raw);
+    bdrv_register(&bdrv_cloop);
+}
diff --git a/tools/ioemu/block_int.h b/tools/ioemu/block_int.h
new file mode 100644 (file)
index 0000000..9d047c4
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * QEMU System Emulator block driver
+ * 
+ * Copyright (c) 2003 Fabrice Bellard
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#ifndef BLOCK_INT_H
+#define BLOCK_INT_H
+
+struct BlockDriver {
+    const char *format_name;
+    int instance_size;
+    int (*bdrv_probe)(const uint8_t *buf, int buf_size, const char *filename);
+    int (*bdrv_open)(BlockDriverState *bs, const char *filename);
+    int (*bdrv_read)(BlockDriverState *bs, int64_t sector_num, 
+                     uint8_t *buf, int nb_sectors);
+    int (*bdrv_write)(BlockDriverState *bs, int64_t sector_num, 
+                      const uint8_t *buf, int nb_sectors);
+    void (*bdrv_close)(BlockDriverState *bs);
+    int (*bdrv_create)(const char *filename, int64_t total_sectors, 
+                       const char *backing_file, int flags);
+    int (*bdrv_is_allocated)(BlockDriverState *bs, int64_t sector_num,
+                             int nb_sectors, int *pnum);
+    int (*bdrv_set_key)(BlockDriverState *bs, const char *key);
+    struct BlockDriver *next;
+};
+
+struct BlockDriverState {
+    int64_t total_sectors;
+    int read_only; /* if true, the media is read only */
+    int inserted; /* if true, the media is present */
+    int removable; /* if true, the media can be removed */
+    int locked;    /* if true, the media cannot temporarily be ejected */
+    int encrypted; /* if true, the media is encrypted */
+    /* event callback when inserting/removing */
+    void (*change_cb)(void *opaque);
+    void *change_opaque;
+
+    BlockDriver *drv;
+    void *opaque;
+
+    int boot_sector_enabled;
+    uint8_t boot_sector_data[512];
+
+    char filename[1024];
+    char backing_file[1024]; /* if non zero, the image is a diff of
+                                this file image */
+    int is_temporary;
+    
+    BlockDriverState *backing_hd;
+    
+    /* NOTE: the following infos are only hints for real hardware
+       drivers. They are not used by the block driver */
+    int cyls, heads, secs;
+    int type;
+    char device_name[32];
+    BlockDriverState *next;
+};
+
+#endif /* BLOCK_INT_H */
diff --git a/tools/ioemu/bswap.h b/tools/ioemu/bswap.h
new file mode 100644 (file)
index 0000000..37fb04e
--- /dev/null
@@ -0,0 +1,202 @@
+#ifndef BSWAP_H
+#define BSWAP_H
+
+#include "config-host.h"
+
+#include <inttypes.h>
+
+#ifdef HAVE_BYTESWAP_H
+#include <byteswap.h>
+#else
+
+#define bswap_16(x) \
+({ \
+       uint16_t __x = (x); \
+       ((uint16_t)( \
+               (((uint16_t)(__x) & (uint16_t)0x00ffU) << 8) | \
+               (((uint16_t)(__x) & (uint16_t)0xff00U) >> 8) )); \
+})
+
+#define bswap_32(x) \
+({ \
+       uint32_t __x = (x); \
+       ((uint32_t)( \
+               (((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \
+               (((uint32_t)(__x) & (uint32_t)0x0000ff00UL) <<  8) | \
+               (((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >>  8) | \
+               (((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) )); \
+})
+
+#define bswap_64(x) \
+({ \
+       uint64_t __x = (x); \
+       ((uint64_t)( \
+               (uint64_t)(((uint64_t)(__x) & (uint64_t)0x00000000000000ffULL) << 56) | \
+               (uint64_t)(((uint64_t)(__x) & (uint64_t)0x000000000000ff00ULL) << 40) | \
+               (uint64_t)(((uint64_t)(__x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \
+               (uint64_t)(((uint64_t)(__x) & (uint64_t)0x00000000ff000000ULL) <<  8) | \
+               (uint64_t)(((uint64_t)(__x) & (uint64_t)0x000000ff00000000ULL) >>  8) | \
+               (uint64_t)(((uint64_t)(__x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \
+               (uint64_t)(((uint64_t)(__x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \
+               (uint64_t)(((uint64_t)(__x) & (uint64_t)0xff00000000000000ULL) >> 56) )); \
+})
+
+#endif /* !HAVE_BYTESWAP_H */
+
+static inline uint16_t bswap16(uint16_t x)
+{
+    return bswap_16(x);
+}
+
+static inline uint32_t bswap32(uint32_t x) 
+{
+    return bswap_32(x);
+}
+
+static inline uint64_t bswap64(uint64_t x) 
+{
+    return bswap_64(x);
+}
+
+static inline void bswap16s(uint16_t *s)
+{
+    *s = bswap16(*s);
+}
+
+static inline void bswap32s(uint32_t *s)
+{
+    *s = bswap32(*s);
+}
+
+static inline void bswap64s(uint64_t *s)
+{
+    *s = bswap64(*s);
+}
+
+#if defined(WORDS_BIGENDIAN)
+#define be_bswap(v, size) (v)
+#define le_bswap(v, size) bswap ## size(v)
+#define be_bswaps(v, size)
+#define le_bswaps(p, size) *p = bswap ## size(*p);
+#else
+#define le_bswap(v, size) (v)
+#define be_bswap(v, size) bswap ## size(v)
+#define le_bswaps(v, size)
+#define be_bswaps(p, size) *p = bswap ## size(*p);
+#endif
+
+#define CPU_CONVERT(endian, size, type)\
+static inline type endian ## size ## _to_cpu(type v)\
+{\
+    return endian ## _bswap(v, size);\
+}\
+\
+static inline type cpu_to_ ## endian ## size(type v)\
+{\
+    return endian ## _bswap(v, size);\
+}\
+\
+static inline void endian ## size ## _to_cpus(type *p)\
+{\
+    endian ## _bswaps(p, size)\
+}\
+\
+static inline void cpu_to_ ## endian ## size ## s(type *p)\
+{\
+    endian ## _bswaps(p, size)\
+}\
+\
+static inline type endian ## size ## _to_cpup(const type *p)\
+{\
+    return endian ## size ## _to_cpu(*p);\
+}\
+\
+static inline void cpu_to_ ## endian ## size ## w(type *p, type v)\
+{\
+     *p = cpu_to_ ## endian ## size(v);\
+}
+
+CPU_CONVERT(be, 16, uint16_t)
+CPU_CONVERT(be, 32, uint32_t)
+CPU_CONVERT(be, 64, uint64_t)
+
+CPU_CONVERT(le, 16, uint16_t)
+CPU_CONVERT(le, 32, uint32_t)
+CPU_CONVERT(le, 64, uint64_t)
+
+/* unaligned versions (optimized for frequent unaligned accesses)*/
+
+#if defined(__i386__) || defined(__powerpc__)
+
+#define cpu_to_le16wu(p, v) cpu_to_le16w(p, v)
+#define cpu_to_le32wu(p, v) cpu_to_le32w(p, v)
+#define le16_to_cpupu(p) le16_to_cpup(p)
+#define le32_to_cpupu(p) le32_to_cpup(p)
+
+#define cpu_to_be16wu(p, v) cpu_to_be16w(p, v)
+#define cpu_to_be32wu(p, v) cpu_to_be32w(p, v)
+
+#else
+
+static inline void cpu_to_le16wu(uint16_t *p, uint16_t v)
+{
+    uint8_t *p1 = (uint8_t *)p;
+
+    p1[0] = v;
+    p1[1] = v >> 8;
+}
+
+static inline void cpu_to_le32wu(uint32_t *p, uint32_t v)
+{
+    uint8_t *p1 = (uint8_t *)p;
+
+    p1[0] = v;
+    p1[1] = v >> 8;
+    p1[2] = v >> 16;
+    p1[3] = v >> 24;
+}
+
+static inline uint16_t le16_to_cpupu(const uint16_t *p)
+{
+    const uint8_t *p1 = (const uint8_t *)p;
+    return p1[0] | (p1[1] << 8);
+}
+
+static inline uint32_t le32_to_cpupu(const uint32_t *p)
+{
+    const uint8_t *p1 = (const uint8_t *)p;
+    return p1[0] | (p1[1] << 8) | (p1[2] << 16) | (p1[3] << 24);
+}
+
+static inline void cpu_to_be16wu(uint16_t *p, uint16_t v)
+{
+    uint8_t *p1 = (uint8_t *)p;
+
+    p1[0] = v >> 8;
+    p1[1] = v;
+}
+
+static inline void cpu_to_be32wu(uint32_t *p, uint32_t v)
+{
+    uint8_t *p1 = (uint8_t *)p;
+
+    p1[0] = v >> 24;
+    p1[1] = v >> 16;
+    p1[2] = v >> 8;
+    p1[3] = v;
+}
+
+#endif
+
+#ifdef WORDS_BIGENDIAN
+#define cpu_to_32wu cpu_to_be32wu
+#else
+#define cpu_to_32wu cpu_to_le32wu
+#endif
+
+#undef le_bswap
+#undef be_bswap
+#undef le_bswaps
+#undef be_bswaps
+
+#endif /* BSWAP_H */
diff --git a/tools/ioemu/configure b/tools/ioemu/configure
new file mode 100755 (executable)
index 0000000..ea9d039
--- /dev/null
@@ -0,0 +1,585 @@
+#!/bin/sh
+#
+# qemu configure script (c) 2003 Fabrice Bellard
+#
+# set temporary file name
+if test ! -z "$TMPDIR" ; then
+    TMPDIR1="${TMPDIR}"
+elif test ! -z "$TEMPDIR" ; then
+    TMPDIR1="${TEMPDIR}"
+else
+    TMPDIR1="/tmp"
+fi
+
+TMPC="${TMPDIR1}/qemu-conf-${RANDOM}-$$-${RANDOM}.c"
+TMPO="${TMPDIR1}/qemu-conf-${RANDOM}-$$-${RANDOM}.o"
+TMPE="${TMPDIR1}/qemu-conf-${RANDOM}-$$-${RANDOM}"
+TMPS="${TMPDIR1}/qemu-conf-${RANDOM}-$$-${RANDOM}.S"
+
+# default parameters
+prefix=""
+static="no"
+libdir="lib"
+cross_prefix=""
+cc="gcc"
+host_cc="gcc"
+ar="ar"
+make="make"
+strip="strip"
+cpu=`uname -m`
+target_list="target-i386-dm"
+case "$cpu" in
+  i386|i486|i586|i686|i86pc|BePC)
+    cpu="i386"
+  ;;
+  armv4l)
+    cpu="armv4l"
+  ;;
+  alpha)
+    cpu="alpha"
+  ;;
+  "Power Macintosh"|ppc|ppc64)
+    cpu="powerpc"
+  ;;
+  mips)
+    cpu="mips"
+  ;;
+  s390)
+    cpu="s390"
+  ;;
+  sparc)
+    cpu="sparc"
+  ;;
+  sparc64)
+    cpu="sparc64"
+  ;;
+  ia64)
+    cpu="ia64"
+  ;;
+  m68k)
+    cpu="m68k"
+  ;;
+  x86_64|amd64)
+    cpu="amd64"
+    libdir="lib64"
+  ;;
+  *)
+    cpu="unknown"
+  ;;
+esac
+gprof="no"
+bigendian="no"
+mingw32="no"
+EXESUF=""
+gdbstub="no"
+slirp="no"
+adlib="no"
+oss="no"
+fmod="no"
+fmod_lib=""
+fmod_inc=""
+
+# OS specific
+targetos=`uname -s`
+case $targetos in
+MINGW32*)
+mingw32="yes"
+;;
+FreeBSD)
+bsd="yes"
+oss="yes"
+;;
+NetBSD)
+bsd="yes"
+oss="yes"
+;;
+OpenBSD)
+bsd="yes"
+oss="yes"
+;;
+Darwin)
+bsd="yes"
+darwin="yes"
+;;
+*) 
+oss="yes"
+;;
+esac
+
+if [ "$bsd" = "yes" ] ; then
+  if [ ! "$darwin" = "yes" ] ; then
+    make="gmake"
+  fi
+  target_list="i386-softmmu ppc-softmmu sparc-softmmu"
+fi
+
+# find source path
+# XXX: we assume an absolute path is given when launching configure, 
+# except in './configure' case.
+source_path=${0%configure}
+source_path=${source_path%/}
+source_path_used="yes"
+if test -z "$source_path" -o "$source_path" = "." ; then
+    source_path=`pwd`
+    source_path_used="no"
+fi
+
+for opt do
+  case "$opt" in
+  --prefix=*) prefix=`echo $opt | cut -d '=' -f 2`
+  ;;
+  --interp-prefix=*) interp_prefix=`echo $opt | cut -d '=' -f 2`
+  ;;
+  --source-path=*) source_path=`echo $opt | cut -d '=' -f 2`
+  ;;
+  --cross-prefix=*) cross_prefix=`echo $opt | cut -d '=' -f 2`
+  ;;
+  --cc=*) cc=`echo $opt | cut -d '=' -f 2`
+  ;;
+  --make=*) make=`echo $opt | cut -d '=' -f 2`
+  ;;
+  --extra-cflags=*) CFLAGS="${opt#--extra-cflags=}"
+  ;;
+  --extra-ldflags=*) LDFLAGS="${opt#--extra-ldflags=}"
+  ;;
+  --extra-libs=*) extralibs=${opt#--extra-libs=}
+  ;;
+  --cpu=*) cpu=`echo $opt | cut -d '=' -f 2`
+  ;;
+  --target-list=*) target_list=${opt#--target-list=}
+  ;;
+  --enable-gprof) gprof="yes"
+  ;;
+  --static) static="yes"
+  ;;
+  --disable-sdl) sdl="no"
+  ;;
+  --enable-fmod) fmod="yes"
+  ;;
+  --fmod-lib=*) fmod_lib=${opt#--fmod-lib=}
+  ;;
+  --fmod-inc=*) fmod_inc=${opt#--fmod-inc=}
+  ;;
+  --disable-vnc) vnc="no"
+  ;;
+  --enable-mingw32) mingw32="yes" ; cross_prefix="i386-mingw32-"
+  ;; 
+  --disable-slirp) slirp="no"
+  ;; 
+  --enable-adlib) adlib="yes"
+  ;; 
+  esac
+done
+
+# Checking for CFLAGS
+if test -z "$CFLAGS"; then
+    CFLAGS="-O2"
+fi
+
+cc="${cross_prefix}${cc}"
+ar="${cross_prefix}${ar}"
+strip="${cross_prefix}${strip}"
+
+if test "$mingw32" = "yes" ; then
+    target_list="i386-softmmu ppc-softmmu sparc-softmmu"
+    EXESUF=".exe"
+    gdbstub="no"
+    oss="no"
+fi
+
+if test -z "$cross_prefix" ; then
+
+# ---
+# big/little endian test
+cat > $TMPC << EOF
+#include <inttypes.h>
+int main(int argc, char ** argv){
+       volatile uint32_t i=0x01234567;
+       return (*((uint8_t*)(&i))) == 0x67;
+}
+EOF
+
+if $cc -o $TMPE $TMPC 2>/dev/null ; then
+$TMPE && bigendian="yes"
+else
+echo big/little test failed
+fi
+
+else
+
+# if cross compiling, cannot launch a program, so make a static guess
+if test "$cpu" = "powerpc" -o "$cpu" = "mips" -o "$cpu" = "s390" -o "$cpu" = "sparc" -o "$cpu" = "sparc64" -o "$cpu" = "m68k"; then
+    bigendian="yes"
+fi
+
+fi
+
+# check gcc options support
+cat > $TMPC <<EOF
+int main(void) {
+}
+EOF
+
+have_gcc3_options="no"
+if $cc -fno-reorder-blocks -fno-optimize-sibling-calls -o $TMPO $TMPC 2> /dev/null ; then
+   have_gcc3_options="yes"
+fi
+
+##########################################
+# VNC probe
+
+if test -z "$vnc"; then
+
+if libvncserver-config --version > /dev/null; then
+    vnc=yes
+else
+    vnc=no
+fi
+
+fi
+
+##########################################
+# SDL probe
+
+sdl_too_old=no
+
+if test -z "$sdl" ; then
+
+sdl_config="sdl-config"
+sdl=no
+sdl_static=no
+
+if test "$mingw32" = "yes" -a ! -z "$cross_prefix" ; then
+# win32 cross compilation case
+    sdl_config="i386-mingw32msvc-sdl-config"
+    sdl=yes
+else
+# normal SDL probe
+cat > $TMPC << EOF
+#include <SDL.h>
+#undef main /* We don't want SDL to override our main() */
+int main( void ) { return SDL_Init (SDL_INIT_VIDEO); }
+EOF
+
+if $cc -o $TMPE `$sdl_config --cflags 2> /dev/null` $TMPC `$sdl_config --libs 2> /dev/null` 2> /dev/null ; then
+_sdlversion=`$sdl_config --version | sed 's/[^0-9]//g'`
+if test "$_sdlversion" -lt 121 ; then
+sdl_too_old=yes
+else
+sdl=yes
+fi
+
+# static link with sdl ?
+if test "$sdl" = "yes" ; then
+aa="no"
+`$sdl_config --static-libs | grep \\\-laa > /dev/null` && aa="yes"
+sdl_static_libs=`$sdl_config --static-libs`
+if [ "$aa" = "yes" ] ; then
+  sdl_static_libs="$sdl_static_libs `aalib-config --static-libs`"
+fi
+
+if $cc -o $TMPE `$sdl_config --cflags 2> /dev/null` $TMPC $sdl_static_libs 2> /dev/null; then
+  sdl_static=yes
+fi
+
+fi # static link
+
+fi # sdl compile test
+
+fi # cross compilation
+fi # -z $sdl
+
+if test x"$1" = x"-h" -o x"$1" = x"--help" ; then
+cat << EOF
+
+Usage: configure [options]
+Options: [defaults in brackets after descriptions]
+
+EOF
+echo "Standard options:"
+echo "  --help                   print this message"
+echo "  --prefix=PREFIX          install in PREFIX [$prefix]"
+echo "  --interp-prefix=PREFIX   where to find shared libraries, etc."
+echo "                           use %M for cpu name [$interp_prefix]"
+echo "  --target-list=LIST       set target list [$target_list]"
+echo "  --disable-vnc            disable vnc support (else configure checks"
+echo "                           for libvncserver-config in your PATH)"
+echo ""
+echo "Advanced options (experts only):"
+echo "  --source-path=PATH       path of source code [$source_path]"
+echo "  --cross-prefix=PREFIX    use PREFIX for compile tools [$cross_prefix]"
+echo "  --cc=CC                  use C compiler CC [$cc]"
+echo "  --make=MAKE              use specified make [$make]"
+echo "  --static                 enable static build [$static]"
+echo "  --enable-mingw32         enable Win32 cross compilation with mingw32"
+echo "  --enable-fmod            enable FMOD audio output driver"
+echo "  --fmod-lib               path to FMOD library"
+echo "  --fmod-inc               path to FMOD includes"
+echo ""
+echo "NOTE: The object files are build at the place where configure is launched"
+exit 1
+fi
+
+#installroot=$source_path/../../dist/install
+installroot=
+
+if test "$mingw32" = "yes" ; then
+if test -z "$prefix" ; then
+    prefix="/c/Program Files/Qemu"
+fi
+
+mandir="$prefix"
+datadir="$prefix"
+docdir="$prefix"
+bindir="$prefix"
+configdir=""
+else
+if test -z "$prefix" ; then
+    prefix="usr/local"
+fi
+mandir="$installroot/$prefix/share/man"
+datadir="$installroot/$prefix/share/qemu"
+docdir="$installroot/$prefix/share/doc/qemu"
+bindir="$installroot/$prefix/bin"
+configdir="$installroot/etc/xen"
+fi
+
+echo "Install prefix    $prefix"
+echo "BIOS directory    $datadir"
+echo "binary directory  $bindir"
+if test "$mingw32" = "no" ; then
+echo "Manual directory  $mandir"
+fi
+echo "Source path       $source_path"
+echo "C compiler        $cc"
+echo "make              $make"
+echo "host CPU          $cpu"
+echo "host big endian   $bigendian"
+echo "target list       $target_list"
+echo "gprof enabled     $gprof"
+echo "static build      $static"
+echo "VNC support       $vnc"
+echo "SDL support       $sdl"
+echo "SDL static link   $sdl_static"
+echo "mingw32 support   $mingw32"
+echo "Adlib support     $adlib"
+echo -n "FMOD support      $fmod"
+if test $fmod = "yes"; then
+    echo -n " (lib='$fmod_lib' include='$fmod_inc')"
+fi
+echo ""
+
+if test $sdl_too_old = "yes"; then
+echo "-> Your SDL version is too old - please upgrade to have FFplay/SDL support"
+fi
+if test "$sdl_static" = "no"; then
+  echo "WARNING: cannot compile statically with SDL - qemu-fast won't have a graphical output"
+fi
+
+config_mak="config-host.mak"
+config_h="config-host.h"
+
+#echo "Creating $config_mak and $config_h"
+
+echo "# Automatically generated by configure - do not modify" > $config_mak
+echo "/* Automatically generated by configure - do not modify */" > $config_h
+
+echo "prefix=$prefix" >> $config_mak
+echo "bindir=$bindir" >> $config_mak
+echo "mandir=$mandir" >> $config_mak
+echo "datadir=$datadir" >> $config_mak
+echo "docdir=$docdir" >> $config_mak
+echo "configdir=$configdir" >> $config_mak
+echo "LIBDIR=$libdir" >> $config_mak
+echo "#define CONFIG_QEMU_SHAREDIR \"$datadir\"" >> $config_h
+echo "MAKE=$make" >> $config_mak
+echo "CC=$cc" >> $config_mak
+if test "$have_gcc3_options" = "yes" ; then
+  echo "HAVE_GCC3_OPTIONS=yes" >> $config_mak
+fi
+echo "HOST_CC=$host_cc" >> $config_mak
+echo "AR=$ar" >> $config_mak
+echo "STRIP=$strip -s -R .comment -R .note" >> $config_mak
+echo "CFLAGS=$CFLAGS" >> $config_mak
+echo "LDFLAGS=$LDFLAGS" >> $config_mak
+echo "EXESUF=$EXESUF" >> $config_mak
+
+if test "$bigendian" = "yes" ; then
+  echo "WORDS_BIGENDIAN=yes" >> $config_mak
+  echo "#define WORDS_BIGENDIAN 1" >> $config_h
+fi
+if test "$mingw32" = "yes" ; then
+  echo "CONFIG_WIN32=yes" >> $config_mak
+  echo "#define CONFIG_WIN32 1" >> $config_h
+elif test -f "/usr/include/byteswap.h" ; then
+  echo "#define HAVE_BYTESWAP_H 1" >> $config_h
+fi
+if test "$darwin" = "yes" ; then
+  echo "CONFIG_DARWIN=yes" >> $config_mak
+  echo "#define CONFIG_DARWIN 1" >> $config_h
+fi
+if test "$gdbstub" = "yes" ; then
+  echo "CONFIG_GDBSTUB=yes" >> $config_mak
+  echo "#define CONFIG_GDBSTUB 1" >> $config_h
+fi
+if test "$gprof" = "yes" ; then
+  echo "TARGET_GPROF=yes" >> $config_mak
+  echo "#define HAVE_GPROF 1" >> $config_h
+fi
+if test "$static" = "yes" ; then
+  echo "CONFIG_STATIC=yes" >> $config_mak
+  echo "#define CONFIG_STATIC 1" >> $config_h
+fi
+if test "$slirp" = "yes" ; then
+  echo "CONFIG_SLIRP=yes" >> $config_mak
+  echo "#define CONFIG_SLIRP 1" >> $config_h
+fi
+if test "$adlib" = "yes" ; then
+  echo "CONFIG_ADLIB=yes" >> $config_mak
+  echo "#define CONFIG_ADLIB 1" >> $config_h
+fi
+if test "$oss" = "yes" ; then
+  echo "CONFIG_OSS=yes" >> $config_mak
+  echo "#define CONFIG_OSS 1" >> $config_h
+fi
+if test "$fmod" = "yes" ; then
+  echo "CONFIG_FMOD=yes" >> $config_mak
+  echo "CONFIG_FMOD_LIB=$fmod_lib" >> $config_mak
+  echo "CONFIG_FMOD_INC=$fmod_inc" >> $config_mak
+  echo "#define CONFIG_FMOD 1" >> $config_h
+fi
+echo -n "VERSION=" >>$config_mak
+head $source_path/VERSION >>$config_mak
+echo "" >>$config_mak
+echo -n "#define QEMU_VERSION \"" >> $config_h
+head $source_path/VERSION >> $config_h
+echo "\"" >> $config_h
+
+echo "SRC_PATH=$source_path" >> $config_mak
+echo "TARGET_DIRS=$target_list" >> $config_mak
+
+# XXX: suppress that
+if [ "$bsd" = "yes" ] ; then
+  echo "#define O_LARGEFILE 0" >> $config_h
+  echo "#define MAP_ANONYMOUS MAP_ANON" >> $config_h
+  echo "#define _BSD 1" >> $config_h
+fi
+
+if test "$vnc" = "yes"; then
+  echo "CONFIG_VNC=yes" >> $config_mak
+  vnc_cflags=`libvncserver-config --cflags`
+  if [ -z $vnc_cflags ]; then
+    vnc_cflags="/usr/include"
+  fi
+  echo "VNC_CFLAGS=$vnc_cflags" >> $config_mak
+fi
+
+if test "$sdl" = "yes"; then
+  echo "CONFIG_SDL=yes" >> $config_mak
+  echo "SDL_CFLAGS=`$sdl_config --cflags`" >> $config_mak
+fi
+
+for target in $target_list; do 
+
+target_dir="$target"
+config_mak=$target_dir/config.mak
+config_h=$target_dir/config.h
+target_cpu=`echo $target | cut -d '-' -f 2`
+[ "$target_cpu" = "ppc" ] && target_bigendian=yes
+target_softmmu="no"
+if expr $target : '.*-softmmu' > /dev/null ; then
+  target_softmmu="yes"
+fi
+target_user_only="no"
+if expr $target : '.*-user' > /dev/null ; then
+  target_user_only="yes"
+fi
+#echo "Creating $config_mak, $config_h and $target_dir/Makefile"
+
+mkdir -p $target_dir
+if test "$target" = "arm-user" ; then
+  mkdir -p $target_dir/nwfpe
+fi
+if test "$target_user_only" = "no" ; then
+  mkdir -p $target_dir/slirp
+fi
+
+ln -sf $source_path/Makefile.target $target_dir/Makefile
+
+echo "# Automatically generated by configure - do not modify" > $config_mak
+echo "/* Automatically generated by configure - do not modify */" > $config_h
+
+
+echo "include ../config-host.mak" >> $config_mak
+echo "#include \"../config-host.h\"" >> $config_h
+
+if test "$target_cpu" = "i386" ; then
+  echo "TARGET_ARCH=i386" >> $config_mak
+  echo "#define TARGET_ARCH \"i386\"" >> $config_h
+  echo "#define TARGET_I386 1" >> $config_h
+fi
+
+interp_prefix1=`echo "$interp_prefix" | sed "s/%M/$target_cpu/g"`
+echo "#define CONFIG_QEMU_PREFIX \"$interp_prefix1\"" >> $config_h
+
+if test "$target_bigendian" = "yes" ; then
+  echo "TARGET_WORDS_BIGENDIAN=yes" >> $config_mak
+  echo "#define TARGET_WORDS_BIGENDIAN 1" >> $config_h
+fi
+if test "$target_softmmu" = "yes" ; then
+  echo "CONFIG_SOFTMMU=yes" >> $config_mak
+  echo "#define CONFIG_SOFTMMU 1" >> $config_h
+fi
+if test "$target_user_only" = "yes" ; then
+  echo "CONFIG_USER_ONLY=yes" >> $config_mak
+  echo "#define CONFIG_USER_ONLY 1" >> $config_h
+fi
+
+if test "$target_user_only" = "no"; then
+    if test "$vnc" = "yes"; then
+       echo "#define CONFIG_VNC 1" >> $config_h
+       echo "CONFIG_VNC=yes" >> $config_mak
+       echo "VNC_CFLAGS=`libvncserver-config --cflags`" >> $config_mak
+       echo "VNC_LIBS=`libvncserver-config --libs`" >> $config_mak
+    fi
+fi
+
+# sdl defines
+
+if test "$sdl" = "yes" -a "$target_user_only" = "no"; then
+    if test "$target_softmmu" = "no" -o "$static" = "yes"; then
+        sdl1=$sdl_static
+    else
+        sdl1=$sdl
+    fi
+    if test "$sdl1" = "yes" ; then
+        echo "#define CONFIG_SDL 1" >> $config_h
+        echo "CONFIG_SDL=yes" >> $config_mak
+        if test "$target_softmmu" = "no" -o "$static" = "yes"; then
+            echo "SDL_LIBS=$sdl_static_libs" >> $config_mak
+        else
+            echo "SDL_LIBS=`$sdl_config --libs`" >> $config_mak
+        fi
+        echo -n "SDL_CFLAGS=`$sdl_config --cflags`" >> $config_mak
+        if [ "${aa}" = "yes" ] ; then
+            echo -n " `aalib-config --cflags`" >> $config_mak ;
+        fi
+        echo "" >> $config_mak
+    fi
+fi
+
+done # for target in $targets
+
+# build tree in object directory if source path is different from current one
+if test "$source_path_used" = "yes" ; then
+    DIRS="tests"
+    FILES="Makefile tests/Makefile"
+    for dir in $DIRS ; do
+            mkdir -p $dir
+    done
+    for f in $FILES ; do
+        ln -sf $source_path/$f $f
+    done
+fi
+
+rm -f $TMPO $TMPC $TMPE $TMPS
diff --git a/tools/ioemu/console.c b/tools/ioemu/console.c
new file mode 100644 (file)
index 0000000..d758801
--- /dev/null
@@ -0,0 +1,731 @@
+/*
+ * QEMU graphical console
+ * 
+ * Copyright (c) 2004 Fabrice Bellard
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+
+#define DEFAULT_BACKSCROLL 512
+#define MAX_CONSOLES 12
+
+#define RGBA(r, g, b, a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
+#define RGB(r, g, b) RGBA(r, g, b, 0xff)
+
+typedef struct TextCell {
+    uint8_t ch;
+    uint8_t bgcol:4;
+    uint8_t fgcol:4;
+} TextCell;
+
+#define MAX_ESC_PARAMS 3
+
+enum TTYState {
+    TTY_STATE_NORM,
+    TTY_STATE_ESC,
+    TTY_STATE_CSI,
+};
+
+struct TextConsole {
+    int text_console; /* true if text console */
+    DisplayState *ds;
+    int g_width, g_height;
+    int width;
+    int height;
+    int total_height;
+    int backscroll_height;
+    int fgcol;
+    int bgcol;
+    int x, y;
+    int y_displayed;
+    int y_base;
+    TextCell *cells;
+
+    enum TTYState state;
+    int esc_params[MAX_ESC_PARAMS];
+    int nb_esc_params;
+
+    /* kbd read handler */
+    IOReadHandler *fd_read;
+    void *fd_opaque;
+};
+
+static TextConsole *active_console;
+static TextConsole *consoles[MAX_CONSOLES];
+static int nb_consoles = 0;
+
+/* convert a RGBA color to a color index usable in graphic primitives */
+static unsigned int vga_get_color(DisplayState *ds, unsigned int rgba)
+{
+    unsigned int r, g, b, color;
+
+    switch(ds->depth) {
+#if 0
+    case 8:
+        r = (rgba >> 16) & 0xff;
+        g = (rgba >> 8) & 0xff;
+        b = (rgba) & 0xff;
+        color = (rgb_to_index[r] * 6 * 6) + 
+            (rgb_to_index[g] * 6) + 
+            (rgb_to_index[b]);
+        break;
+#endif
+    case 15:
+        r = (rgba >> 16) & 0xff;
+        g = (rgba >> 8) & 0xff;
+        b = (rgba) & 0xff;
+        color = ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3);
+        break;
+    case 16:
+        r = (rgba >> 16) & 0xff;
+        g = (rgba >> 8) & 0xff;
+        b = (rgba) & 0xff;
+        color = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
+        break;
+    case 32:
+    default:
+        color = rgba;
+        break;
+    }
+    return color;
+}
+
+static void vga_fill_rect (DisplayState *ds, 
+                           int posx, int posy, int width, int height, uint32_t color)
+{
+    uint8_t *d, *d1;
+    int x, y, bpp;
+    
+    bpp = (ds->depth + 7) >> 3;
+    d1 = ds->data + 
+        ds->linesize * posy + bpp * posx;
+    for (y = 0; y < height; y++) {
+        d = d1;
+        switch(bpp) {
+        case 1:
+            for (x = 0; x < width; x++) {
+                *((uint8_t *)d) = color;
+                d++;
+            }
+            break;
+        case 2:
+            for (x = 0; x < width; x++) {
+                *((uint16_t *)d) = color;
+                d += 2;
+            }
+            break;
+        case 4:
+            for (x = 0; x < width; x++) {
+                *((uint32_t *)d) = color;
+                d += 4;
+            }
+            break;
+        }
+        d1 += ds->linesize;
+    }
+}
+
+/* copy from (xs, ys) to (xd, yd) a rectangle of size (w, h) */
+static void vga_bitblt(DisplayState *ds, int xs, int ys, int xd, int yd, int w, int h)
+{
+    const uint8_t *s;
+    uint8_t *d;
+    int wb, y, bpp;
+
+    bpp = (ds->depth + 7) >> 3;
+    wb = w * bpp;
+    if (yd <= ys) {
+        s = ds->data + 
+            ds->linesize * ys + bpp * xs;
+        d = ds->data + 
+            ds->linesize * yd + bpp * xd;
+        for (y = 0; y < h; y++) {
+            memmove(d, s, wb);
+            d += ds->linesize;
+            s += ds->linesize;
+        }
+    } else {
+        s = ds->data + 
+            ds->linesize * (ys + h - 1) + bpp * xs;
+        d = ds->data + 
+            ds->linesize * (yd + h - 1) + bpp * xd;
+       for (y = 0; y < h; y++) {
+            memmove(d, s, wb);
+            d -= ds->linesize;
+            s -= ds->linesize;
+        }
+    }
+}
+
+/***********************************************************/
+/* basic char display */
+
+#define FONT_HEIGHT 16
+#define FONT_WIDTH 8
+
+#include "vgafont.h"
+
+#define cbswap_32(__x) \
+((uint32_t)( \
+               (((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \
+               (((uint32_t)(__x) & (uint32_t)0x0000ff00UL) <<  8) | \
+               (((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >>  8) | \
+               (((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) ))
+
+#ifdef WORDS_BIGENDIAN
+#define PAT(x) x
+#else
+#define PAT(x) cbswap_32(x)
+#endif
+
+static const uint32_t dmask16[16] = {
+    PAT(0x00000000),
+    PAT(0x000000ff),
+    PAT(0x0000ff00),
+    PAT(0x0000ffff),
+    PAT(0x00ff0000),
+    PAT(0x00ff00ff),
+    PAT(0x00ffff00),
+    PAT(0x00ffffff),
+    PAT(0xff000000),
+    PAT(0xff0000ff),
+    PAT(0xff00ff00),
+    PAT(0xff00ffff),
+    PAT(0xffff0000),
+    PAT(0xffff00ff),
+    PAT(0xffffff00),
+    PAT(0xffffffff),
+};
+
+static const uint32_t dmask4[4] = {
+    PAT(0x00000000),
+    PAT(0x0000ffff),
+    PAT(0xffff0000),
+    PAT(0xffffffff),
+};
+
+static uint32_t color_table[8];
+
+static const uint32_t color_table_rgb[8] = {
+    RGB(0x00, 0x00, 0x00),
+    RGB(0xff, 0x00, 0x00),
+    RGB(0x00, 0xff, 0x00),
+    RGB(0xff, 0xff, 0x00),
+    RGB(0x00, 0x00, 0xff),
+    RGB(0xff, 0x00, 0xff),
+    RGB(0x00, 0xff, 0xff),
+    RGB(0xff, 0xff, 0xff),
+};
+
+static inline unsigned int col_expand(DisplayState *ds, unsigned int col)
+{
+    switch(ds->depth) {
+    case 8:
+        col |= col << 8;
+        col |= col << 16;
+        break;
+    case 15:
+    case 16:
+        col |= col << 16;
+        break;
+    default:
+        break;
+    }
+
+    return col;
+}
+
+static void vga_putcharxy(DisplayState *ds, int x, int y, int ch, 
+                          unsigned int fgcol, unsigned int bgcol)
+{
+    uint8_t *d;
+    const uint8_t *font_ptr;
+    unsigned int font_data, linesize, xorcol, bpp;
+    int i;
+
+    bpp = (ds->depth + 7) >> 3;
+    d = ds->data + 
+        ds->linesize * y * FONT_HEIGHT + bpp * x * FONT_WIDTH;
+    linesize = ds->linesize;
+    font_ptr = vgafont16 + FONT_HEIGHT * ch;
+    xorcol = bgcol ^ fgcol;
+    switch(ds->depth) {
+    case 8:
+        for(i = 0; i < FONT_HEIGHT; i++) {
+            font_data = *font_ptr++;
+            ((uint32_t *)d)[0] = (dmask16[(font_data >> 4)] & xorcol) ^ bgcol;
+            ((uint32_t *)d)[1] = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol;
+            d += linesize;
+        }
+        break;
+    case 16:
+    case 15:
+        for(i = 0; i < FONT_HEIGHT; i++) {
+            font_data = *font_ptr++;
+            ((uint32_t *)d)[0] = (dmask4[(font_data >> 6)] & xorcol) ^ bgcol;
+            ((uint32_t *)d)[1] = (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol;
+            ((uint32_t *)d)[2] = (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol;
+            ((uint32_t *)d)[3] = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol;
+            d += linesize;
+        }
+        break;
+    case 32:
+        for(i = 0; i < FONT_HEIGHT; i++) {
+            font_data = *font_ptr++;
+            ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol;
+            ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol;
+            ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol;
+            ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol;
+            ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol;
+            ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol;
+            ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol;
+            ((uint32_t *)d)[7] = (-((font_data >> 0) & 1) & xorcol) ^ bgcol;
+            d += linesize;
+        }
+        break;
+    }
+}
+
+static void text_console_resize(TextConsole *s)
+{
+    TextCell *cells, *c, *c1;
+    int w1, x, y, last_width;
+
+    last_width = s->width;
+    s->width = s->g_width / FONT_WIDTH;
+    s->height = s->g_height / FONT_HEIGHT;
+
+    w1 = last_width;
+    if (s->width < w1)
+        w1 = s->width;
+
+    cells = qemu_malloc(s->width * s->total_height * sizeof(TextCell));
+    for(y = 0; y < s->total_height; y++) {
+        c = &cells[y * s->width];
+        if (w1 > 0) {
+            c1 = &s->cells[y * last_width];
+            for(x = 0; x < w1; x++) {
+                *c++ = *c1++;
+            }
+        }
+        for(x = w1; x < s->width; x++) {
+            c->ch = ' ';
+            c->fgcol = 7;
+            c->bgcol = 0;
+            c++;
+        }
+    }
+    qemu_free(s->cells);
+    s->cells = cells;
+}
+
+static void update_xy(TextConsole *s, int x, int y)
+{
+    TextCell *c;
+    int y1, y2;
+
+    if (s == active_console) {
+        y1 = (s->y_base + y) % s->total_height;
+        y2 = y1 - s->y_displayed;
+        if (y2 < 0)
+            y2 += s->total_height;
+        if (y2 < s->height) {
+            c = &s->cells[y1 * s->width + x];
+            vga_putcharxy(s->ds, x, y2, c->ch, 
+                          color_table[c->fgcol], color_table[c->bgcol]);
+            dpy_update(s->ds, x * FONT_WIDTH, y2 * FONT_HEIGHT, 
+                       FONT_WIDTH, FONT_HEIGHT);
+        }
+    }
+}
+
+static void console_show_cursor(TextConsole *s, int show)
+{
+    TextCell *c;
+    int y, y1;
+
+    if (s == active_console) {
+        y1 = (s->y_base + s->y) % s->total_height;
+        y = y1 - s->y_displayed;
+        if (y < 0)
+            y += s->total_height;
+        if (y < s->height) {
+            c = &s->cells[y1 * s->width + s->x];
+            if (show) {
+                vga_putcharxy(s->ds, s->x, y, c->ch, 
+                              color_table[0], color_table[7]);
+            } else {
+                vga_putcharxy(s->ds, s->x, y, c->ch, 
+                              color_table[c->fgcol], color_table[c->bgcol]);
+            }
+            dpy_update(s->ds, s->x * FONT_WIDTH, y * FONT_HEIGHT, 
+                       FONT_WIDTH, FONT_HEIGHT);
+        }
+    }
+}
+
+static void console_refresh(TextConsole *s)
+{
+    TextCell *c;
+    int x, y, y1;
+
+    if (s != active_console) 
+        return;
+
+    vga_fill_rect(s->ds, 0, 0, s->ds->width, s->ds->height,
+                  color_table[0]);
+    y1 = s->y_displayed;
+    for(y = 0; y < s->height; y++) {
+        c = s->cells + y1 * s->width;
+        for(x = 0; x < s->width; x++) {
+            vga_putcharxy(s->ds, x, y, c->ch, 
+                          color_table[c->fgcol], color_table[c->bgcol]);
+            c++;
+        }
+        if (++y1 == s->total_height)
+            y1 = 0;
+    }
+    dpy_update(s->ds, 0, 0, s->ds->width, s->ds->height);
+    console_show_cursor(s, 1);
+}
+
+static void console_scroll(int ydelta)
+{
+    TextConsole *s;
+    int i, y1;
+    
+    s = active_console;
+    if (!s || !s->text_console)
+        return;
+
+    if (ydelta > 0) {
+        for(i = 0; i < ydelta; i++) {
+            if (s->y_displayed == s->y_base)
+                break;
+            if (++s->y_displayed == s->total_height)
+                s->y_displayed = 0;
+        }
+    } else {
+        ydelta = -ydelta;
+        i = s->backscroll_height;
+        if (i > s->total_height - s->height)
+            i = s->total_height - s->height;
+        y1 = s->y_base - i;
+        if (y1 < 0)
+            y1 += s->total_height;
+        for(i = 0; i < ydelta; i++) {
+            if (s->y_displayed == y1)
+                break;
+            if (--s->y_displayed < 0)
+                s->y_displayed = s->total_height - 1;
+        }
+    }
+    console_refresh(s);
+}
+
+static void console_put_lf(TextConsole *s)
+{
+    TextCell *c;
+    int x, y1;
+
+    s->x = 0;
+    s->y++;
+    if (s->y >= s->height) {
+        s->y = s->height - 1;
+        
+        if (s->y_displayed == s->y_base) {
+            if (++s->y_displayed == s->total_height)
+                s->y_displayed = 0;
+        }
+        if (++s->y_base == s->total_height)
+            s->y_base = 0;
+        if (s->backscroll_height < s->total_height)
+            s->backscroll_height++;
+        y1 = (s->y_base + s->height - 1) % s->total_height;
+        c = &s->cells[y1 * s->width];
+        for(x = 0; x < s->width; x++) {
+            c->ch = ' ';
+            c->fgcol = s->fgcol;
+            c->bgcol = s->bgcol;
+            c++;
+        }
+        if (s == active_console && s->y_displayed == s->y_base) {
+            vga_bitblt(s->ds, 0, FONT_HEIGHT, 0, 0, 
+                       s->width * FONT_WIDTH, 
+                       (s->height - 1) * FONT_HEIGHT);
+            vga_fill_rect(s->ds, 0, (s->height - 1) * FONT_HEIGHT,
+                          s->width * FONT_WIDTH, FONT_HEIGHT, 
+                          color_table[s->bgcol]);
+            dpy_update(s->ds, 0, 0, 
+                       s->width * FONT_WIDTH, s->height * FONT_HEIGHT);
+        }
+    }
+}
+
+static void console_putchar(TextConsole *s, int ch)
+{
+    TextCell *c;
+    int y1, i, x;
+
+    switch(s->state) {
+    case TTY_STATE_NORM:
+        switch(ch) {
+        case '\r':
+            s->x = 0;
+            break;
+        case '\n':
+            console_put_lf(s);
+            break;
+        case 27:
+            s->state = TTY_STATE_ESC;
+            break;
+        default:
+            y1 = (s->y_base + s->y) % s->total_height;
+            c = &s->cells[y1 * s->width + s->x];
+            c->ch = ch;
+            c->fgcol = s->fgcol;
+            c->bgcol = s->bgcol;
+            update_xy(s, s->x, s->y);
+            s->x++;
+            if (s->x >= s->width)
+                console_put_lf(s);
+            break;
+        }
+        break;
+    case TTY_STATE_ESC:
+        if (ch == '[') {
+            for(i=0;i<MAX_ESC_PARAMS;i++)
+                s->esc_params[i] = 0;
+            s->nb_esc_params = 0;
+            s->state = TTY_STATE_CSI;
+        } else {
+            s->state = TTY_STATE_NORM;
+        }
+        break;
+    case TTY_STATE_CSI:
+        if (ch >= '0' && ch <= '9') {
+            if (s->nb_esc_params < MAX_ESC_PARAMS) {
+                s->esc_params[s->nb_esc_params] = 
+                    s->esc_params[s->nb_esc_params] * 10 + ch - '0';
+            }
+        } else {
+            s->nb_esc_params++;
+            if (ch == ';')
+                break;
+            s->state = TTY_STATE_NORM;
+            switch(ch) {
+            case 'D':
+                if (s->x > 0)
+                    s->x--;
+                break;
+            case 'C':
+                if (s->x < (s->width - 1))
+                    s->x++;
+                break;
+            case 'K':
+                /* clear to eol */
+                y1 = (s->y_base + s->y) % s->total_height;
+                for(x = s->x; x < s->width; x++) {
+                    c = &s->cells[y1 * s->width + x];
+                    c->ch = ' ';
+                    c->fgcol = s->fgcol;
+                    c->bgcol = s->bgcol;
+                    c++;
+                    update_xy(s, x, s->y);
+                }
+                break;
+            default:
+                break;
+            }
+            break;
+        }
+    }
+}
+
+void console_select(unsigned int index)
+{
+    TextConsole *s;
+    
+    if (index >= MAX_CONSOLES)
+        return;
+    s = consoles[index];
+    if (s) {
+        active_console = s;
+        if (s->text_console) {
+            if (s->g_width != s->ds->width ||
+                s->g_height != s->ds->height) {
+               s->g_width = s->ds->width;
+               s->g_height = s->ds->height;
+                text_console_resize(s);
+           }
+            console_refresh(s);
+        }
+    }
+}
+
+static int console_puts(CharDriverState *chr, const uint8_t *buf, int len)
+{
+    TextConsole *s = chr->opaque;
+    int i;
+
+    console_show_cursor(s, 0);
+    for(i = 0; i < len; i++) {
+        console_putchar(s, buf[i]);
+    }
+    console_show_cursor(s, 1);
+    return len;
+}
+
+static void console_chr_add_read_handler(CharDriverState *chr, 
+                                         IOCanRWHandler *fd_can_read, 
+                                         IOReadHandler *fd_read, void *opaque)
+{
+    TextConsole *s = chr->opaque;
+    s->fd_read = fd_read;
+    s->fd_opaque = opaque;
+}
+
+static void console_send_event(CharDriverState *chr, int event)
+{
+    TextConsole *s = chr->opaque;
+    int i;
+
+    if (event == CHR_EVENT_FOCUS) {
+        for(i = 0; i < nb_consoles; i++) {
+            if (consoles[i] == s) {
+                console_select(i);
+                break;
+            }
+        }
+    }
+}
+
+/* called when an ascii key is pressed */
+void kbd_put_keysym(int keysym)
+{
+    TextConsole *s;
+    uint8_t buf[16], *q;
+    int c;
+
+    s = active_console;
+    if (!s || !s->text_console)
+        return;
+
+    switch(keysym) {
+    case QEMU_KEY_CTRL_UP:
+        console_scroll(-1);
+        break;
+    case QEMU_KEY_CTRL_DOWN:
+        console_scroll(1);
+        break;
+    case QEMU_KEY_CTRL_PAGEUP:
+        console_scroll(-10);
+        break;
+    case QEMU_KEY_CTRL_PAGEDOWN:
+        console_scroll(10);
+        break;
+    default:
+        if (s->fd_read) {
+            /* convert the QEMU keysym to VT100 key string */
+            q = buf;
+            if (keysym >= 0xe100 && keysym <= 0xe11f) {
+                *q++ = '\033';
+                *q++ = '[';
+                c = keysym - 0xe100;
+                if (c >= 10)
+                    *q++ = '0' + (c / 10);
+                *q++ = '0' + (c % 10);
+                *q++ = '~';
+            } else if (keysym >= 0xe120 && keysym <= 0xe17f) {
+                *q++ = '\033';
+                *q++ = '[';
+                *q++ = keysym & 0xff;
+            } else {
+                *q++ = keysym;
+            }
+            s->fd_read(s->fd_opaque, buf, q - buf);
+        }
+        break;
+    }
+}
+
+TextConsole *graphic_console_init(DisplayState *ds)
+{
+    TextConsole *s;
+
+    if (nb_consoles >= MAX_CONSOLES)
+        return NULL;
+    s = qemu_mallocz(sizeof(TextConsole));
+    if (!s) {
+        return NULL;
+    }
+    if (!active_console)
+        active_console = s;
+    s->ds = ds;
+    consoles[nb_consoles++] = s;
+    return s;
+}
+
+int is_active_console(TextConsole *s)
+{
+    return s == active_console;
+}
+
+CharDriverState *text_console_init(DisplayState *ds)
+{
+    CharDriverState *chr;
+    TextConsole *s;
+    int i;
+    static int color_inited;
+    
+    chr = qemu_mallocz(sizeof(CharDriverState));
+    if (!chr)
+        return NULL;
+    s = graphic_console_init(ds);
+    if (!s) {
+        free(chr);
+        return NULL;
+    }
+    s->text_console = 1;
+    chr->opaque = s;
+    chr->chr_write = console_puts;
+    chr->chr_add_read_handler = console_chr_add_read_handler;
+    chr->chr_send_event = console_send_event;
+
+    if (!color_inited) {
+        color_inited = 1;
+        for(i = 0; i < 8; i++) {
+            color_table[i] = col_expand(s->ds, 
+                                        vga_get_color(s->ds, color_table_rgb[i]));
+        }
+    }
+    s->y_displayed = 0;
+    s->y_base = 0;
+    s->total_height = DEFAULT_BACKSCROLL;
+    s->x = 0;
+    s->y = 0;
+    s->fgcol = 7;
+    s->bgcol = 0;
+    s->g_width = s->ds->width;
+    s->g_height = s->ds->height;
+    text_console_resize(s);
+
+    return chr;
+}
diff --git a/tools/ioemu/cpu-all.h b/tools/ioemu/cpu-all.h
new file mode 100644 (file)
index 0000000..6e9a8b8
--- /dev/null
@@ -0,0 +1,688 @@
+/*
+ * defines common to all virtual CPUs
+ * 
+ *  Copyright (c) 2003 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef CPU_ALL_H
+#define CPU_ALL_H
+
+#if defined(__arm__) || defined(__sparc__)
+#define WORDS_ALIGNED
+#endif
+
+/* some important defines: 
+ * 
+ * WORDS_ALIGNED : if defined, the host cpu can only make word aligned
+ * memory accesses.
+ * 
+ * WORDS_BIGENDIAN : if defined, the host cpu is big endian and
+ * otherwise little endian.
+ * 
+ * (TARGET_WORDS_ALIGNED : same for target cpu (not supported yet))
+ * 
+ * TARGET_WORDS_BIGENDIAN : same for target cpu
+ */
+
+#include "bswap.h"
+
+#if defined(WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
+#define BSWAP_NEEDED
+#endif
+
+#ifdef BSWAP_NEEDED
+
+static inline uint16_t tswap16(uint16_t s)
+{
+    return bswap16(s);
+}
+
+static inline uint32_t tswap32(uint32_t s)
+{
+    return bswap32(s);
+}
+
+static inline uint64_t tswap64(uint64_t s)
+{
+    return bswap64(s);
+}
+
+static inline void tswap16s(uint16_t *s)
+{
+    *s = bswap16(*s);
+}
+
+static inline void tswap32s(uint32_t *s)
+{
+    *s = bswap32(*s);
+}
+
+static inline void tswap64s(uint64_t *s)
+{
+    *s = bswap64(*s);
+}
+
+#else
+
+static inline uint16_t tswap16(uint16_t s)
+{
+    return s;
+}
+
+static inline uint32_t tswap32(uint32_t s)
+{
+    return s;
+}
+
+static inline uint64_t tswap64(uint64_t s)
+{
+    return s;
+}
+
+static inline void tswap16s(uint16_t *s)
+{
+}
+
+static inline void tswap32s(uint32_t *s)
+{
+}
+
+static inline void tswap64s(uint64_t *s)
+{
+}
+
+#endif
+
+#if TARGET_LONG_SIZE == 4
+#define tswapl(s) tswap32(s)
+#define tswapls(s) tswap32s((uint32_t *)(s))
+#else
+#define tswapl(s) tswap64(s)
+#define tswapls(s) tswap64s((uint64_t *)(s))
+#endif
+
+/* NOTE: arm is horrible as double 32 bit words are stored in big endian ! */
+typedef union {
+    double d;
+#if !defined(WORDS_BIGENDIAN) && !defined(__arm__)
+    struct {
+        uint32_t lower;
+        uint32_t upper;
+    } l;
+#else
+    struct {
+        uint32_t upper;
+        uint32_t lower;
+    } l;
+#endif
+    uint64_t ll;
+} CPU_DoubleU;
+
+/* CPU memory access without any memory or io remapping */
+
+/*
+ * the generic syntax for the memory accesses is:
+ *
+ * load: ld{type}{sign}{size}{endian}_{access_type}(ptr)
+ *
+ * store: st{type}{size}{endian}_{access_type}(ptr, val)
+ *
+ * type is:
+ * (empty): integer access
+ *   f    : float access
+ * 
+ * sign is:
+ * (empty): for floats or 32 bit size
+ *   u    : unsigned
+ *   s    : signed
+ *
+ * size is:
+ *   b: 8 bits
+ *   w: 16 bits
+ *   l: 32 bits
+ *   q: 64 bits
+ * 
+ * endian is:
+ * (empty): target cpu endianness or 8 bit access
+ *   r    : reversed target cpu endianness (not implemented yet)
+ *   be   : big endian (not implemented yet)
+ *   le   : little endian (not implemented yet)
+ *
+ * access_type is:
+ *   raw    : host memory access
+ *   user   : user mode access using soft MMU
+ *   kernel : kernel mode access using soft MMU
+ */
+static inline int ldub_raw(void *ptr)
+{
+    return *(uint8_t *)ptr;
+}
+
+static inline int ldsb_raw(void *ptr)
+{
+    return *(int8_t *)ptr;
+}
+
+static inline void stb_raw(void *ptr, int v)
+{
+    *(uint8_t *)ptr = v;
+}
+
+/* NOTE: on arm, putting 2 in /proc/sys/debug/alignment so that the
+   kernel handles unaligned load/stores may give better results, but
+   it is a system wide setting : bad */
+#if !defined(TARGET_WORDS_BIGENDIAN) && (defined(WORDS_BIGENDIAN) || defined(WORDS_ALIGNED))
+
+/* conservative code for little endian unaligned accesses */
+static inline int lduw_raw(void *ptr)
+{
+#ifdef __powerpc__
+    int val;
+    __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
+    return val;
+#else
+    uint8_t *p = ptr;
+    return p[0] | (p[1] << 8);
+#endif
+}
+
+static inline int ldsw_raw(void *ptr)
+{
+#ifdef __powerpc__
+    int val;
+    __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
+    return (int16_t)val;
+#else
+    uint8_t *p = ptr;
+    return (int16_t)(p[0] | (p[1] << 8));
+#endif
+}
+
+static inline int ldl_raw(void *ptr)
+{
+#ifdef __powerpc__
+    int val;
+    __asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (ptr));
+    return val;
+#else
+    uint8_t *p = ptr;
+    return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
+#endif
+}
+
+static inline uint64_t ldq_raw(void *ptr)
+{
+    uint8_t *p = ptr;
+    uint32_t v1, v2;
+    v1 = ldl_raw(p);
+    v2 = ldl_raw(p + 4);
+    return v1 | ((uint64_t)v2 << 32);
+}
+
+static inline void stw_raw(void *ptr, int v)
+{
+#ifdef __powerpc__
+    __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*(uint16_t *)ptr) : "r" (v), "r" (ptr));
+#else
+    uint8_t *p = ptr;
+    p[0] = v;
+    p[1] = v >> 8;
+#endif
+}
+
+static inline void stl_raw(void *ptr, int v)
+{
+#ifdef __powerpc__
+    __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*(uint32_t *)ptr) : "r" (v), "r" (ptr));
+#else
+    uint8_t *p = ptr;
+    p[0] = v;
+    p[1] = v >> 8;
+    p[2] = v >> 16;
+    p[3] = v >> 24;
+#endif
+}
+
+static inline void stq_raw(void *ptr, uint64_t v)
+{
+    uint8_t *p = ptr;
+    stl_raw(p, (uint32_t)v);
+    stl_raw(p + 4, v >> 32);
+}
+
+/* float access */
+
+static inline float ldfl_raw(void *ptr)
+{
+    union {
+        float f;
+        uint32_t i;
+    } u;
+    u.i = ldl_raw(ptr);
+    return u.f;
+}
+
+static inline void stfl_raw(void *ptr, float v)
+{
+    union {
+        float f;
+        uint32_t i;
+    } u;
+    u.f = v;
+    stl_raw(ptr, u.i);
+}
+
+static inline double ldfq_raw(void *ptr)
+{
+    CPU_DoubleU u;
+    u.l.lower = ldl_raw(ptr);
+    u.l.upper = ldl_raw(ptr + 4);
+    return u.d;
+}
+
+static inline void stfq_raw(void *ptr, double v)
+{
+    CPU_DoubleU u;
+    u.d = v;
+    stl_raw(ptr, u.l.lower);
+    stl_raw(ptr + 4, u.l.upper);
+}
+
+#elif defined(TARGET_WORDS_BIGENDIAN) && (!defined(WORDS_BIGENDIAN) || defined(WORDS_ALIGNED))
+
+static inline int lduw_raw(void *ptr)
+{
+#if defined(__i386__)
+    int val;
+    asm volatile ("movzwl %1, %0\n"
+                  "xchgb %b0, %h0\n"
+                  : "=q" (val)
+                  : "m" (*(uint16_t *)ptr));
+    return val;
+#else
+    uint8_t *b = (uint8_t *) ptr;
+    return ((b[0] << 8) | b[1]);
+#endif
+}
+
+static inline int ldsw_raw(void *ptr)
+{
+#if defined(__i386__)
+    int val;
+    asm volatile ("movzwl %1, %0\n"
+                  "xchgb %b0, %h0\n"
+                  : "=q" (val)
+                  : "m" (*(uint16_t *)ptr));
+    return (int16_t)val;
+#else
+    uint8_t *b = (uint8_t *) ptr;
+    return (int16_t)((b[0] << 8) | b[1]);
+#endif
+}
+
+static inline int ldl_raw(void *ptr)
+{
+#if defined(__i386__) || defined(__x86_64__)
+    int val;
+    asm volatile ("movl %1, %0\n"
+                  "bswap %0\n"
+                  : "=r" (val)
+                  : "m" (*(uint32_t *)ptr));
+    return val;
+#else
+    uint8_t *b = (uint8_t *) ptr;
+    return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
+#endif
+}
+
+static inline uint64_t ldq_raw(void *ptr)
+{
+    uint32_t a,b;
+    a = ldl_raw(ptr);
+    b = ldl_raw(ptr+4);
+    return (((uint64_t)a<<32)|b);
+}
+
+static inline void stw_raw(void *ptr, int v)
+{
+#if defined(__i386__)
+    asm volatile ("xchgb %b0, %h0\n"
+                  "movw %w0, %1\n"
+                  : "=q" (v)
+                  : "m" (*(uint16_t *)ptr), "0" (v));
+#else
+    uint8_t *d = (uint8_t *) ptr;
+    d[0] = v >> 8;
+    d[1] = v;
+#endif
+}
+
+static inline void stl_raw(void *ptr, int v)
+{
+#if defined(__i386__) || defined(__x86_64__)
+    asm volatile ("bswap %0\n"
+                  "movl %0, %1\n"
+                  : "=r" (v)
+                  : "m" (*(uint32_t *)ptr), "0" (v));
+#else
+    uint8_t *d = (uint8_t *) ptr;
+    d[0] = v >> 24;
+    d[1] = v >> 16;
+    d[2] = v >> 8;
+    d[3] = v;
+#endif
+}
+
+static inline void stq_raw(void *ptr, uint64_t v)
+{
+    stl_raw(ptr, v >> 32);
+    stl_raw(ptr + 4, v);
+}
+
+/* float access */
+
+static inline float ldfl_raw(void *ptr)
+{
+    union {
+        float f;
+        uint32_t i;
+    } u;
+    u.i = ldl_raw(ptr);
+    return u.f;
+}
+
+static inline void stfl_raw(void *ptr, float v)
+{
+    union {
+        float f;
+        uint32_t i;
+    } u;
+    u.f = v;
+    stl_raw(ptr, u.i);
+}
+
+static inline double ldfq_raw(void *ptr)
+{
+    CPU_DoubleU u;
+    u.l.upper = ldl_raw(ptr);
+    u.l.lower = ldl_raw(ptr + 4);
+    return u.d;
+}
+
+static inline void stfq_raw(void *ptr, double v)
+{
+    CPU_DoubleU u;
+    u.d = v;
+    stl_raw(ptr, u.l.upper);
+    stl_raw(ptr + 4, u.l.lower);
+}
+
+#else
+
+static inline int lduw_raw(void *ptr)
+{
+    return *(uint16_t *)ptr;
+}
+
+static inline int ldsw_raw(void *ptr)
+{
+    return *(int16_t *)ptr;
+}
+
+static inline int ldl_raw(void *ptr)
+{
+    return *(uint32_t *)ptr;
+}
+
+static inline uint64_t ldq_raw(void *ptr)
+{
+    return *(uint64_t *)ptr;
+}
+
+static inline void stw_raw(void *ptr, int v)
+{
+    *(uint16_t *)ptr = v;
+}
+
+static inline void stl_raw(void *ptr, int v)
+{
+    *(uint32_t *)ptr = v;
+}
+
+static inline void stq_raw(void *ptr, uint64_t v)
+{
+    *(uint64_t *)ptr = v;
+}
+
+/* float access */
+
+static inline float ldfl_raw(void *ptr)
+{
+    return *(float *)ptr;
+}
+
+static inline double ldfq_raw(void *ptr)
+{
+    return *(double *)ptr;
+}
+
+static inline void stfl_raw(void *ptr, float v)
+{
+    *(float *)ptr = v;
+}
+
+static inline void stfq_raw(void *ptr, double v)
+{
+    *(double *)ptr = v;
+}
+#endif
+
+/* MMU memory access macros */
+
+#if defined(CONFIG_USER_ONLY) 
+
+/* if user mode, no other memory access functions */
+#define ldub(p) ldub_raw(p)
+#define ldsb(p) ldsb_raw(p)
+#define lduw(p) lduw_raw(p)
+#define ldsw(p) ldsw_raw(p)
+#define ldl(p) ldl_raw(p)
+#define ldq(p) ldq_raw(p)
+#define ldfl(p) ldfl_raw(p)
+#define ldfq(p) ldfq_raw(p)
+#define stb(p, v) stb_raw(p, v)
+#define stw(p, v) stw_raw(p, v)
+#define stl(p, v) stl_raw(p, v)
+#define stq(p, v) stq_raw(p, v)
+#define stfl(p, v) stfl_raw(p, v)
+#define stfq(p, v) stfq_raw(p, v)
+
+#define ldub_code(p) ldub_raw(p)
+#define ldsb_code(p) ldsb_raw(p)
+#define lduw_code(p) lduw_raw(p)
+#define ldsw_code(p) ldsw_raw(p)
+#define ldl_code(p) ldl_raw(p)
+
+#define ldub_kernel(p) ldub_raw(p)
+#define ldsb_kernel(p) ldsb_raw(p)
+#define lduw_kernel(p) lduw_raw(p)
+#define ldsw_kernel(p) ldsw_raw(p)
+#define ldl_kernel(p) ldl_raw(p)
+#define ldfl_kernel(p) ldfl_raw(p)
+#define ldfq_kernel(p) ldfq_raw(p)
+#define stb_kernel(p, v) stb_raw(p, v)
+#define stw_kernel(p, v) stw_raw(p, v)
+#define stl_kernel(p, v) stl_raw(p, v)
+#define stq_kernel(p, v) stq_raw(p, v)
+#define stfl_kernel(p, v) stfl_raw(p, v)
+#define stfq_kernel(p, vt) stfq_raw(p, v)
+
+#endif /* defined(CONFIG_USER_ONLY) */
+
+/* page related stuff */
+
+#define TARGET_PAGE_SIZE (1 << TARGET_PAGE_BITS)
+#define TARGET_PAGE_MASK ~(TARGET_PAGE_SIZE - 1)
+#define TARGET_PAGE_ALIGN(addr) (((addr) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK)
+
+extern unsigned long qemu_real_host_page_size;
+extern unsigned long qemu_host_page_bits;
+extern unsigned long qemu_host_page_size;
+extern unsigned long qemu_host_page_mask;
+
+#define HOST_PAGE_ALIGN(addr) (((addr) + qemu_host_page_size - 1) & qemu_host_page_mask)
+
+/* same as PROT_xxx */
+#define PAGE_READ      0x0001
+#define PAGE_WRITE     0x0002
+#define PAGE_EXEC      0x0004
+#define PAGE_BITS      (PAGE_READ | PAGE_WRITE | PAGE_EXEC)
+#define PAGE_VALID     0x0008
+/* original state of the write flag (used when tracking self-modifying
+   code */
+#define PAGE_WRITE_ORG 0x0010 
+
+void page_dump(FILE *f);
+int page_get_flags(unsigned long address);
+void page_set_flags(unsigned long start, unsigned long end, int flags);
+void page_unprotect_range(uint8_t *data, unsigned long data_size);
+
+#define CPUState CPUX86State
+
+void cpu_dump_state(CPUState *env, FILE *f, 
+                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
+                    int flags);
+
+void cpu_abort(CPUState *env, const char *fmt, ...);
+extern CPUState *cpu_single_env;
+extern int code_copy_enabled;
+
+#define CPU_INTERRUPT_EXIT   0x01 /* wants exit from main loop */
+#define CPU_INTERRUPT_HARD   0x02 /* hardware interrupt pending */
+#define CPU_INTERRUPT_EXITTB 0x04 /* exit the current TB (use for x86 a20 case) */
+#define CPU_INTERRUPT_TIMER  0x08 /* internal timer exception pending */
+void cpu_interrupt(CPUState *s, int mask);
+void cpu_reset_interrupt(CPUState *env, int mask);
+
+int cpu_breakpoint_insert(CPUState *env, target_ulong pc);
+int cpu_breakpoint_remove(CPUState *env, target_ulong pc);
+void cpu_single_step(CPUState *env, int enabled);
+void cpu_reset(CPUState *s);
+CPUState *cpu_init(void);
+int main_loop(void);
+
+/* Return the physical page corresponding to a virtual one. Use it
+   only for debugging because no protection checks are done. Return -1
+   if no page found. */
+target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr);
+
+#define CPU_LOG_TB_OUT_ASM (1 << 0) 
+#define CPU_LOG_TB_IN_ASM  (1 << 1)
+#define CPU_LOG_TB_OP      (1 << 2)
+#define CPU_LOG_TB_OP_OPT  (1 << 3)
+#define CPU_LOG_INT        (1 << 4)
+#define CPU_LOG_EXEC       (1 << 5)
+#define CPU_LOG_PCALL      (1 << 6)
+#define CPU_LOG_IOPORT     (1 << 7)
+#define CPU_LOG_TB_CPU     (1 << 8)
+
+/* define log items */
+typedef struct CPULogItem {
+    int mask;
+    const char *name;
+    const char *help;
+} CPULogItem;
+
+extern CPULogItem cpu_log_items[];
+
+void cpu_set_log(int log_flags);
+void cpu_set_log_filename(const char *filename);
+int cpu_str_to_log_mask(const char *str);
+
+/* IO ports API */
+
+/* NOTE: as these functions may be even used when there is an isa
+   brige on non x86 targets, we always defined them */
+#ifndef NO_CPU_IO_DEFS
+void cpu_outb(CPUState *env, int addr, int val);
+void cpu_outw(CPUState *env, int addr, int val);
+void cpu_outl(CPUState *env, int addr, int val);
+int cpu_inb(CPUState *env, int addr);
+int cpu_inw(CPUState *env, int addr);
+int cpu_inl(CPUState *env, int addr);
+#endif
+
+/* memory API */
+
+extern int phys_ram_size;
+extern int phys_ram_fd;
+extern uint8_t *phys_ram_base;
+extern uint8_t *phys_ram_dirty;
+
+/* physical memory access */
+#define IO_MEM_NB_ENTRIES  256
+#define TLB_INVALID_MASK   (1 << 3)
+#define IO_MEM_SHIFT       4
+
+#define IO_MEM_RAM         (0 << IO_MEM_SHIFT) /* hardcoded offset */
+#define IO_MEM_ROM         (1 << IO_MEM_SHIFT) /* hardcoded offset */
+#define IO_MEM_UNASSIGNED  (2 << IO_MEM_SHIFT)
+#define IO_MEM_CODE        (3 << IO_MEM_SHIFT) /* used internally, never use directly */
+#define IO_MEM_NOTDIRTY    (4 << IO_MEM_SHIFT) /* used internally, never use directly */
+
+typedef void CPUWriteMemoryFunc(void *opaque, target_phys_addr_t addr, uint32_t value);
+typedef uint32_t CPUReadMemoryFunc(void *opaque, target_phys_addr_t addr);
+
+void cpu_register_physical_memory(target_phys_addr_t start_addr, 
+                                  unsigned long size,
+                                  unsigned long phys_offset);
+int cpu_register_io_memory(int io_index,
+                           CPUReadMemoryFunc **mem_read,
+                           CPUWriteMemoryFunc **mem_write,
+                           void *opaque);
+CPUWriteMemoryFunc **cpu_get_io_memory_write(int io_index);
+CPUReadMemoryFunc **cpu_get_io_memory_read(int io_index);
+
+void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
+                            int len, int is_write);
+static inline void cpu_physical_memory_read(target_phys_addr_t addr, 
+                                            uint8_t *buf, int len)
+{
+    cpu_physical_memory_rw(addr, buf, len, 0);
+}
+static inline void cpu_physical_memory_write(target_phys_addr_t addr, 
+                                             const uint8_t *buf, int len)
+{
+    cpu_physical_memory_rw(addr, (uint8_t *)buf, len, 1);
+}
+
+int cpu_memory_rw_debug(CPUState *env, target_ulong addr, 
+                        uint8_t *buf, int len, int is_write);
+
+/* read dirty bit (return 0 or 1) */
+static inline int cpu_physical_memory_is_dirty(target_ulong addr)
+{
+    return phys_ram_dirty[addr >> TARGET_PAGE_BITS];
+}
+
+static inline void cpu_physical_memory_set_dirty(target_ulong addr)
+{
+    phys_ram_dirty[addr >> TARGET_PAGE_BITS] = 1;
+}
+
+void cpu_physical_memory_reset_dirty(target_ulong start, target_ulong end);
+
+#endif /* CPU_ALL_H */
diff --git a/tools/ioemu/cpu-defs.h b/tools/ioemu/cpu-defs.h
new file mode 100644 (file)
index 0000000..388d4ab
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * common defines for all CPUs
+ * 
+ * Copyright (c) 2003 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef CPU_DEFS_H
+#define CPU_DEFS_H
+
+#include "config.h"
+#include <setjmp.h>
+#include <inttypes.h>
+#include "osdep.h"
+
+#ifndef TARGET_LONG_BITS
+#error TARGET_LONG_BITS must be defined before including this header
+#endif
+
+#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
+#define HOST_LONG_BITS 64
+#else
+#define HOST_LONG_BITS 32
+#endif
+
+#ifndef TARGET_PHYS_ADDR_BITS 
+#if TARGET_LONG_BITS >= HOST_LONG_BITS
+#define TARGET_PHYS_ADDR_BITS TARGET_LONG_BITS
+#else
+#define TARGET_PHYS_ADDR_BITS HOST_LONG_BITS
+#endif
+#endif
+
+#define TARGET_LONG_SIZE (TARGET_LONG_BITS / 8)
+
+/* target_ulong is the type of a virtual address */
+#if TARGET_LONG_SIZE == 4
+typedef int32_t target_long;
+typedef uint32_t target_ulong;
+#elif TARGET_LONG_SIZE == 8
+typedef int64_t target_long;
+typedef uint64_t target_ulong;
+#else
+#error TARGET_LONG_SIZE undefined
+#endif
+
+/* target_phys_addr_t is the type of a physical address (its size can
+   be different from 'target_ulong'). We have sizeof(target_phys_addr)
+   = max(sizeof(unsigned long),
+   sizeof(size_of_target_physical_address)) because we must pass a
+   host pointer to memory operations in some cases */
+
+#if TARGET_PHYS_ADDR_BITS == 32
+typedef uint32_t target_phys_addr_t;
+#elif TARGET_PHYS_ADDR_BITS == 64
+typedef uint64_t target_phys_addr_t;
+#else
+#error TARGET_PHYS_ADDR_BITS undefined
+#endif
+
+#define HOST_LONG_SIZE (HOST_LONG_BITS / 8)
+
+#define EXCP_INTERRUPT         256 /* async interruption */
+#define EXCP_HLT        257 /* hlt instruction reached */
+#define EXCP_DEBUG      258 /* cpu stopped after a breakpoint or singlestep */
+
+#define MAX_BREAKPOINTS 32
+
+#define CPU_TLB_SIZE 256
+
+typedef struct CPUTLBEntry {
+    /* bit 31 to TARGET_PAGE_BITS : virtual address 
+       bit TARGET_PAGE_BITS-1..IO_MEM_SHIFT : if non zero, memory io
+                                              zone number
+       bit 3                      : indicates that the entry is invalid
+       bit 2..0                   : zero
+    */
+    target_ulong address; 
+    /* addend to virtual address to get physical address */
+    target_phys_addr_t addend; 
+} CPUTLBEntry;
+
+#endif
diff --git a/tools/ioemu/cpu.h b/tools/ioemu/cpu.h
new file mode 100644 (file)
index 0000000..adeb5bd
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * i386 virtual CPU header
+ * 
+ *  Copyright (c) 2003 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef CPU_I386_H
+#define CPU_I386_H
+
+#include "config.h"
+
+#ifdef TARGET_X86_64
+#define TARGET_LONG_BITS 64
+#else
+#define TARGET_LONG_BITS 32
+#endif
+
+/* target supports implicit self modifying code */
+#define TARGET_HAS_SMC
+/* support for self modifying code even if the modified instruction is
+   close to the modifying instruction */
+#define TARGET_HAS_PRECISE_SMC
+
+#include "cpu-defs.h"
+
+#if defined(__i386__) && !defined(CONFIG_SOFTMMU)
+#define USE_CODE_COPY
+#endif
+
+/* Empty for now */
+typedef struct CPUX86State {
+    uint32_t a20_mask;
+    int interrupt_request;
+    int send_event;
+} CPUX86State;
+
+#ifndef IN_OP_I386
+void cpu_x86_outb(CPUX86State *env, int addr, int val);
+void cpu_x86_outw(CPUX86State *env, int addr, int val);
+void cpu_x86_outl(CPUX86State *env, int addr, int val);
+int cpu_x86_inb(CPUX86State *env, int addr);
+int cpu_x86_inw(CPUX86State *env, int addr);
+int cpu_x86_inl(CPUX86State *env, int addr);
+#endif
+
+CPUX86State *cpu_x86_init(void);
+int cpu_x86_exec(CPUX86State *s);
+void cpu_x86_close(CPUX86State *s);
+int cpu_get_pic_interrupt(CPUX86State *s);
+/* MSDOS compatibility mode FPU exception support */
+void cpu_set_ferr(CPUX86State *s);
+
+#define TARGET_PAGE_BITS 12
+#include "cpu-all.h"
+
+#endif /* CPU_I386_H */
diff --git a/tools/ioemu/create_keysym_header.sh b/tools/ioemu/create_keysym_header.sh
new file mode 100644 (file)
index 0000000..87b05e0
--- /dev/null
@@ -0,0 +1,77 @@
+#!/bin/sh
+
+# QEMU keysym adapter: create a header file to link the name to its keysym
+#
+# Copyright (c) 2004,2005 Johannes E. Schindelin
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+type="$1"
+cflags="$2"
+if [ -z "$cflags" ]; then
+       echo "Usage: $0 vnc|sdl cflags"
+       exit 1
+fi
+
+
+case "$type" in
+vnc)
+       ignore_case=''
+       header=rfb/keysym.h
+       keysym_t=rfbKeySym
+       pattern='^#define[      ]*XK_\([^       ]*\)[   ].*$'
+       replacement='#ifdef XK_\1\n{\"\1\", XK_\1},\n#endif'
+       extra_replace='cat'
+       extra_sort='cat'
+       ;;
+sdl)
+       ignore_case='-f'
+       header=SDL_keysym.h
+       keysym_t=int
+       pattern='^[     ]*SDLK_\([^     ]*\)[   ]*=.*$'
+       replacement='{\"\1\", SDLK_\1},'
+       extra_replace='sed -e s/{"\([RL]\)\(SUPER\|META\|ALT\|CONTROL\|SHIFT\)/{"\2_\1/ -e s/{"\([RL]\)CTRL/{"CONTROL_\1/ -e s/{"\(PAGE\)\(UP\|DOWN\)/{"\1_\2/ -e s/{"\(KP\)\([0-9]\)/{"\1_\2/ -e s/{"KP_MINUS/{"KP_SUBTRACT/ -e s/{"KP_PLUS/{"KP_ADD/ -e s/{"KP_PERIOD/{"KP_DECIMAL/ -e s/{"\(LEFT\|RIGHT\)\(PAREN\|BRACKET\)/{"\2\1/ -e s/{"EXCLAIM/{"EXCLAM/ -e s/{"\(CAPS\|NUM\)\(LOCK\)/{"\1_\2/ -e s/{"SCROLLOCK/{"SCROLL_LOCK/ -e s/{"KP_EQUALS/{"KP_EQUAL/ -e s/{"SYSREQ/{"SYS_REQ/ -e s/{"QUOTE"/{"APOSTROPHE"/ -e s/{"BACKQUOTE/{"GRAVE/ -e s/{"EQUALS/{"EQUAL/ -e s/{"EURO/{"EUROSIGN/ -e s/{"COMPOSE/{"MULTI_KEY/ -e s/{"MODE/{"MODE_SWITCH/ -e s/{"HASH/{"NUMBERSIGN/ -e s/{"WORLD_68/{"ADIAERESIS/ -e s/{"WORLD_86/{"ODIAERESIS/ -e s/{"WORLD_92/{"UDIAERESIS/ -e s/{"WORLD_63/{"SSHARP/ -e s/{"WORLD_20/{"ACUTE/ -e s/{"CARET/{"ASCIICIRCUM/'
+       extra_sort='sort -f'
+       ;;
+*) echo "Unknown type: $type is neither vnc nor sdl"; exit 1;;
+esac
+
+outfile=keysym_adapter_"$type".h
+
+echo "typedef struct {" > $outfile
+echo " const char* name;" >> $outfile
+echo " $keysym_t keysym;" >> $outfile
+echo "} name2keysym_t;" >> $outfile
+echo "static name2keysym_t name2keysym[]={" >> $outfile
+
+for path in $(echo "$cflags" | sed "s/-I/ /g"); do
+       if [ -f $path/$header ]; then
+               cat $path/$header
+       fi
+done | tr "\011" " " | LC_ALL=C sort $ignore_case | uniq | \
+sed -n -e "s/$pattern/$replacement/p" | $extra_replace | \
+LC_ALL=C $extra_sort >> $outfile
+
+echo "{0,0}};" >> $outfile
+
+if [ -n "$ignore_case" ]; then
+echo "#define KEYBOARD_IGNORE_CASE" >> $outfile
+fi
+
+
diff --git a/tools/ioemu/exec-all.h b/tools/ioemu/exec-all.h
new file mode 100644 (file)
index 0000000..ac05339
--- /dev/null
@@ -0,0 +1,579 @@
+/*
+ * internal execution defines for qemu
+ * 
+ *  Copyright (c) 2003 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/* allow to see translation results - the slowdown should be negligible, so we leave it */
+#define DEBUG_DISAS
+
+#ifndef glue
+#define xglue(x, y) x ## y
+#define glue(x, y) xglue(x, y)
+#define stringify(s)   tostring(s)
+#define tostring(s)    #s
+#endif
+
+#if GCC_MAJOR < 3
+#define __builtin_expect(x, n) (x)
+#endif
+
+#ifdef __i386__
+#define REGPARM(n) __attribute((regparm(n)))
+#else
+#define REGPARM(n)
+#endif
+
+/* is_jmp field values */
+#define DISAS_NEXT    0 /* next instruction can be analyzed */
+#define DISAS_JUMP    1 /* only pc was modified dynamically */
+#define DISAS_UPDATE  2 /* cpu state was modified dynamically */
+#define DISAS_TB_JUMP 3 /* only pc was modified statically */
+
+struct TranslationBlock;
+
+/* XXX: make safe guess about sizes */
+#define MAX_OP_PER_INSTR 32
+#define OPC_BUF_SIZE 512
+#define OPC_MAX_SIZE (OPC_BUF_SIZE - MAX_OP_PER_INSTR)
+
+#define OPPARAM_BUF_SIZE (OPC_BUF_SIZE * 3)
+
+extern uint16_t gen_opc_buf[OPC_BUF_SIZE];
+extern uint32_t gen_opparam_buf[OPPARAM_BUF_SIZE];
+extern uint32_t gen_opc_pc[OPC_BUF_SIZE];
+extern uint32_t gen_opc_npc[OPC_BUF_SIZE];
+extern uint8_t gen_opc_cc_op[OPC_BUF_SIZE];
+extern uint8_t gen_opc_instr_start[OPC_BUF_SIZE];
+
+typedef void (GenOpFunc)(void);
+typedef void (GenOpFunc1)(long);
+typedef void (GenOpFunc2)(long, long);
+typedef void (GenOpFunc3)(long, long, long);
+                    
+#if defined(TARGET_I386)
+
+void optimize_flags_init(void);
+
+#endif
+
+extern FILE *logfile;
+extern int loglevel;
+
+int gen_intermediate_code(CPUState *env, struct TranslationBlock *tb);
+int gen_intermediate_code_pc(CPUState *env, struct TranslationBlock *tb);
+void dump_ops(const uint16_t *opc_buf, const uint32_t *opparam_buf);
+int cpu_gen_code(CPUState *env, struct TranslationBlock *tb,
+                 int max_code_size, int *gen_code_size_ptr);
+int cpu_restore_state(struct TranslationBlock *tb, 
+                      CPUState *env, unsigned long searched_pc,
+                      void *puc);
+int cpu_gen_code_copy(CPUState *env, struct TranslationBlock *tb,
+                      int max_code_size, int *gen_code_size_ptr);
+int cpu_restore_state_copy(struct TranslationBlock *tb, 
+                           CPUState *env, unsigned long searched_pc,
+                           void *puc);
+void cpu_resume_from_signal(CPUState *env1, void *puc);
+void cpu_exec_init(void);
+int page_unprotect(unsigned long address, unsigned long pc, void *puc);
+void tb_invalidate_phys_page_range(target_ulong start, target_ulong end, 
+                                   int is_cpu_write_access);
+void tb_invalidate_page_range(target_ulong start, target_ulong end);
+void tlb_flush_page(CPUState *env, target_ulong addr);
+void tlb_flush(CPUState *env, int flush_global);
+int tlb_set_page(CPUState *env, target_ulong vaddr, 
+                 target_phys_addr_t paddr, int prot, 
+                 int is_user, int is_softmmu);
+
+#define CODE_GEN_MAX_SIZE        65536
+#define CODE_GEN_ALIGN           16 /* must be >= of the size of a icache line */
+
+#define CODE_GEN_HASH_BITS     15
+#define CODE_GEN_HASH_SIZE     (1 << CODE_GEN_HASH_BITS)
+
+#define CODE_GEN_PHYS_HASH_BITS     15
+#define CODE_GEN_PHYS_HASH_SIZE     (1 << CODE_GEN_PHYS_HASH_BITS)
+
+/* maximum total translate dcode allocated */
+
+/* NOTE: the translated code area cannot be too big because on some
+   archs the range of "fast" function calls is limited. Here is a
+   summary of the ranges:
+
+   i386  : signed 32 bits
+   arm   : signed 26 bits
+   ppc   : signed 24 bits
+   sparc : signed 32 bits
+   alpha : signed 23 bits
+*/
+
+#if defined(__alpha__)
+#define CODE_GEN_BUFFER_SIZE     (2 * 1024 * 1024)
+#elif defined(__powerpc__)
+#define CODE_GEN_BUFFER_SIZE     (6 * 1024 * 1024)
+#else
+#define CODE_GEN_BUFFER_SIZE     (8 * 1024 * 1024)
+#endif
+
+//#define CODE_GEN_BUFFER_SIZE     (128 * 1024)
+
+/* estimated block size for TB allocation */
+/* XXX: use a per code average code fragment size and modulate it
+   according to the host CPU */
+#if defined(CONFIG_SOFTMMU)
+#define CODE_GEN_AVG_BLOCK_SIZE 128
+#else
+#define CODE_GEN_AVG_BLOCK_SIZE 64
+#endif
+
+#define CODE_GEN_MAX_BLOCKS    (CODE_GEN_BUFFER_SIZE / CODE_GEN_AVG_BLOCK_SIZE)
+
+#if defined(__powerpc__) 
+#define USE_DIRECT_JUMP
+#endif
+#if defined(__i386__) && !defined(_WIN32)
+#define USE_DIRECT_JUMP
+#endif
+
+typedef struct TranslationBlock {
+    target_ulong pc;   /* simulated PC corresponding to this block (EIP + CS base) */
+    target_ulong cs_base; /* CS base for this block */
+    unsigned int flags; /* flags defining in which context the code was generated */
+    uint16_t size;      /* size of target code for this block (1 <=
+                           size <= TARGET_PAGE_SIZE) */
+    uint16_t cflags;    /* compile flags */
+#define CF_CODE_COPY   0x0001 /* block was generated in code copy mode */
+#define CF_TB_FP_USED  0x0002 /* fp ops are used in the TB */
+#define CF_FP_USED     0x0004 /* fp ops are used in the TB or in a chained TB */
+#define CF_SINGLE_INSN 0x0008 /* compile only a single instruction */
+
+    uint8_t *tc_ptr;    /* pointer to the translated code */
+    struct TranslationBlock *hash_next; /* next matching tb for virtual address */
+    /* next matching tb for physical address. */
+    struct TranslationBlock *phys_hash_next; 
+    /* first and second physical page containing code. The lower bit
+       of the pointer tells the index in page_next[] */
+    struct TranslationBlock *page_next[2]; 
+    target_ulong page_addr[2]; 
+
+    /* the following data are used to directly call another TB from
+       the code of this one. */
+    uint16_t tb_next_offset[2]; /* offset of original jump target */
+#ifdef USE_DIRECT_JUMP
+    uint16_t tb_jmp_offset[4]; /* offset of jump instruction */
+#else
+    uint32_t tb_next[2]; /* address of jump generated code */
+#endif
+    /* list of TBs jumping to this one. This is a circular list using
+       the two least significant bits of the pointers to tell what is
+       the next pointer: 0 = jmp_next[0], 1 = jmp_next[1], 2 =
+       jmp_first */
+    struct TranslationBlock *jmp_next[2]; 
+    struct TranslationBlock *jmp_first;
+} TranslationBlock;
+
+static inline unsigned int tb_hash_func(unsigned long pc)
+{
+    return pc & (CODE_GEN_HASH_SIZE - 1);
+}
+
+static inline unsigned int tb_phys_hash_func(unsigned long pc)
+{
+    return pc & (CODE_GEN_PHYS_HASH_SIZE - 1);
+}
+
+TranslationBlock *tb_alloc(unsigned long pc);
+void tb_flush(CPUState *env);
+void tb_link(TranslationBlock *tb);
+void tb_link_phys(TranslationBlock *tb, 
+                  target_ulong phys_pc, target_ulong phys_page2);
+
+extern TranslationBlock *tb_hash[CODE_GEN_HASH_SIZE];
+extern TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE];
+
+extern uint8_t code_gen_buffer[CODE_GEN_BUFFER_SIZE];
+extern uint8_t *code_gen_ptr;
+
+/* find a translation block in the translation cache. If not found,
+   return NULL and the pointer to the last element of the list in pptb */
+static inline TranslationBlock *tb_find(TranslationBlock ***pptb,
+                                        target_ulong pc, 
+                                        target_ulong cs_base,
+                                        unsigned int flags)
+{
+    TranslationBlock **ptb, *tb;
+    unsigned int h;
+    h = tb_hash_func(pc);
+    ptb = &tb_hash[h];
+    for(;;) {
+        tb = *ptb;
+        if (!tb)
+            break;
+        if (tb->pc == pc && tb->cs_base == cs_base && tb->flags == flags)
+            return tb;
+        ptb = &tb->hash_next;
+    }
+    *pptb = ptb;
+    return NULL;
+}
+
+
+#if defined(USE_DIRECT_JUMP)
+
+#if defined(__powerpc__)
+static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr)
+{
+    uint32_t val, *ptr;
+
+    /* patch the branch destination */
+    ptr = (uint32_t *)jmp_addr;
+    val = *ptr;
+    val = (val & ~0x03fffffc) | ((addr - jmp_addr) & 0x03fffffc);
+    *ptr = val;
+    /* flush icache */
+    asm volatile ("dcbst 0,%0" : : "r"(ptr) : "memory");
+    asm volatile ("sync" : : : "memory");
+    asm volatile ("icbi 0,%0" : : "r"(ptr) : "memory");
+    asm volatile ("sync" : : : "memory");
+    asm volatile ("isync" : : : "memory");
+}
+#elif defined(__i386__)
+static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr)
+{
+    /* patch the branch destination */
+    *(uint32_t *)jmp_addr = addr - (jmp_addr + 4);
+    /* no need to flush icache explicitely */
+}
+#endif
+
+static inline void tb_set_jmp_target(TranslationBlock *tb, 
+                                     int n, unsigned long addr)
+{
+    unsigned long offset;
+
+    offset = tb->tb_jmp_offset[n];
+    tb_set_jmp_target1((unsigned long)(tb->tc_ptr + offset), addr);
+    offset = tb->tb_jmp_offset[n + 2];
+    if (offset != 0xffff)
+        tb_set_jmp_target1((unsigned long)(tb->tc_ptr + offset), addr);
+}
+
+#else
+
+/* set the jump target */
+static inline void tb_set_jmp_target(TranslationBlock *tb, 
+                                     int n, unsigned long addr)
+{
+    tb->tb_next[n] = addr;
+}
+
+#endif
+
+static inline void tb_add_jump(TranslationBlock *tb, int n, 
+                               TranslationBlock *tb_next)
+{
+    /* NOTE: this test is only needed for thread safety */
+    if (!tb->jmp_next[n]) {
+        /* patch the native jump address */
+        tb_set_jmp_target(tb, n, (unsigned long)tb_next->tc_ptr);
+        
+        /* add in TB jmp circular list */
+        tb->jmp_next[n] = tb_next->jmp_first;
+        tb_next->jmp_first = (TranslationBlock *)((long)(tb) | (n));
+    }
+}
+
+TranslationBlock *tb_find_pc(unsigned long pc_ptr);
+
+#ifndef offsetof
+#define offsetof(type, field) ((size_t) &((type *)0)->field)
+#endif
+
+#if defined(_WIN32)
+#define ASM_DATA_SECTION ".section \".data\"\n"
+#define ASM_PREVIOUS_SECTION ".section .text\n"
+#elif defined(__APPLE__)
+#define ASM_DATA_SECTION ".data\n"
+#define ASM_PREVIOUS_SECTION ".text\n"
+#define ASM_NAME(x) "_" #x
+#else
+#define ASM_DATA_SECTION ".section \".data\"\n"
+#define ASM_PREVIOUS_SECTION ".previous\n"
+#define ASM_NAME(x) stringify(x)
+#endif
+
+#if defined(__powerpc__)
+
+/* we patch the jump instruction directly */
+#define JUMP_TB(opname, tbparam, n, eip)\
+do {\
+    asm volatile (ASM_DATA_SECTION\
+                 ASM_NAME(__op_label) #n "." ASM_NAME(opname) ":\n"\
+                 ".long 1f\n"\
+                 ASM_PREVIOUS_SECTION \
+                  "b " ASM_NAME(__op_jmp) #n "\n"\
+                 "1:\n");\
+    T0 = (long)(tbparam) + (n);\
+    EIP = eip;\
+    EXIT_TB();\
+} while (0)
+
+#define JUMP_TB2(opname, tbparam, n)\
+do {\
+    asm volatile ("b " ASM_NAME(__op_jmp) #n "\n");\
+} while (0)
+
+#elif defined(__i386__) && defined(USE_DIRECT_JUMP)
+
+/* we patch the jump instruction directly */
+#define JUMP_TB(opname, tbparam, n, eip)\
+do {\
+    asm volatile (".section .data\n"\
+                 ASM_NAME(__op_label) #n "." ASM_NAME(opname) ":\n"\
+                 ".long 1f\n"\
+                 ASM_PREVIOUS_SECTION \
+                  "jmp " ASM_NAME(__op_jmp) #n "\n"\
+                 "1:\n");\
+    T0 = (long)(tbparam) + (n);\
+    EIP = eip;\
+    EXIT_TB();\
+} while (0)
+
+#define JUMP_TB2(opname, tbparam, n)\
+do {\
+    asm volatile ("jmp " ASM_NAME(__op_jmp) #n "\n");\
+} while (0)
+
+#else
+
+/* jump to next block operations (more portable code, does not need
+   cache flushing, but slower because of indirect jump) */
+#define JUMP_TB(opname, tbparam, n, eip)\
+do {\
+    static void __attribute__((unused)) *__op_label ## n = &&label ## n;\
+    static void __attribute__((unused)) *dummy ## n = &&dummy_label ## n;\
+    goto *(void *)(((TranslationBlock *)tbparam)->tb_next[n]);\
+label ## n:\
+    T0 = (long)(tbparam) + (n);\
+    EIP = eip;\
+dummy_label ## n:\
+    EXIT_TB();\
+} while (0)
+
+/* second jump to same destination 'n' */
+#define JUMP_TB2(opname, tbparam, n)\
+do {\
+    goto *(void *)(((TranslationBlock *)tbparam)->tb_next[n - 2]);\
+} while (0)
+
+#endif
+
+extern CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
+extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
+extern void *io_mem_opaque[IO_MEM_NB_ENTRIES];
+
+#ifdef __powerpc__
+static inline int testandset (int *p)
+{
+    int ret;
+    __asm__ __volatile__ (
+                          "0:    lwarx %0,0,%1\n"
+                          "      xor. %0,%3,%0\n"
+                          "      bne 1f\n"
+                          "      stwcx. %2,0,%1\n"
+                          "      bne- 0b\n"
+                          "1:    "
+                          : "=&r" (ret)
+                          : "r" (p), "r" (1), "r" (0)
+                          : "cr0", "memory");
+    return ret;
+}
+#endif
+
+#ifdef __i386__
+static inline int testandset (int *p)
+{
+    char ret;
+    long int readval;
+    
+    __asm__ __volatile__ ("lock; cmpxchgl %3, %1; sete %0"
+                          : "=q" (ret), "=m" (*p), "=a" (readval)
+                          : "r" (1), "m" (*p), "a" (0)
+                          : "memory");
+    return ret;
+}
+#endif
+
+#ifdef __x86_64__
+static inline int testandset (int *p)
+{
+    char ret;
+    int readval;
+    
+    __asm__ __volatile__ ("lock; cmpxchgl %3, %1; sete %0"
+                          : "=q" (ret), "=m" (*p), "=a" (readval)
+                          : "r" (1), "m" (*p), "a" (0)
+                          : "memory");
+    return ret;
+}
+#endif
+
+#ifdef __s390__
+static inline int testandset (int *p)
+{
+    int ret;
+
+    __asm__ __volatile__ ("0: cs    %0,%1,0(%2)\n"
+                         "   jl    0b"
+                         : "=&d" (ret)
+                         : "r" (1), "a" (p), "0" (*p) 
+                         : "cc", "memory" );
+    return ret;
+}
+#endif
+
+#ifdef __alpha__
+static inline int testandset (int *p)
+{
+    int ret;
+    unsigned long one;
+
+    __asm__ __volatile__ ("0:  mov 1,%2\n"
+                         "     ldl_l %0,%1\n"
+                         "     stl_c %2,%1\n"
+                         "     beq %2,1f\n"
+                         ".subsection 2\n"
+                         "1:   br 0b\n"
+                         ".previous"
+                         : "=r" (ret), "=m" (*p), "=r" (one)
+                         : "m" (*p));
+    return ret;
+}
+#endif
+
+#ifdef __sparc__
+static inline int testandset (int *p)
+{
+       int ret;
+
+       __asm__ __volatile__("ldstub    [%1], %0"
+                            : "=r" (ret)
+                            : "r" (p)
+                            : "memory");
+
+       return (ret ? 1 : 0);
+}
+#endif
+
+#ifdef __arm__
+static inline int testandset (int *spinlock)
+{
+    register unsigned int ret;
+    __asm__ __volatile__("swp %0, %1, [%2]"
+                         : "=r"(ret)
+                         : "0"(1), "r"(spinlock));
+    
+    return ret;
+}
+#endif
+
+#ifdef __mc68000
+static inline int testandset (int *p)
+{
+    char ret;
+    __asm__ __volatile__("tas %1; sne %0"
+                         : "=r" (ret)
+                         : "m" (p)
+                         : "cc","memory");
+    return ret == 0;
+}
+#endif
+
+typedef int spinlock_t;
+
+#define SPIN_LOCK_UNLOCKED 0
+
+#if defined(CONFIG_USER_ONLY)
+static inline void spin_lock(spinlock_t *lock)
+{
+    while (testandset(lock));
+}
+
+static inline void spin_unlock(spinlock_t *lock)
+{
+    *lock = 0;
+}
+
+static inline int spin_trylock(spinlock_t *lock)
+{
+    return !testandset(lock);
+}
+#else
+static inline void spin_lock(spinlock_t *lock)
+{
+}
+
+static inline void spin_unlock(spinlock_t *lock)
+{
+}
+
+static inline int spin_trylock(spinlock_t *lock)
+{
+    return 1;
+}
+#endif
+
+extern spinlock_t tb_lock;
+
+extern int tb_invalidated_flag;
+
+#if !defined(CONFIG_USER_ONLY)
+
+void tlb_fill(unsigned long addr, int is_write, int is_user, 
+              void *retaddr);
+
+#define ACCESS_TYPE 3
+#define MEMSUFFIX _code
+#define env cpu_single_env
+
+#undef ACCESS_TYPE
+#undef MEMSUFFIX
+#undef env
+
+#endif
+
+#if defined(CONFIG_USER_ONLY)
+static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr)
+{
+    return addr;
+}
+#else
+/* NOTE: this function can trigger an exception */
+/* NOTE2: the returned address is not exactly the physical address: it
+   is the offset relative to phys_ram_base */
+/* XXX: i386 target specific */
+static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr)
+{
+       return addr;
+}
+#endif
+
+//#define DEBUG_UNUSED_IOPORT
+//#define DEBUG_IOPORT
+#define TARGET_VMX
+
diff --git a/tools/ioemu/exec.c b/tools/ioemu/exec.c
new file mode 100644 (file)
index 0000000..c49975c
--- /dev/null
@@ -0,0 +1,461 @@
+/*
+ *  virtual page mapping and translated block handling
+ * 
+ *  Copyright (c) 2003 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include "config.h"
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <sys/types.h>
+#include <sys/mman.h>
+#endif
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <inttypes.h>
+
+#include "cpu.h"
+#include "exec-all.h"
+
+//#define DEBUG_TB_INVALIDATE
+//#define DEBUG_FLUSH
+//#define DEBUG_TLB
+
+/* make various TB consistency checks */
+//#define DEBUG_TB_CHECK 
+//#define DEBUG_TLB_CHECK 
+
+/* threshold to flush the translated code buffer */
+#define CODE_GEN_BUFFER_MAX_SIZE (CODE_GEN_BUFFER_SIZE - CODE_GEN_MAX_SIZE)
+
+#define SMC_BITMAP_USE_THRESHOLD 10
+
+#define MMAP_AREA_START        0x00000000
+#define MMAP_AREA_END          0xa8000000
+
+TranslationBlock tbs[CODE_GEN_MAX_BLOCKS];
+TranslationBlock *tb_hash[CODE_GEN_HASH_SIZE];
+TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE];
+int nb_tbs;
+/* any access to the tbs or the page table must use this lock */
+spinlock_t tb_lock = SPIN_LOCK_UNLOCKED;
+
+uint8_t code_gen_buffer[CODE_GEN_BUFFER_SIZE];
+uint8_t *code_gen_ptr;
+
+int phys_ram_size;
+int phys_ram_fd;
+uint8_t *phys_ram_base;
+uint8_t *phys_ram_dirty;
+
+typedef struct PageDesc {
+    /* list of TBs intersecting this ram page */
+    TranslationBlock *first_tb;
+    /* in order to optimize self modifying code, we count the number
+       of lookups we do to a given page to use a bitmap */
+    unsigned int code_write_count;
+    uint8_t *code_bitmap;
+#if defined(CONFIG_USER_ONLY)
+    unsigned long flags;
+#endif
+} PageDesc;
+
+typedef struct PhysPageDesc {
+    /* offset in host memory of the page + io_index in the low 12 bits */
+    unsigned long phys_offset;
+} PhysPageDesc;
+
+typedef struct VirtPageDesc {
+    /* physical address of code page. It is valid only if 'valid_tag'
+       matches 'virt_valid_tag' */ 
+    target_ulong phys_addr; 
+    unsigned int valid_tag;
+#if !defined(CONFIG_SOFTMMU)
+    /* original page access rights. It is valid only if 'valid_tag'
+       matches 'virt_valid_tag' */
+    unsigned int prot;
+#endif
+} VirtPageDesc;
+
+#define L2_BITS 10
+#define L1_BITS (32 - L2_BITS - TARGET_PAGE_BITS)
+
+#define L1_SIZE (1 << L1_BITS)
+#define L2_SIZE (1 << L2_BITS)
+
+unsigned long qemu_real_host_page_size;
+unsigned long qemu_host_page_bits;
+unsigned long qemu_host_page_size;
+unsigned long qemu_host_page_mask;
+
+/* io memory support */
+CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
+CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
+void *io_mem_opaque[IO_MEM_NB_ENTRIES];
+static int io_mem_nb = 1;
+
+/* log support */
+char *logfilename = "/tmp/qemu.log";
+FILE *logfile;
+int loglevel;
+
+void cpu_exec_init(void)
+{
+    /* alloc dirty bits array */
+    phys_ram_dirty = qemu_malloc(phys_ram_size >> TARGET_PAGE_BITS);
+}
+
+/* enable or disable low levels log */
+void cpu_set_log(int log_flags)
+{
+    loglevel = log_flags;
+    if (loglevel && !logfile) {
+        logfile = fopen(logfilename, "w");
+        if (!logfile) {
+            perror(logfilename);
+            _exit(1);
+        }
+#if !defined(CONFIG_SOFTMMU)
+        /* must avoid mmap() usage of glibc by setting a buffer "by hand" */
+        {
+            static uint8_t logfile_buf[4096];
+            setvbuf(logfile, logfile_buf, _IOLBF, sizeof(logfile_buf));
+        }
+#else
+        setvbuf(logfile, NULL, _IOLBF, 0);
+#endif
+    }
+}
+
+void cpu_set_log_filename(const char *filename)
+{
+    logfilename = strdup(filename);
+}
+
+/* mask must never be zero, except for A20 change call */
+void cpu_interrupt(CPUState *env, int mask)
+{
+    env->interrupt_request |= mask;
+}
+
+void cpu_reset_interrupt(CPUState *env, int mask)
+{
+    env->interrupt_request &= ~mask;
+}
+
+CPULogItem cpu_log_items[] = {
+    { CPU_LOG_TB_OUT_ASM, "out_asm", 
+      "show generated host assembly code for each compiled TB" },
+    { CPU_LOG_TB_IN_ASM, "in_asm",
+      "show target assembly code for each compiled TB" },
+    { CPU_LOG_TB_OP, "op", 
+      "show micro ops for each compiled TB (only usable if 'in_asm' used)" },
+#ifdef TARGET_I386
+    { CPU_LOG_TB_OP_OPT, "op_opt",
+      "show micro ops after optimization for each compiled TB" },
+#endif
+    { CPU_LOG_INT, "int",
+      "show interrupts/exceptions in short format" },
+    { CPU_LOG_EXEC, "exec",
+      "show trace before each executed TB (lots of logs)" },
+    { CPU_LOG_TB_CPU, "cpu",
+      "show CPU state before bloc translation" },
+#ifdef TARGET_I386
+    { CPU_LOG_PCALL, "pcall",
+      "show protected mode far calls/returns/exceptions" },
+#endif
+#ifdef DEBUG_IOPORT
+    { CPU_LOG_IOPORT, "ioport",
+      "show all i/o ports accesses" },
+#endif
+    { 0, NULL, NULL },
+};
+
+static int cmp1(const char *s1, int n, const char *s2)
+{
+    if (strlen(s2) != n)
+        return 0;
+    return memcmp(s1, s2, n) == 0;
+}
+      
+/* takes a comma separated list of log masks. Return 0 if error. */
+int cpu_str_to_log_mask(const char *str)
+{
+    CPULogItem *item;
+    int mask;
+    const char *p, *p1;
+
+    p = str;
+    mask = 0;
+    for(;;) {
+        p1 = strchr(p, ',');
+        if (!p1)
+            p1 = p + strlen(p);
+       if(cmp1(p,p1-p,"all")) {
+               for(item = cpu_log_items; item->mask != 0; item++) {
+                       mask |= item->mask;
+               }
+       } else {
+        for(item = cpu_log_items; item->mask != 0; item++) {
+            if (cmp1(p, p1 - p, item->name))
+                goto found;
+        }
+        return 0;
+       }
+    found:
+        mask |= item->mask;
+        if (*p1 != ',')
+            break;
+        p = p1 + 1;
+    }
+    return mask;
+}
+
+void cpu_abort(CPUState *env, const char *fmt, ...)
+{
+    va_list ap;
+
+    va_start(ap, fmt);
+    fprintf(stderr, "qemu: fatal: ");
+    vfprintf(stderr, fmt, ap);
+    fprintf(stderr, "\n");
+    va_end(ap);
+    abort();
+}
+
+
+/* XXX: Simple implementation. Fix later */
+#define MAX_MMIO 32
+struct mmio_space {
+        target_phys_addr_t start;
+        unsigned long size;
+        unsigned long io_index;
+} mmio[MAX_MMIO];
+unsigned long mmio_cnt;
+
+/* register physical memory. 'size' must be a multiple of the target
+   page size. If (phys_offset & ~TARGET_PAGE_MASK) != 0, then it is an
+   io memory page */
+void cpu_register_physical_memory(target_phys_addr_t start_addr, 
+                                  unsigned long size,
+                                  unsigned long phys_offset)
+{
+        if (mmio_cnt == MAX_MMIO) {
+                fprintf(logfile, "too many mmio regions\n");
+                exit(-1);
+        }
+        mmio[mmio_cnt].io_index = phys_offset;
+        mmio[mmio_cnt].start = start_addr;
+        mmio[mmio_cnt++].size = size;
+}
+
+/* mem_read and mem_write are arrays of functions containing the
+   function to access byte (index 0), word (index 1) and dword (index
+   2). All functions must be supplied. If io_index is non zero, the
+   corresponding io zone is modified. If it is zero, a new io zone is
+   allocated. The return value can be used with
+   cpu_register_physical_memory(). (-1) is returned if error. */
+int cpu_register_io_memory(int io_index,
+                           CPUReadMemoryFunc **mem_read,
+                           CPUWriteMemoryFunc **mem_write,
+                           void *opaque)
+{
+    int i;
+
+    if (io_index <= 0) {
+        if (io_index >= IO_MEM_NB_ENTRIES)
+            return -1;
+        io_index = io_mem_nb++;
+    } else {
+        if (io_index >= IO_MEM_NB_ENTRIES)
+            return -1;
+    }
+
+    for(i = 0;i < 3; i++) {
+        io_mem_read[io_index][i] = mem_read[i];
+        io_mem_write[io_index][i] = mem_write[i];
+    }
+    io_mem_opaque[io_index] = opaque;
+    return io_index << IO_MEM_SHIFT;
+}
+
+CPUWriteMemoryFunc **cpu_get_io_memory_write(int io_index)
+{
+    return io_mem_write[io_index >> IO_MEM_SHIFT];
+}
+
+CPUReadMemoryFunc **cpu_get_io_memory_read(int io_index)
+{
+    return io_mem_read[io_index >> IO_MEM_SHIFT];
+}
+
+/* physical memory access (slow version, mainly for debug) */
+#if defined(CONFIG_USER_ONLY)
+void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, 
+                            int len, int is_write)
+{
+    int l, flags;
+    target_ulong page;
+
+    while (len > 0) {
+        page = addr & TARGET_PAGE_MASK;
+        l = (page + TARGET_PAGE_SIZE) - addr;
+        if (l > len)
+            l = len;
+        flags = page_get_flags(page);
+        if (!(flags & PAGE_VALID))
+            return;
+        if (is_write) {
+            if (!(flags & PAGE_WRITE))
+                return;
+            memcpy((uint8_t *)addr, buf, len);
+        } else {
+            if (!(flags & PAGE_READ))
+                return;
+            memcpy(buf, (uint8_t *)addr, len);
+        }
+        len -= l;
+        buf += l;
+        addr += l;
+    }
+}
+#else
+
+int iomem_index(target_phys_addr_t addr)
+{
+        int i;
+
+        for (i = 0; i < mmio_cnt; i++) {
+                unsigned long start, end;
+
+                start = mmio[i].start;
+                end = mmio[i].start + mmio[i].size;
+
+                if ((addr >= start) && (addr <= end)){
+                        return (mmio[i].io_index >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
+                }
+        }
+        return 0;
+}
+
+void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, 
+                            int len, int is_write)
+{
+    int l, io_index;
+    uint8_t *ptr;
+    uint32_t val;
+    target_phys_addr_t page;
+    unsigned long pd;
+    
+    while (len > 0) {
+        page = addr & TARGET_PAGE_MASK;
+        l = (page + TARGET_PAGE_SIZE) - addr;
+        if (l > len)
+            l = len;
+       
+        pd = page;
+        io_index = iomem_index(page);
+        if (is_write) {
+            if (io_index) {
+                if (l >= 4 && ((addr & 3) == 0)) {
+                    /* 32 bit read access */
+                    val = ldl_raw(buf);
+                    io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val);
+                    l = 4;
+                } else if (l >= 2 && ((addr & 1) == 0)) {
+                    /* 16 bit read access */
+                    val = lduw_raw(buf);
+                    io_mem_write[io_index][1](io_mem_opaque[io_index], addr, val);
+                    l = 2;
+                } else {
+                    /* 8 bit access */
+                    val = ldub_raw(buf);
+                    io_mem_write[io_index][0](io_mem_opaque[io_index], addr, val);
+                    l = 1;
+                }
+            } else {
+                unsigned long addr1;
+
+                addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
+                /* RAM case */
+                ptr = phys_ram_base + addr1;
+                memcpy(ptr, buf, l);
+            }
+        } else {
+            if (io_index) {
+                if (l >= 4 && ((addr & 3) == 0)) {
+                    /* 32 bit read access */
+                    val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr);
+                    stl_raw(buf, val);
+                    l = 4;
+                } else if (l >= 2 && ((addr & 1) == 0)) {
+                    /* 16 bit read access */
+                    val = io_mem_read[io_index][1](io_mem_opaque[io_index], addr);
+                    stw_raw(buf, val);
+                    l = 2;
+                } else {
+                    /* 8 bit access */
+                    val = io_mem_read[io_index][0](io_mem_opaque[io_index], addr);
+                    stb_raw(buf, val);
+                    l = 1;
+                }
+            } else {
+                /* RAM case */
+                ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) + 
+                    (addr & ~TARGET_PAGE_MASK);
+                memcpy(buf, ptr, l);
+            }
+        }
+        len -= l;
+        buf += l;
+        addr += l;
+    }
+}
+#endif
+
+/* virtual memory access for debug */
+int cpu_memory_rw_debug(CPUState *env, target_ulong addr, 
+                        uint8_t *buf, int len, int is_write)
+{
+    int l;
+    target_ulong page, phys_addr;
+
+    while (len > 0) {
+        page = addr & TARGET_PAGE_MASK;
+        phys_addr = cpu_get_phys_page_debug(env, page);
+        /* if no physical page mapped, return an error */
+        if (phys_addr == -1)
+            return -1;
+        l = (page + TARGET_PAGE_SIZE) - addr;
+        if (l > len)
+            l = len;
+        cpu_physical_memory_rw(phys_addr + (addr & ~TARGET_PAGE_MASK), 
+                               buf, l, is_write);
+        len -= l;
+        buf += l;
+        addr += l;
+    }
+    return 0;
+}
+
+void cpu_physical_memory_reset_dirty(target_ulong start, target_ulong end)
+{
+}
diff --git a/tools/ioemu/font/vga.bitmap.h b/tools/ioemu/font/vga.bitmap.h
deleted file mode 100644 (file)
index e82dd62..0000000
+++ /dev/null
@@ -1,288 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: vga.bitmap.h,v 1.4 2002/05/25 14:22:53 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-typedef struct {
-  unsigned char data[16];
-  } bx_fontcharbitmap_t;
-
-static const bx_fontcharbitmap_t bx_vgafont[256] = {
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xa5, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xdb, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x36, 0x7f, 0x7f, 0x7f, 0x7f, 0x3e, 0x1c, 0x08, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x08, 0x1c, 0x3e, 0x7f, 0x3e, 0x1c, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff }},
-{{ 0x00, 0x00, 0x78, 0x60, 0x70, 0x58, 0x1e, 0x33, 0x33, 0x33, 0x33, 0x1e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0xfc, 0xcc, 0xfc, 0x0c, 0x0c, 0x0c, 0x0c, 0x0e, 0x0f, 0x07, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0xfe, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xe6, 0xe7, 0x67, 0x03, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x7f, 0x1f, 0x0f, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x40, 0x60, 0x70, 0x78, 0x7c, 0x7f, 0x7c, 0x78, 0x70, 0x60, 0x40, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0xfe, 0xdb, 0xdb, 0xdb, 0xde, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x3e, 0x63, 0x06, 0x1c, 0x36, 0x63, 0x63, 0x36, 0x1c, 0x30, 0x63, 0x3e, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x7f, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x7f, 0x06, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x36, 0x7f, 0x36, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x08, 0x1c, 0x1c, 0x3e, 0x3e, 0x7f, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0x3e, 0x3e, 0x1c, 0x1c, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x36, 0x36, 0x7f, 0x36, 0x36, 0x36, 0x7f, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x18, 0x18, 0x3e, 0x63, 0x43, 0x03, 0x3e, 0x60, 0x60, 0x61, 0x63, 0x3e, 0x18, 0x18, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x43, 0x63, 0x30, 0x18, 0x0c, 0x06, 0x63, 0x61, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x1c, 0x36, 0x36, 0x1c, 0x6e, 0x3b, 0x33, 0x33, 0x33, 0x6e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x0c, 0x0c, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x0c, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x1c, 0x36, 0x63, 0x63, 0x6b, 0x6b, 0x63, 0x63, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x18, 0x1c, 0x1e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x3e, 0x63, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x63, 0x7f, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x3e, 0x63, 0x60, 0x60, 0x3c, 0x60, 0x60, 0x60, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x30, 0x38, 0x3c, 0x36, 0x33, 0x7f, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x7f, 0x03, 0x03, 0x03, 0x3f, 0x60, 0x60, 0x60, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x1c, 0x06, 0x03, 0x03, 0x3f, 0x63, 0x63, 0x63, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x7f, 0x63, 0x60, 0x60, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x3e, 0x63, 0x63, 0x63, 0x3e, 0x63, 0x63, 0x63, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x3e, 0x63, 0x63, 0x63, 0x7e, 0x60, 0x60, 0x60, 0x30, 0x1e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x3e, 0x63, 0x63, 0x30, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x3e, 0x63, 0x63, 0x7b, 0x7b, 0x7b, 0x3b, 0x03, 0x3e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x08, 0x1c, 0x36, 0x63, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x3f, 0x66, 0x66, 0x66, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x3f, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x3c, 0x66, 0x43, 0x03, 0x03, 0x03, 0x03, 0x43, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x1f, 0x36, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x36, 0x1f, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x7f, 0x66, 0x46, 0x16, 0x1e, 0x16, 0x06, 0x46, 0x66, 0x7f, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x7f, 0x66, 0x46, 0x16, 0x1e, 0x16, 0x06, 0x06, 0x06, 0x0f, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x3c, 0x66, 0x43, 0x03, 0x03, 0x7b, 0x63, 0x63, 0x66, 0x5c, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x63, 0x63, 0x63, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, 0x33, 0x33, 0x1e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x67, 0x66, 0x66, 0x36, 0x1e, 0x1e, 0x36, 0x66, 0x66, 0x67, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x0f, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7f, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x63, 0x77, 0x7f, 0x7f, 0x6b, 0x63, 0x63, 0x63, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x63, 0x67, 0x6f, 0x7f, 0x7b, 0x73, 0x63, 0x63, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x3e, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x3f, 0x66, 0x66, 0x66, 0x3e, 0x06, 0x06, 0x06, 0x06, 0x0f, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x3e, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x6b, 0x7b, 0x3e, 0x30, 0x70, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x3f, 0x66, 0x66, 0x66, 0x3e, 0x36, 0x66, 0x66, 0x66, 0x67, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x3e, 0x63, 0x63, 0x06, 0x1c, 0x30, 0x60, 0x63, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x36, 0x1c, 0x08, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x63, 0x63, 0x63, 0x63, 0x6b, 0x6b, 0x6b, 0x7f, 0x77, 0x36, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x63, 0x63, 0x36, 0x3e, 0x1c, 0x1c, 0x3e, 0x36, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x7f, 0x63, 0x61, 0x30, 0x18, 0x0c, 0x06, 0x43, 0x63, 0x7f, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0e, 0x1c, 0x38, 0x70, 0x60, 0x40, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x08, 0x1c, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00 }},
-{{ 0x0c, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x3e, 0x33, 0x33, 0x33, 0x6e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x07, 0x06, 0x06, 0x1e, 0x36, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x63, 0x03, 0x03, 0x03, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x38, 0x30, 0x30, 0x3c, 0x36, 0x33, 0x33, 0x33, 0x33, 0x6e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x63, 0x7f, 0x03, 0x03, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x1c, 0x36, 0x26, 0x06, 0x0f, 0x06, 0x06, 0x06, 0x06, 0x0f, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3e, 0x30, 0x33, 0x1e, 0x00 }},
-{{ 0x00, 0x00, 0x07, 0x06, 0x06, 0x36, 0x6e, 0x66, 0x66, 0x66, 0x66, 0x67, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x18, 0x18, 0x00, 0x1c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x60, 0x60, 0x00, 0x70, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x66, 0x3c, 0x00 }},
-{{ 0x00, 0x00, 0x07, 0x06, 0x06, 0x66, 0x36, 0x1e, 0x1e, 0x36, 0x66, 0x67, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x1c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x7f, 0x6b, 0x6b, 0x6b, 0x6b, 0x63, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x63, 0x63, 0x63, 0x63, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x06, 0x06, 0x0f, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3e, 0x30, 0x30, 0x78, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x6e, 0x66, 0x06, 0x06, 0x06, 0x0f, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x63, 0x06, 0x1c, 0x30, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x08, 0x0c, 0x0c, 0x3f, 0x0c, 0x0c, 0x0c, 0x0c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x6e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x6b, 0x6b, 0x6b, 0x7f, 0x36, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x36, 0x1c, 0x1c, 0x1c, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x7e, 0x60, 0x30, 0x1f, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x33, 0x18, 0x0c, 0x06, 0x63, 0x7f, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x6e, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x08, 0x1c, 0x36, 0x63, 0x63, 0x63, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x3c, 0x66, 0x43, 0x03, 0x03, 0x03, 0x43, 0x66, 0x3c, 0x30, 0x60, 0x3e, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x33, 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x6e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x30, 0x18, 0x0c, 0x00, 0x3e, 0x63, 0x7f, 0x03, 0x03, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x08, 0x1c, 0x36, 0x00, 0x1e, 0x30, 0x3e, 0x33, 0x33, 0x33, 0x6e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x33, 0x00, 0x00, 0x1e, 0x30, 0x3e, 0x33, 0x33, 0x33, 0x6e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x06, 0x0c, 0x18, 0x00, 0x1e, 0x30, 0x3e, 0x33, 0x33, 0x33, 0x6e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x1c, 0x36, 0x1c, 0x00, 0x1e, 0x30, 0x3e, 0x33, 0x33, 0x33, 0x6e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x06, 0x06, 0x66, 0x3c, 0x30, 0x60, 0x3c, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x08, 0x1c, 0x36, 0x00, 0x3e, 0x63, 0x7f, 0x03, 0x03, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x63, 0x00, 0x00, 0x3e, 0x63, 0x7f, 0x03, 0x03, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x06, 0x0c, 0x18, 0x00, 0x3e, 0x63, 0x7f, 0x03, 0x03, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x66, 0x00, 0x00, 0x1c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x18, 0x3c, 0x66, 0x00, 0x1c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x06, 0x0c, 0x18, 0x00, 0x1c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x63, 0x00, 0x08, 0x1c, 0x36, 0x63, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x1c, 0x36, 0x1c, 0x00, 0x1c, 0x36, 0x63, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x18, 0x0c, 0x06, 0x00, 0x7f, 0x66, 0x06, 0x3e, 0x06, 0x06, 0x66, 0x7f, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x6e, 0x6c, 0x7e, 0x1b, 0x1b, 0x76, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x7c, 0x36, 0x33, 0x33, 0x7f, 0x33, 0x33, 0x33, 0x33, 0x73, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x08, 0x1c, 0x36, 0x00, 0x3e, 0x63, 0x63, 0x63, 0x63, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x63, 0x00, 0x00, 0x3e, 0x63, 0x63, 0x63, 0x63, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x06, 0x0c, 0x18, 0x00, 0x3e, 0x63, 0x63, 0x63, 0x63, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x0c, 0x1e, 0x33, 0x00, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x6e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x06, 0x0c, 0x18, 0x00, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x6e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x63, 0x00, 0x00, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x7e, 0x60, 0x30, 0x1e, 0x00 }},
-{{ 0x00, 0x63, 0x00, 0x3e, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x63, 0x00, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x18, 0x18, 0x3c, 0x66, 0x06, 0x06, 0x06, 0x66, 0x3c, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x1c, 0x36, 0x26, 0x06, 0x0f, 0x06, 0x06, 0x06, 0x06, 0x67, 0x3f, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x1f, 0x33, 0x33, 0x1f, 0x23, 0x33, 0x7b, 0x33, 0x33, 0x33, 0x63, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x70, 0xd8, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1b, 0x0e, 0x00, 0x00 }},
-{{ 0x00, 0x18, 0x0c, 0x06, 0x00, 0x1e, 0x30, 0x3e, 0x33, 0x33, 0x33, 0x6e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x30, 0x18, 0x0c, 0x00, 0x1c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x18, 0x0c, 0x06, 0x00, 0x3e, 0x63, 0x63, 0x63, 0x63, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x18, 0x0c, 0x06, 0x00, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x6e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x6e, 0x3b, 0x00, 0x3b, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x6e, 0x3b, 0x00, 0x63, 0x67, 0x6f, 0x7f, 0x7b, 0x73, 0x63, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x3c, 0x36, 0x36, 0x7c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x1c, 0x36, 0x36, 0x1c, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x0c, 0x0c, 0x06, 0x03, 0x63, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x60, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x03, 0x03, 0x43, 0x63, 0x33, 0x18, 0x0c, 0x06, 0x3b, 0x61, 0x30, 0x18, 0x7c, 0x00, 0x00 }},
-{{ 0x00, 0x03, 0x03, 0x43, 0x63, 0x33, 0x18, 0x0c, 0x66, 0x73, 0x79, 0x7c, 0x60, 0x60, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x36, 0x1b, 0x36, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x36, 0x6c, 0x36, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22 }},
-{{ 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55 }},
-{{ 0xbb, 0xee, 0xbb, 0xee, 0xbb, 0xee, 0xbb, 0xee, 0xbb, 0xee, 0xbb, 0xee, 0xbb, 0xee, 0xbb, 0xee }},
-{{ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 }},
-{{ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 }},
-{{ 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 }},
-{{ 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6f, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 }},
-{{ 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6f, 0x60, 0x6f, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c }},
-{{ 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x60, 0x6f, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c }},
-{{ 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6f, 0x60, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 }},
-{{ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 }},
-{{ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 }},
-{{ 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 }},
-{{ 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0xec, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c }},
-{{ 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0xec, 0x0c, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0c, 0xec, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c }},
-{{ 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0xef, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xef, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c }},
-{{ 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0xec, 0x0c, 0xec, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0xef, 0x00, 0xef, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c }},
-{{ 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c }},
-{{ 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c }},
-{{ 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0xff, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c }},
-{{ 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 }},
-{{ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 }},
-{{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }},
-{{ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f }},
-{{ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0 }},
-{{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b, 0x1b, 0x1b, 0x3b, 0x6e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x1e, 0x33, 0x33, 0x33, 0x1b, 0x33, 0x63, 0x63, 0x63, 0x33, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x7f, 0x63, 0x63, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x7f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x7f, 0x63, 0x06, 0x0c, 0x18, 0x0c, 0x06, 0x63, 0x7f, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x0e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x06, 0x06, 0x03, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x1c, 0x36, 0x63, 0x63, 0x7f, 0x63, 0x63, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x1c, 0x36, 0x63, 0x63, 0x63, 0x36, 0x36, 0x36, 0x36, 0x77, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x78, 0x0c, 0x18, 0x30, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0xc0, 0x60, 0x7e, 0xdb, 0xdb, 0xcf, 0x7e, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x38, 0x0c, 0x06, 0x06, 0x3e, 0x06, 0x06, 0x06, 0x0c, 0x38, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x3e, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x70, 0xd8, 0xd8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 }},
-{{ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1b, 0x1b, 0x1b, 0x0e, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x00, 0x6e, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x1c, 0x36, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0xf0, 0x30, 0x30, 0x30, 0x30, 0x30, 0x37, 0x36, 0x36, 0x3c, 0x38, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x1b, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x0e, 0x1b, 0x0c, 0x06, 0x13, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }},
-};
diff --git a/tools/ioemu/gui/Makefile b/tools/ioemu/gui/Makefile
deleted file mode 100644 (file)
index e6ddc74..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-TOPDIR= ..
-CXXFLAGS=-I. -I../include -I..
-OBJS= gui.o keymap.o siminterface.o textconfig.o x.o rfb.o term.o
-
-all: libgui.a
-
-libgui.a: $(OBJS)
-       $(AR) $(ARFLAGS) $@ $(OBJS)
-
-include $(TOPDIR)/mk/helix.mk
-
-install:: all
diff --git a/tools/ioemu/gui/Makefile.in b/tools/ioemu/gui/Makefile.in
deleted file mode 100644 (file)
index c9fd865..0000000
+++ /dev/null
@@ -1,561 +0,0 @@
-# Copyright (C) 2002  MandrakeSoft S.A.
-#
-#   MandrakeSoft S.A.
-#   43, rue d'Aboukir
-#   75002 Paris - France
-#   http://www.linux-mandrake.com/
-#   http://www.mandrakesoft.com/
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-# Makefile for the gui component of bochs
-
-
-@SUFFIX_LINE@
-
-prefix          = @prefix@
-exec_prefix     = @exec_prefix@
-srcdir          = @srcdir@
-VPATH = @srcdir@
-bindir          = @bindir@
-libdir          = @libdir@
-mandir          = @mandir@
-man1dir         = $(mandir)/man1
-man5dir         = $(mandir)/man5
-docdir          = $(prefix)/share/doc/bochs
-sharedir        = $(prefix)/share/bochs
-top_builddir    = ..
-top_srcdir      = @top_srcdir@
-
-SHELL = /bin/sh
-
-@SET_MAKE@
-
-CXX = @CXX@
-CXXFLAGS = $(BX_INCDIRS) @CXXFLAGS@  @GUI_CXXFLAGS@
-LOCAL_CXXFLAGS =
-LDFLAGS = @LDFLAGS@
-LIBS = @LIBS@
-X_CFLAGS = @X_CFLAGS@
-RANLIB = @RANLIB@
-PLUGIN_PATH=@libdir@
-top_builddir    = ..
-LIBTOOL=@LIBTOOL@
-WIN32_DLL_IMPORT_LIBRARY=../dllexports.a
-BX_INCDIRS = -I.. -I$(srcdir)/.. -I../iodev -I$(srcdir)/../iodev -I../@INSTRUMENT_DIR@ -I$(srcdir)/../@INSTRUMENT_DIR@
-
-GUI_OBJS_X11  = x.o
-GUI_OBJS_SDL = sdl.o
-GUI_OBJS_SVGA = svga.o
-GUI_OBJS_BEOS = beos.o
-GUI_OBJS_WIN32 = win32.o
-GUI_OBJS_MACOS = macintosh.o
-GUI_OBJS_CARBON = carbon.o
-GUI_OBJS_NOGUI = nogui.o
-GUI_OBJS_TERM  = term.o
-GUI_OBJS_RFB = rfb.o
-GUI_OBJS_AMIGAOS = amigaos.o
-GUI_OBJS_WX = wx.o
-GUI_OBJS_WX_SUPPORT = wxmain.o wxdialog.o
-OBJS_THAT_CANNOT_BE_PLUGINS = keymap.o gui.o siminterface.o textconfig.o @DIALOG_OBJS@
-OBJS_THAT_CAN_BE_PLUGINS = @GUI_OBJS@
-
-X_LIBS = @X_LIBS@
-X_PRE_LIBS = @X_PRE_LIBS@
-GUI_LINK_OPTS_X = $(X_LIBS) $(X_PRE_LIBS) -lX11 -lXpm
-GUI_LINK_OPTS_SDL = `sdl-config --cflags --libs`
-GUI_LINK_OPTS_SVGA =  -lvga -lvgagl
-GUI_LINK_OPTS_BEOS = -lbe
-GUI_LINK_OPTS_RFB = @RFB_LIBS@
-GUI_LINK_OPTS_AMIGAOS = 
-GUI_LINK_OPTS_WIN32 = -luser32 -lgdi32 -lcomdlg32 -lcomctl32
-GUI_LINK_OPTS_WIN32_VCPP = user32.lib gdi32.lib winmm.lib \
-  comdlg32.lib comctl32.lib wsock32.lib
-GUI_LINK_OPTS_MACOS =
-GUI_LINK_OPTS_CARBON = -framework Carbon
-GUI_LINK_OPTS_NOGUI =
-GUI_LINK_OPTS_TERM = @GUI_LINK_OPTS_TERM@
-GUI_LINK_OPTS_WX = @GUI_LINK_OPTS_WX@
-GUI_LINK_OPTS = @GUI_LINK_OPTS@  @DEVICE_LINK_OPTS@
-
-NONPLUGIN_OBJS = @GUI_NON_PLUGIN_OBJS@
-PLUGIN_OBJS = @GUI_PLUGIN_OBJS@
-
-#
-# -------- end configurable options --------------------------
-#
-
-all: libgui.a 
-
-plugins: $(PLUGIN_OBJS:@PLUGIN_LIBNAME_TRANSFORMATION@)
-
-libgui.a: $(NONPLUGIN_OBJS)
-       @RMCOMMAND@ libgui.a
-       @MAKELIB@ $(NONPLUGIN_OBJS)
-       @RANLIB@ libgui.a
-
-# standard compile rule for C++ files
-.@CPP_SUFFIX@.o:
-       $(CXX) @DASH@c  $(CXXFLAGS) $(LOCAL_CXXFLAGS) @CXXFP@$< @OFP@$@
-
-##### building plugins with libtool
-%.lo: %.@CPP_SUFFIX@
-       $(LIBTOOL) --mode=compile $(CXX) -c $(CXXFLAGS) $(LOCAL_CXXFLAGS) $< -o $@
-
-libbx_%.la: %.lo
-       $(LIBTOOL) --mode=link $(CXX) -module $< -o $@ -rpath $(PLUGIN_PATH)
-
-libbx_x.la: x.lo
-       $(LIBTOOL) --mode=link $(CXX) -module $< -o $@ -rpath $(PLUGIN_PATH) $(GUI_LINK_OPTS_X)
-
-libbx_sdl.la: sdl.lo
-       $(LIBTOOL) --mode=link $(CXX) -module $< -o $@ -rpath $(PLUGIN_PATH) $(GUI_LINK_OPTS_SDL)
-
-libbx_svga.la: svga.lo
-       $(LIBTOOL) --mode=link $(CXX) -module $< -o $@ -rpath $(PLUGIN_PATH) $(GUI_LINK_OPTS_SVGA)
-
-libbx_beos.la: beos.lo
-       $(LIBTOOL) --mode=link $(CXX) -module $< -o $@ -rpath $(PLUGIN_PATH) $(GUI_LINK_OPTS_BEOS)
-
-libbx_rfb.la: rfb.lo
-       $(LIBTOOL) --mode=link $(CXX) -module $< -o $@ -rpath $(PLUGIN_PATH) $(GUI_LINK_OPTS_RFB)
-
-libbx_amigaos.la: amigaos.lo
-       $(LIBTOOL) --mode=link $(CXX) -module $< -o $@ -rpath $(PLUGIN_PATH) $(GUI_LINK_OPTS_AMIGAOS)
-
-libbx_win32.la: win32.lo
-       $(LIBTOOL) --mode=link $(CXX) -module $< -o $@ -rpath $(PLUGIN_PATH) $(GUI_LINK_OPTS_WIN32)
-
-libbx_macos.la: macos.lo
-       $(LIBTOOL) --mode=link $(CXX) -module $< -o $@ -rpath $(PLUGIN_PATH) $(GUI_LINK_OPTS_MACOS)
-
-libbx_carbon.la: carbon.lo
-       $(LIBTOOL) --mode=link $(CXX) -module $< -o $@ -rpath $(PLUGIN_PATH) $(GUI_LINK_OPTS_CARBON)
-
-libbx_nogui.la: nogui.lo
-       $(LIBTOOL) --mode=link $(CXX) -module $< -o $@ -rpath $(PLUGIN_PATH) $(GUI_LINK_OPTS_NOGUI)
-
-libbx_term.la: term.lo
-       $(LIBTOOL) --mode=link $(CXX) -module $< -o $@ -rpath $(PLUGIN_PATH) $(GUI_LINK_OPTS_TERM)
-
-# special link rules for plugins that require more than one object file
-libbx_wx.la: $(GUI_OBJS_WX:.o=.lo) $(GUI_OBJS_WX_SUPPORT:.o=.lo)
-       $(LIBTOOL) --mode=link $(CXX) -module $(GUI_OBJS_WX:.o=.lo) $(GUI_OBJS_WX_SUPPORT:.o=.lo) -o libbx_wx.la -rpath $(PLUGIN_PATH)  $(GUI_LINK_OPTS_WX)
-
-#### building DLLs for win32  (tested on cygwin only)
-bx_%.dll: %.o
-       $(CXX) $(CXXFLAGS) -shared -o $@ $< $(WIN32_DLL_IMPORT_LIBRARY)  $(GUI_LINK_OPTS_WIN32)
-
-bx_wx.dll: $(GUI_OBJS_WX) $(GUI_OBJS_WX_SUPPORT)
-       $(CXX) $(CXXFLAGS) -shared -o bx_wx.dll $(GUI_OBJS_WX) $(GUI_OBJS_WX_SUPPORT) $(WIN32_DLL_IMPORT_LIBRARY) `wx-config --libs` -luser32 -lgdi32 -lcomdlg32 -lcomctl32
-
-bx_sdl.dll: $(GUI_OBJS_SDL) 
-       $(CXX) $(CXXFLAGS) -shared -o bx_sdl.dll $(GUI_OBJS_SDL) $(WIN32_DLL_IMPORT_LIBRARY) $(GUI_LINK_OPTS_SDL)
-
-bx_rfb.dll: $(GUI_OBJS_RFB) 
-       $(CXX) $(CXXFLAGS) -shared -o bx_rfb.dll $(GUI_OBJS_RFB) $(WIN32_DLL_IMPORT_LIBRARY) $(GUI_LINK_OPTS_RFB)
-
-# no need to build DLLs for beos.o
-# no need to build DLLs for x.o
-
-##### end DLL section
-
-clean:
-       @RMCOMMAND@ -rf .libs *.la *.a *.lo *.o *.dll
-
-dist-clean: clean
-       @RMCOMMAND@ Makefile
-
-###########################################
-# all other dependencies generated by
-#  gcc -MM -I.. -I../instrument/stubs `wx-config --cxxflags` *.cc | 
-#     sed -e 's/\.cc/.@CPP_SUFFIX@/g'
-#  gcc -MM -I.. -I../instrument/stubs `wx-config --cxxflags` *.cc | \
-#     sed -e 's/\.cc/.@CPP_SUFFIX@/g' -e 's/\.o:/.lo:/g'
-#
-# This means that every source file is listed twice, once with a .o rule
-# and then again with an identical .lo rule.  The .lo rules are used when
-# building plugins.
-###########################################
-amigaos.o: amigaos.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h \
- ../bx_debug/debug.h ../bxversion.h ../gui/siminterface.h ../state_file.h \
- ../cpu/cpu.h ../cpu/lazy_flags.h ../cpu/i387.h ../memory/memory.h \
- ../pc_system.h ../plugin.h ../extplugin.h ../ltdl.h ../gui/gui.h \
- ../gui/textconfig.h ../gui/keymap.h ../iodev/iodev.h ../iodev/vga.h \
- ../iodev/biosdev.h ../iodev/cmos.h ../iodev/dma.h ../iodev/floppy.h \
- ../iodev/harddrv.h ../iodev/cdrom.h ../iodev/keyboard.h \
- ../iodev/parallel.h ../iodev/pic.h ../iodev/pit.h ../iodev/pit_wrap.h \
- ../iodev/pit82c54.h ../iodev/serial.h ../iodev/unmapped.h \
- ../iodev/eth.h ../iodev/ne2k.h ../iodev/guest2host.h \
- ../iodev/slowdown_timer.h ../instrument/stubs/instrument.h \
- icon_bochs.h amigagui.h
-beos.o: beos.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h ../bx_debug/debug.h \
- ../bxversion.h ../gui/siminterface.h ../state_file.h ../cpu/cpu.h \
- ../cpu/lazy_flags.h ../cpu/i387.h ../memory/memory.h ../pc_system.h \
- ../plugin.h ../extplugin.h ../ltdl.h ../gui/gui.h ../gui/textconfig.h \
- ../gui/keymap.h ../iodev/iodev.h ../iodev/vga.h ../iodev/biosdev.h \
- ../iodev/cmos.h ../iodev/dma.h ../iodev/floppy.h ../iodev/harddrv.h \
- ../iodev/cdrom.h ../iodev/keyboard.h ../iodev/parallel.h \
- ../iodev/pic.h ../iodev/pit.h ../iodev/pit_wrap.h ../iodev/pit82c54.h \
- ../iodev/serial.h ../iodev/unmapped.h ../iodev/eth.h ../iodev/ne2k.h \
- ../iodev/guest2host.h ../iodev/slowdown_timer.h \
- ../instrument/stubs/instrument.h ../font/vga.bitmap.h
-carbon.o: carbon.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h ../bx_debug/debug.h \
- ../bxversion.h ../gui/siminterface.h ../state_file.h ../cpu/cpu.h \
- ../cpu/lazy_flags.h ../cpu/i387.h ../memory/memory.h ../pc_system.h \
- ../plugin.h ../extplugin.h ../ltdl.h ../gui/gui.h ../gui/textconfig.h \
- ../gui/keymap.h ../iodev/iodev.h ../iodev/vga.h ../iodev/biosdev.h \
- ../iodev/cmos.h ../iodev/dma.h ../iodev/floppy.h ../iodev/harddrv.h \
- ../iodev/cdrom.h ../iodev/keyboard.h ../iodev/parallel.h \
- ../iodev/pic.h ../iodev/pit.h ../iodev/pit_wrap.h ../iodev/pit82c54.h \
- ../iodev/serial.h ../iodev/unmapped.h ../iodev/eth.h ../iodev/ne2k.h \
- ../iodev/guest2host.h ../iodev/slowdown_timer.h \
- ../instrument/stubs/instrument.h icon_bochs.h ../font/vga.bitmap.h
-gui.o: gui.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h ../bx_debug/debug.h \
- ../bxversion.h ../gui/siminterface.h ../state_file.h ../cpu/cpu.h \
- ../cpu/lazy_flags.h ../cpu/i387.h ../memory/memory.h ../pc_system.h \
- ../plugin.h ../extplugin.h ../ltdl.h ../gui/gui.h ../gui/textconfig.h \
- ../gui/keymap.h ../iodev/iodev.h ../iodev/vga.h ../iodev/biosdev.h \
- ../iodev/cmos.h ../iodev/dma.h ../iodev/floppy.h ../iodev/harddrv.h \
- ../iodev/cdrom.h ../iodev/keyboard.h ../iodev/parallel.h \
- ../iodev/pic.h ../iodev/pit.h ../iodev/pit_wrap.h ../iodev/pit82c54.h \
- ../iodev/serial.h ../iodev/unmapped.h ../iodev/eth.h ../iodev/ne2k.h \
- ../iodev/guest2host.h ../iodev/slowdown_timer.h \
- ../instrument/stubs/instrument.h ../gui/bitmaps/floppya.h \
- ../gui/bitmaps/floppyb.h ../gui/bitmaps/mouse.h \
- ../gui/bitmaps/reset.h ../gui/bitmaps/power.h \
- ../gui/bitmaps/snapshot.h ../gui/bitmaps/copy.h \
- ../gui/bitmaps/paste.h ../gui/bitmaps/configbutton.h \
- ../gui/bitmaps/cdromd.h ../gui/bitmaps/userbutton.h
-keymap.o: keymap.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h ../bx_debug/debug.h \
- ../bxversion.h ../gui/siminterface.h ../state_file.h ../cpu/cpu.h \
- ../cpu/lazy_flags.h ../cpu/i387.h ../memory/memory.h ../pc_system.h \
- ../plugin.h ../extplugin.h ../ltdl.h ../gui/gui.h ../gui/textconfig.h \
- ../gui/keymap.h ../iodev/iodev.h ../iodev/vga.h ../iodev/biosdev.h \
- ../iodev/cmos.h ../iodev/dma.h ../iodev/floppy.h ../iodev/harddrv.h \
- ../iodev/cdrom.h ../iodev/keyboard.h ../iodev/parallel.h \
- ../iodev/pic.h ../iodev/pit.h ../iodev/pit_wrap.h ../iodev/pit82c54.h \
- ../iodev/serial.h ../iodev/unmapped.h ../iodev/eth.h ../iodev/ne2k.h \
- ../iodev/guest2host.h ../iodev/slowdown_timer.h \
- ../instrument/stubs/instrument.h
-macintosh.o: macintosh.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h \
- ../bx_debug/debug.h ../bxversion.h ../gui/siminterface.h ../state_file.h \
- ../cpu/cpu.h ../cpu/lazy_flags.h ../cpu/i387.h ../memory/memory.h \
- ../pc_system.h ../plugin.h ../extplugin.h ../ltdl.h ../gui/gui.h \
- ../gui/textconfig.h ../gui/keymap.h ../iodev/iodev.h ../iodev/vga.h \
- ../iodev/biosdev.h ../iodev/cmos.h ../iodev/dma.h ../iodev/floppy.h \
- ../iodev/harddrv.h ../iodev/cdrom.h ../iodev/keyboard.h \
- ../iodev/parallel.h ../iodev/pic.h ../iodev/pit.h ../iodev/pit_wrap.h \
- ../iodev/pit82c54.h ../iodev/serial.h ../iodev/unmapped.h \
- ../iodev/eth.h ../iodev/ne2k.h ../iodev/guest2host.h \
- ../iodev/slowdown_timer.h ../instrument/stubs/instrument.h \
- icon_bochs.h ../font/vga.bitmap.h
-nogui.o: nogui.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h ../bx_debug/debug.h \
- ../bxversion.h ../gui/siminterface.h ../state_file.h ../cpu/cpu.h \
- ../cpu/lazy_flags.h ../cpu/i387.h ../memory/memory.h ../pc_system.h \
- ../plugin.h ../extplugin.h ../ltdl.h ../gui/gui.h ../gui/textconfig.h \
- ../gui/keymap.h ../iodev/iodev.h ../iodev/vga.h ../iodev/biosdev.h \
- ../iodev/cmos.h ../iodev/dma.h ../iodev/floppy.h ../iodev/harddrv.h \
- ../iodev/cdrom.h ../iodev/keyboard.h ../iodev/parallel.h \
- ../iodev/pic.h ../iodev/pit.h ../iodev/pit_wrap.h ../iodev/pit82c54.h \
- ../iodev/serial.h ../iodev/unmapped.h ../iodev/eth.h ../iodev/ne2k.h \
- ../iodev/guest2host.h ../iodev/slowdown_timer.h \
- ../instrument/stubs/instrument.h icon_bochs.h
-rfb.o: rfb.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h ../bx_debug/debug.h \
- ../bxversion.h ../gui/siminterface.h ../state_file.h ../cpu/cpu.h \
- ../cpu/lazy_flags.h ../cpu/i387.h ../memory/memory.h ../pc_system.h \
- ../plugin.h ../extplugin.h ../ltdl.h ../gui/gui.h ../gui/textconfig.h \
- ../gui/keymap.h ../iodev/iodev.h ../iodev/vga.h ../iodev/biosdev.h \
- ../iodev/cmos.h ../iodev/dma.h ../iodev/floppy.h ../iodev/harddrv.h \
- ../iodev/cdrom.h ../iodev/keyboard.h ../iodev/parallel.h \
- ../iodev/pic.h ../iodev/pit.h ../iodev/pit_wrap.h ../iodev/pit82c54.h \
- ../iodev/serial.h ../iodev/unmapped.h ../iodev/eth.h ../iodev/ne2k.h \
- ../iodev/guest2host.h ../iodev/slowdown_timer.h \
- ../instrument/stubs/instrument.h icon_bochs.h ../font/vga.bitmap.h \
- rfbproto.h
-sdl.o: sdl.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h ../bx_debug/debug.h \
- ../bxversion.h ../gui/siminterface.h ../state_file.h ../cpu/cpu.h \
- ../cpu/lazy_flags.h ../cpu/i387.h ../memory/memory.h ../pc_system.h \
- ../plugin.h ../extplugin.h ../ltdl.h ../gui/gui.h ../gui/textconfig.h \
- ../gui/keymap.h ../iodev/iodev.h ../iodev/vga.h ../iodev/biosdev.h \
- ../iodev/cmos.h ../iodev/dma.h ../iodev/floppy.h ../iodev/harddrv.h \
- ../iodev/cdrom.h ../iodev/keyboard.h ../iodev/parallel.h \
- ../iodev/pic.h ../iodev/pit.h ../iodev/pit_wrap.h ../iodev/pit82c54.h \
- ../iodev/serial.h ../iodev/unmapped.h ../iodev/eth.h ../iodev/ne2k.h \
- ../iodev/guest2host.h ../iodev/slowdown_timer.h \
- ../instrument/stubs/instrument.h icon_bochs.h sdl.h sdlkeys.h
-siminterface.o: siminterface.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h \
- ../bx_debug/debug.h ../bxversion.h ../gui/siminterface.h ../state_file.h \
- ../cpu/cpu.h ../cpu/lazy_flags.h ../cpu/i387.h ../memory/memory.h \
- ../pc_system.h ../plugin.h ../extplugin.h ../ltdl.h ../gui/gui.h \
- ../gui/textconfig.h ../gui/keymap.h ../iodev/iodev.h ../iodev/vga.h \
- ../iodev/biosdev.h ../iodev/cmos.h ../iodev/dma.h ../iodev/floppy.h \
- ../iodev/harddrv.h ../iodev/cdrom.h ../iodev/keyboard.h \
- ../iodev/parallel.h ../iodev/pic.h ../iodev/pit.h ../iodev/pit_wrap.h \
- ../iodev/pit82c54.h ../iodev/serial.h ../iodev/unmapped.h \
- ../iodev/eth.h ../iodev/ne2k.h ../iodev/guest2host.h \
- ../iodev/slowdown_timer.h ../instrument/stubs/instrument.h
-svga.o: svga.@CPP_SUFFIX@ ../font/vga.bitmap.h ../bochs.h ../config.h ../osdep.h \
- ../bx_debug/debug.h ../bxversion.h ../gui/siminterface.h ../state_file.h \
- ../cpu/cpu.h ../cpu/lazy_flags.h ../cpu/i387.h ../memory/memory.h \
- ../pc_system.h ../plugin.h ../extplugin.h ../ltdl.h ../gui/gui.h \
- ../gui/textconfig.h ../gui/keymap.h ../iodev/iodev.h ../iodev/vga.h \
- ../iodev/biosdev.h ../iodev/cmos.h ../iodev/dma.h ../iodev/floppy.h \
- ../iodev/harddrv.h ../iodev/cdrom.h ../iodev/keyboard.h \
- ../iodev/parallel.h ../iodev/pic.h ../iodev/pit.h ../iodev/pit_wrap.h \
- ../iodev/pit82c54.h ../iodev/serial.h ../iodev/unmapped.h \
- ../iodev/eth.h ../iodev/ne2k.h ../iodev/guest2host.h \
- ../iodev/slowdown_timer.h ../instrument/stubs/instrument.h \
- icon_bochs.h
-term.o: term.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h ../bx_debug/debug.h \
- ../bxversion.h ../gui/siminterface.h ../state_file.h ../cpu/cpu.h \
- ../cpu/lazy_flags.h ../cpu/i387.h ../memory/memory.h ../pc_system.h \
- ../plugin.h ../extplugin.h ../ltdl.h ../gui/gui.h ../gui/textconfig.h \
- ../gui/keymap.h ../iodev/iodev.h ../iodev/vga.h ../iodev/biosdev.h \
- ../iodev/cmos.h ../iodev/dma.h ../iodev/floppy.h ../iodev/harddrv.h \
- ../iodev/cdrom.h ../iodev/keyboard.h ../iodev/parallel.h \
- ../iodev/pic.h ../iodev/pit.h ../iodev/pit_wrap.h ../iodev/pit82c54.h \
- ../iodev/serial.h ../iodev/unmapped.h ../iodev/eth.h ../iodev/ne2k.h \
- ../iodev/guest2host.h ../iodev/slowdown_timer.h \
- ../instrument/stubs/instrument.h icon_bochs.h
-textconfig.o: textconfig.@CPP_SUFFIX@ ../config.h ../osdep.h textconfig.h \
- siminterface.h ../extplugin.h ../ltdl.h
-win32.o: win32.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h ../bx_debug/debug.h \
- ../bxversion.h ../gui/siminterface.h ../state_file.h ../cpu/cpu.h \
- ../cpu/lazy_flags.h ../cpu/i387.h ../memory/memory.h ../pc_system.h \
- ../plugin.h ../extplugin.h ../ltdl.h ../gui/gui.h ../gui/textconfig.h \
- ../gui/keymap.h ../iodev/iodev.h ../iodev/vga.h ../iodev/biosdev.h \
- ../iodev/cmos.h ../iodev/dma.h ../iodev/floppy.h ../iodev/harddrv.h \
- ../iodev/cdrom.h ../iodev/keyboard.h ../iodev/parallel.h \
- ../iodev/pic.h ../iodev/pit.h ../iodev/pit_wrap.h ../iodev/pit82c54.h \
- ../iodev/serial.h ../iodev/unmapped.h ../iodev/eth.h ../iodev/ne2k.h \
- ../iodev/guest2host.h ../iodev/slowdown_timer.h \
- ../instrument/stubs/instrument.h icon_bochs.h ../font/vga.bitmap.h
-wx.o: wx.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h ../bx_debug/debug.h \
- ../bxversion.h ../gui/siminterface.h ../state_file.h ../cpu/cpu.h \
- ../cpu/lazy_flags.h ../cpu/i387.h ../memory/memory.h ../pc_system.h \
- ../plugin.h ../extplugin.h ../ltdl.h ../gui/gui.h ../gui/textconfig.h \
- ../gui/keymap.h ../iodev/iodev.h ../iodev/vga.h ../iodev/biosdev.h \
- ../iodev/cmos.h ../iodev/dma.h ../iodev/floppy.h ../iodev/harddrv.h \
- ../iodev/cdrom.h ../iodev/keyboard.h ../iodev/parallel.h \
- ../iodev/pic.h ../iodev/pit.h ../iodev/pit_wrap.h ../iodev/pit82c54.h \
- ../iodev/serial.h ../iodev/unmapped.h ../iodev/eth.h ../iodev/ne2k.h \
- ../iodev/guest2host.h ../iodev/slowdown_timer.h \
- ../instrument/stubs/instrument.h ../gui/icon_bochs.h \
- ../font/vga.bitmap.h wxmain.h
-wxdialog.o: wxdialog.@CPP_SUFFIX@ ../config.h ../osdep.h ../gui/siminterface.h \
- ../bxversion.h wxdialog.h wxmain.h
-wxmain.o: wxmain.@CPP_SUFFIX@ ../config.h ../osdep.h ../gui/siminterface.h \
- ../bxversion.h wxdialog.h wxmain.h ../extplugin.h ../ltdl.h \
- bitmaps/cdromd.xpm bitmaps/copy.xpm bitmaps/floppya.xpm \
- bitmaps/floppyb.xpm bitmaps/paste.xpm bitmaps/power.xpm \
- bitmaps/reset.xpm bitmaps/snapshot.xpm bitmaps/mouse.xpm \
- bitmaps/userbutton.xpm
-x.o: x.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h ../bx_debug/debug.h \
- ../bxversion.h ../gui/siminterface.h ../state_file.h ../cpu/cpu.h \
- ../cpu/lazy_flags.h ../cpu/i387.h ../memory/memory.h ../pc_system.h \
- ../plugin.h ../extplugin.h ../ltdl.h ../gui/gui.h ../gui/textconfig.h \
- ../gui/keymap.h ../iodev/iodev.h ../iodev/vga.h ../iodev/biosdev.h \
- ../iodev/cmos.h ../iodev/dma.h ../iodev/floppy.h ../iodev/harddrv.h \
- ../iodev/cdrom.h ../iodev/keyboard.h ../iodev/parallel.h \
- ../iodev/pic.h ../iodev/pit.h ../iodev/pit_wrap.h ../iodev/pit82c54.h \
- ../iodev/serial.h ../iodev/unmapped.h ../iodev/eth.h ../iodev/ne2k.h \
- ../iodev/guest2host.h ../iodev/slowdown_timer.h \
- ../instrument/stubs/instrument.h icon_bochs.h
-amigaos.lo: amigaos.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h \
- ../bx_debug/debug.h ../bxversion.h ../gui/siminterface.h ../state_file.h \
- ../cpu/cpu.h ../cpu/lazy_flags.h ../cpu/i387.h ../memory/memory.h \
- ../pc_system.h ../plugin.h ../extplugin.h ../ltdl.h ../gui/gui.h \
- ../gui/textconfig.h ../gui/keymap.h ../iodev/iodev.h ../iodev/vga.h \
- ../iodev/biosdev.h ../iodev/cmos.h ../iodev/dma.h ../iodev/floppy.h \
- ../iodev/harddrv.h ../iodev/cdrom.h ../iodev/keyboard.h \
- ../iodev/parallel.h ../iodev/pic.h ../iodev/pit.h ../iodev/pit_wrap.h \
- ../iodev/pit82c54.h ../iodev/serial.h ../iodev/unmapped.h \
- ../iodev/eth.h ../iodev/ne2k.h ../iodev/guest2host.h \
- ../iodev/slowdown_timer.h ../instrument/stubs/instrument.h \
- icon_bochs.h amigagui.h
-beos.lo: beos.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h ../bx_debug/debug.h \
- ../bxversion.h ../gui/siminterface.h ../state_file.h ../cpu/cpu.h \
- ../cpu/lazy_flags.h ../cpu/i387.h ../memory/memory.h ../pc_system.h \
- ../plugin.h ../extplugin.h ../ltdl.h ../gui/gui.h ../gui/textconfig.h \
- ../gui/keymap.h ../iodev/iodev.h ../iodev/vga.h ../iodev/biosdev.h \
- ../iodev/cmos.h ../iodev/dma.h ../iodev/floppy.h ../iodev/harddrv.h \
- ../iodev/cdrom.h ../iodev/keyboard.h ../iodev/parallel.h \
- ../iodev/pic.h ../iodev/pit.h ../iodev/pit_wrap.h ../iodev/pit82c54.h \
- ../iodev/serial.h ../iodev/unmapped.h ../iodev/eth.h ../iodev/ne2k.h \
- ../iodev/guest2host.h ../iodev/slowdown_timer.h \
- ../instrument/stubs/instrument.h ../font/vga.bitmap.h
-carbon.lo: carbon.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h ../bx_debug/debug.h \
- ../bxversion.h ../gui/siminterface.h ../state_file.h ../cpu/cpu.h \
- ../cpu/lazy_flags.h ../cpu/i387.h ../memory/memory.h ../pc_system.h \
- ../plugin.h ../extplugin.h ../ltdl.h ../gui/gui.h ../gui/textconfig.h \
- ../gui/keymap.h ../iodev/iodev.h ../iodev/vga.h ../iodev/biosdev.h \
- ../iodev/cmos.h ../iodev/dma.h ../iodev/floppy.h ../iodev/harddrv.h \
- ../iodev/cdrom.h ../iodev/keyboard.h ../iodev/parallel.h \
- ../iodev/pic.h ../iodev/pit.h ../iodev/pit_wrap.h ../iodev/pit82c54.h \
- ../iodev/serial.h ../iodev/unmapped.h ../iodev/eth.h ../iodev/ne2k.h \
- ../iodev/guest2host.h ../iodev/slowdown_timer.h \
- ../instrument/stubs/instrument.h icon_bochs.h ../font/vga.bitmap.h
-gui.lo: gui.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h ../bx_debug/debug.h \
- ../bxversion.h ../gui/siminterface.h ../state_file.h ../cpu/cpu.h \
- ../cpu/lazy_flags.h ../cpu/i387.h ../memory/memory.h ../pc_system.h \
- ../plugin.h ../extplugin.h ../ltdl.h ../gui/gui.h ../gui/textconfig.h \
- ../gui/keymap.h ../iodev/iodev.h ../iodev/vga.h ../iodev/biosdev.h \
- ../iodev/cmos.h ../iodev/dma.h ../iodev/floppy.h ../iodev/harddrv.h \
- ../iodev/cdrom.h ../iodev/keyboard.h ../iodev/parallel.h \
- ../iodev/pic.h ../iodev/pit.h ../iodev/pit_wrap.h ../iodev/pit82c54.h \
- ../iodev/serial.h ../iodev/unmapped.h ../iodev/eth.h ../iodev/ne2k.h \
- ../iodev/guest2host.h ../iodev/slowdown_timer.h \
- ../instrument/stubs/instrument.h ../gui/bitmaps/floppya.h \
- ../gui/bitmaps/floppyb.h ../gui/bitmaps/mouse.h \
- ../gui/bitmaps/reset.h ../gui/bitmaps/power.h \
- ../gui/bitmaps/snapshot.h ../gui/bitmaps/copy.h \
- ../gui/bitmaps/paste.h ../gui/bitmaps/configbutton.h \
- ../gui/bitmaps/cdromd.h ../gui/bitmaps/userbutton.h
-keymap.lo: keymap.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h ../bx_debug/debug.h \
- ../bxversion.h ../gui/siminterface.h ../state_file.h ../cpu/cpu.h \
- ../cpu/lazy_flags.h ../cpu/i387.h ../memory/memory.h ../pc_system.h \
- ../plugin.h ../extplugin.h ../ltdl.h ../gui/gui.h ../gui/textconfig.h \
- ../gui/keymap.h ../iodev/iodev.h ../iodev/vga.h ../iodev/biosdev.h \
- ../iodev/cmos.h ../iodev/dma.h ../iodev/floppy.h ../iodev/harddrv.h \
- ../iodev/cdrom.h ../iodev/keyboard.h ../iodev/parallel.h \
- ../iodev/pic.h ../iodev/pit.h ../iodev/pit_wrap.h ../iodev/pit82c54.h \
- ../iodev/serial.h ../iodev/unmapped.h ../iodev/eth.h ../iodev/ne2k.h \
- ../iodev/guest2host.h ../iodev/slowdown_timer.h \
- ../instrument/stubs/instrument.h
-macintosh.lo: macintosh.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h \
- ../bx_debug/debug.h ../bxversion.h ../gui/siminterface.h ../state_file.h \
- ../cpu/cpu.h ../cpu/lazy_flags.h ../cpu/i387.h ../memory/memory.h \
- ../pc_system.h ../plugin.h ../extplugin.h ../ltdl.h ../gui/gui.h \
- ../gui/textconfig.h ../gui/keymap.h ../iodev/iodev.h ../iodev/vga.h \
- ../iodev/biosdev.h ../iodev/cmos.h ../iodev/dma.h ../iodev/floppy.h \
- ../iodev/harddrv.h ../iodev/cdrom.h ../iodev/keyboard.h \
- ../iodev/parallel.h ../iodev/pic.h ../iodev/pit.h ../iodev/pit_wrap.h \
- ../iodev/pit82c54.h ../iodev/serial.h ../iodev/unmapped.h \
- ../iodev/eth.h ../iodev/ne2k.h ../iodev/guest2host.h \
- ../iodev/slowdown_timer.h ../instrument/stubs/instrument.h \
- icon_bochs.h ../font/vga.bitmap.h
-nogui.lo: nogui.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h ../bx_debug/debug.h \
- ../bxversion.h ../gui/siminterface.h ../state_file.h ../cpu/cpu.h \
- ../cpu/lazy_flags.h ../cpu/i387.h ../memory/memory.h ../pc_system.h \
- ../plugin.h ../extplugin.h ../ltdl.h ../gui/gui.h ../gui/textconfig.h \
- ../gui/keymap.h ../iodev/iodev.h ../iodev/vga.h ../iodev/biosdev.h \
- ../iodev/cmos.h ../iodev/dma.h ../iodev/floppy.h ../iodev/harddrv.h \
- ../iodev/cdrom.h ../iodev/keyboard.h ../iodev/parallel.h \
- ../iodev/pic.h ../iodev/pit.h ../iodev/pit_wrap.h ../iodev/pit82c54.h \
- ../iodev/serial.h ../iodev/unmapped.h ../iodev/eth.h ../iodev/ne2k.h \
- ../iodev/guest2host.h ../iodev/slowdown_timer.h \
- ../instrument/stubs/instrument.h icon_bochs.h
-rfb.lo: rfb.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h ../bx_debug/debug.h \
- ../bxversion.h ../gui/siminterface.h ../state_file.h ../cpu/cpu.h \
- ../cpu/lazy_flags.h ../cpu/i387.h ../memory/memory.h ../pc_system.h \
- ../plugin.h ../extplugin.h ../ltdl.h ../gui/gui.h ../gui/textconfig.h \
- ../gui/keymap.h ../iodev/iodev.h ../iodev/vga.h ../iodev/biosdev.h \
- ../iodev/cmos.h ../iodev/dma.h ../iodev/floppy.h ../iodev/harddrv.h \
- ../iodev/cdrom.h ../iodev/keyboard.h ../iodev/parallel.h \
- ../iodev/pic.h ../iodev/pit.h ../iodev/pit_wrap.h ../iodev/pit82c54.h \
- ../iodev/serial.h ../iodev/unmapped.h ../iodev/eth.h ../iodev/ne2k.h \
- ../iodev/guest2host.h ../iodev/slowdown_timer.h \
- ../instrument/stubs/instrument.h icon_bochs.h ../font/vga.bitmap.h \
- rfbproto.h
-sdl.lo: sdl.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h ../bx_debug/debug.h \
- ../bxversion.h ../gui/siminterface.h ../state_file.h ../cpu/cpu.h \
- ../cpu/lazy_flags.h ../cpu/i387.h ../memory/memory.h ../pc_system.h \
- ../plugin.h ../extplugin.h ../ltdl.h ../gui/gui.h ../gui/textconfig.h \
- ../gui/keymap.h ../iodev/iodev.h ../iodev/vga.h ../iodev/biosdev.h \
- ../iodev/cmos.h ../iodev/dma.h ../iodev/floppy.h ../iodev/harddrv.h \
- ../iodev/cdrom.h ../iodev/keyboard.h ../iodev/parallel.h \
- ../iodev/pic.h ../iodev/pit.h ../iodev/pit_wrap.h ../iodev/pit82c54.h \
- ../iodev/serial.h ../iodev/unmapped.h ../iodev/eth.h ../iodev/ne2k.h \
- ../iodev/guest2host.h ../iodev/slowdown_timer.h \
- ../instrument/stubs/instrument.h icon_bochs.h sdl.h sdlkeys.h
-siminterface.lo: siminterface.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h \
- ../bx_debug/debug.h ../bxversion.h ../gui/siminterface.h ../state_file.h \
- ../cpu/cpu.h ../cpu/lazy_flags.h ../cpu/i387.h ../memory/memory.h \
- ../pc_system.h ../plugin.h ../extplugin.h ../ltdl.h ../gui/gui.h \
- ../gui/textconfig.h ../gui/keymap.h ../iodev/iodev.h ../iodev/vga.h \
- ../iodev/biosdev.h ../iodev/cmos.h ../iodev/dma.h ../iodev/floppy.h \
- ../iodev/harddrv.h ../iodev/cdrom.h ../iodev/keyboard.h \
- ../iodev/parallel.h ../iodev/pic.h ../iodev/pit.h ../iodev/pit_wrap.h \
- ../iodev/pit82c54.h ../iodev/serial.h ../iodev/unmapped.h \
- ../iodev/eth.h ../iodev/ne2k.h ../iodev/guest2host.h \
- ../iodev/slowdown_timer.h ../instrument/stubs/instrument.h
-svga.lo: svga.@CPP_SUFFIX@ ../font/vga.bitmap.h ../bochs.h ../config.h ../osdep.h \
- ../bx_debug/debug.h ../bxversion.h ../gui/siminterface.h ../state_file.h \
- ../cpu/cpu.h ../cpu/lazy_flags.h ../cpu/i387.h ../memory/memory.h \
- ../pc_system.h ../plugin.h ../extplugin.h ../ltdl.h ../gui/gui.h \
- ../gui/textconfig.h ../gui/keymap.h ../iodev/iodev.h ../iodev/vga.h \
- ../iodev/biosdev.h ../iodev/cmos.h ../iodev/dma.h ../iodev/floppy.h \
- ../iodev/harddrv.h ../iodev/cdrom.h ../iodev/keyboard.h \
- ../iodev/parallel.h ../iodev/pic.h ../iodev/pit.h ../iodev/pit_wrap.h \
- ../iodev/pit82c54.h ../iodev/serial.h ../iodev/unmapped.h \
- ../iodev/eth.h ../iodev/ne2k.h ../iodev/guest2host.h \
- ../iodev/slowdown_timer.h ../instrument/stubs/instrument.h \
- icon_bochs.h
-term.lo: term.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h ../bx_debug/debug.h \
- ../bxversion.h ../gui/siminterface.h ../state_file.h ../cpu/cpu.h \
- ../cpu/lazy_flags.h ../cpu/i387.h ../memory/memory.h ../pc_system.h \
- ../plugin.h ../extplugin.h ../ltdl.h ../gui/gui.h ../gui/textconfig.h \
- ../gui/keymap.h ../iodev/iodev.h ../iodev/vga.h ../iodev/biosdev.h \
- ../iodev/cmos.h ../iodev/dma.h ../iodev/floppy.h ../iodev/harddrv.h \
- ../iodev/cdrom.h ../iodev/keyboard.h ../iodev/parallel.h \
- ../iodev/pic.h ../iodev/pit.h ../iodev/pit_wrap.h ../iodev/pit82c54.h \
- ../iodev/serial.h ../iodev/unmapped.h ../iodev/eth.h ../iodev/ne2k.h \
- ../iodev/guest2host.h ../iodev/slowdown_timer.h \
- ../instrument/stubs/instrument.h icon_bochs.h
-textconfig.lo: textconfig.@CPP_SUFFIX@ ../config.h ../osdep.h textconfig.h \
- siminterface.h ../extplugin.h ../ltdl.h
-win32.lo: win32.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h ../bx_debug/debug.h \
- ../bxversion.h ../gui/siminterface.h ../state_file.h ../cpu/cpu.h \
- ../cpu/lazy_flags.h ../cpu/i387.h ../memory/memory.h ../pc_system.h \
- ../plugin.h ../extplugin.h ../ltdl.h ../gui/gui.h ../gui/textconfig.h \
- ../gui/keymap.h ../iodev/iodev.h ../iodev/vga.h ../iodev/biosdev.h \
- ../iodev/cmos.h ../iodev/dma.h ../iodev/floppy.h ../iodev/harddrv.h \
- ../iodev/cdrom.h ../iodev/keyboard.h ../iodev/parallel.h \
- ../iodev/pic.h ../iodev/pit.h ../iodev/pit_wrap.h ../iodev/pit82c54.h \
- ../iodev/serial.h ../iodev/unmapped.h ../iodev/eth.h ../iodev/ne2k.h \
- ../iodev/guest2host.h ../iodev/slowdown_timer.h \
- ../instrument/stubs/instrument.h icon_bochs.h ../font/vga.bitmap.h
-wx.lo: wx.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h ../bx_debug/debug.h \
- ../bxversion.h ../gui/siminterface.h ../state_file.h ../cpu/cpu.h \
- ../cpu/lazy_flags.h ../cpu/i387.h ../memory/memory.h ../pc_system.h \
- ../plugin.h ../extplugin.h ../ltdl.h ../gui/gui.h ../gui/textconfig.h \
- ../gui/keymap.h ../iodev/iodev.h ../iodev/vga.h ../iodev/biosdev.h \
- ../iodev/cmos.h ../iodev/dma.h ../iodev/floppy.h ../iodev/harddrv.h \
- ../iodev/cdrom.h ../iodev/keyboard.h ../iodev/parallel.h \
- ../iodev/pic.h ../iodev/pit.h ../iodev/pit_wrap.h ../iodev/pit82c54.h \
- ../iodev/serial.h ../iodev/unmapped.h ../iodev/eth.h ../iodev/ne2k.h \
- ../iodev/guest2host.h ../iodev/slowdown_timer.h \
- ../instrument/stubs/instrument.h ../gui/icon_bochs.h \
- ../font/vga.bitmap.h wxdialog.h wxmain.h
-wxdialog.lo: wxdialog.@CPP_SUFFIX@ ../config.h ../osdep.h ../gui/siminterface.h \
- ../bxversion.h wxdialog.h wxmain.h
-wxmain.lo: wxmain.@CPP_SUFFIX@ ../config.h ../osdep.h ../gui/siminterface.h \
- ../bxversion.h wxdialog.h wxmain.h ../extplugin.h ../ltdl.h \
- bitmaps/cdromd.xpm bitmaps/copy.xpm bitmaps/floppya.xpm \
- bitmaps/floppyb.xpm bitmaps/paste.xpm bitmaps/power.xpm \
- bitmaps/reset.xpm bitmaps/snapshot.xpm bitmaps/mouse.xpm \
- bitmaps/userbutton.xpm
-x.lo: x.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h ../bx_debug/debug.h \
- ../bxversion.h ../gui/siminterface.h ../state_file.h ../cpu/cpu.h \
- ../cpu/lazy_flags.h ../cpu/i387.h ../memory/memory.h ../pc_system.h \
- ../plugin.h ../extplugin.h ../ltdl.h ../gui/gui.h ../gui/textconfig.h \
- ../gui/keymap.h ../iodev/iodev.h ../iodev/vga.h ../iodev/biosdev.h \
- ../iodev/cmos.h ../iodev/dma.h ../iodev/floppy.h ../iodev/harddrv.h \
- ../iodev/cdrom.h ../iodev/keyboard.h ../iodev/parallel.h \
- ../iodev/pic.h ../iodev/pit.h ../iodev/pit_wrap.h ../iodev/pit82c54.h \
- ../iodev/serial.h ../iodev/unmapped.h ../iodev/eth.h ../iodev/ne2k.h \
- ../iodev/guest2host.h ../iodev/slowdown_timer.h \
- ../instrument/stubs/instrument.h icon_bochs.h
diff --git a/tools/ioemu/gui/bitmaps/cdromd.h b/tools/ioemu/gui/bitmaps/cdromd.h
deleted file mode 100644 (file)
index 49d78e1..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: cdromd.h,v 1.1 2002/01/31 21:16:52 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-#define BX_CDROMD_BMAP_X 32
-#define BX_CDROMD_BMAP_Y 32
-
-static const unsigned char bx_cdromd_bmap[(BX_CONFIG_BMAP_X * BX_CONFIG_BMAP_Y)/8] = {
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x0e, 0x00, 0x00, 0x10, 0x12, 0x00, 
-  0x00, 0x10, 0x12, 0x00, 0x00, 0x10, 0x12, 0x00, 0x00, 0x60, 0x0e, 0x00, 
-  0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0x0c, 0x30, 0x00, 
-  0x00, 0xe2, 0x47, 0x00, 0x00, 0x19, 0x98, 0x00, 0x80, 0xe6, 0x67, 0x01, 
-  0x40, 0x19, 0x98, 0x02, 0x20, 0xe5, 0xa7, 0x04, 0xa0, 0x12, 0x48, 0x05, 
-  0x90, 0xca, 0x53, 0x09, 0x50, 0x25, 0xa4, 0x0a, 0x50, 0x15, 0xa8, 0x0a, 
-  0x50, 0x15, 0xa8, 0x0a, 0x50, 0x15, 0xa8, 0x0a, 0x50, 0x15, 0xa8, 0x0a, 
-  0x50, 0x25, 0xa4, 0x0a, 0x90, 0xca, 0x53, 0x09, 0xa0, 0x12, 0x48, 0x05, 
-  0x20, 0xe5, 0xa7, 0x04, 0x40, 0x19, 0x98, 0x02, 0x80, 0xe6, 0x67, 0x01, 
-  0x00, 0x19, 0x98, 0x00, 0x00, 0xe2, 0x47, 0x00, 0x00, 0x0c, 0x30, 0x00, 
-  0x00, 0xf0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00
-  };
-
-static const unsigned char bx_cdromd_eject_bmap[(BX_CONFIG_BMAP_X * BX_CONFIG_BMAP_Y)/8] = {
-  0x01, 0x00, 0x00, 0x80, 0x02, 0x60, 0x0e, 0x40, 0x04, 0x10, 0x12, 0x20, 
-  0x08, 0x10, 0x12, 0x10, 0x10, 0x10, 0x12, 0x08, 0x20, 0x60, 0x0e, 0x04, 
-  0x40, 0x00, 0x00, 0x02, 0x80, 0xf0, 0x0f, 0x01, 0x00, 0x0d, 0xb0, 0x00, 
-  0x00, 0xe2, 0x47, 0x00, 0x00, 0x1d, 0xb8, 0x00, 0x80, 0xee, 0x77, 0x01, 
-  0x40, 0x19, 0x98, 0x02, 0x20, 0xe5, 0xa7, 0x04, 0xa0, 0x52, 0x4a, 0x05, 
-  0x90, 0xca, 0x53, 0x09, 0x50, 0xa5, 0xa5, 0x0a, 0x50, 0x55, 0xaa, 0x0a, 
-  0x50, 0x35, 0xac, 0x0a, 0x50, 0x15, 0xa8, 0x0a, 0x50, 0x1d, 0xb8, 0x0a, 
-  0x50, 0x25, 0xa4, 0x0a, 0x90, 0xca, 0x53, 0x09, 0xa0, 0x13, 0xc8, 0x05, 
-  0xa0, 0xe5, 0xa7, 0x05, 0x40, 0x19, 0x98, 0x02, 0xa0, 0xe6, 0x67, 0x05, 
-  0x10, 0x19, 0x98, 0x08, 0x08, 0xe2, 0x47, 0x10, 0x04, 0x0c, 0x30, 0x20, 
-  0x02, 0xf0, 0x0f, 0x40, 0x01, 0x00, 0x00, 0x80
-  };
diff --git a/tools/ioemu/gui/bitmaps/cdromd.xpm b/tools/ioemu/gui/bitmaps/cdromd.xpm
deleted file mode 100644 (file)
index 7a216b0..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/* XPM */
-static char *cdromd_xpm[] = {
-/* width height num_colors chars_per_pixel */
-"    32    32        2            1",
-/* colors */
-". c None",
-"# c #000000",
-/* pixels */
-"................................",
-".............##..###............",
-"............#....#..#...........",
-"............#....#..#...........",
-"............#....#..#...........",
-".............##..###............",
-"................................",
-"............########............",
-"..........##........##..........",
-".........#...######...#.........",
-"........#..##......##..#........",
-".......#.##..######..##.#.......",
-"......#.#..##......##..#.#......",
-".....#..#.#..######..#.#..#.....",
-".....#.#.#..#......#..#.#.#.....",
-"....#..#.#.#..####..#.#.#..#....",
-"....#.#.#.#..#....#..#.#.#.#....",
-"....#.#.#.#.#......#.#.#.#.#....",
-"....#.#.#.#.#......#.#.#.#.#....",
-"....#.#.#.#.#......#.#.#.#.#....",
-"....#.#.#.#.#......#.#.#.#.#....",
-"....#.#.#.#..#....#..#.#.#.#....",
-"....#..#.#.#..####..#.#.#..#....",
-".....#.#.#..#......#..#.#.#.....",
-".....#..#.#..######..#.#..#.....",
-"......#.#..##......##..#.#......",
-".......#.##..######..##.#.......",
-"........#..##......##..#........",
-".........#...######...#.........",
-"..........##........##..........",
-"............########............",
-"................................"
-};
diff --git a/tools/ioemu/gui/bitmaps/configbutton.h b/tools/ioemu/gui/bitmaps/configbutton.h
deleted file mode 100644 (file)
index 7c51ff9..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-#define BX_CONFIG_BMAP_X 32
-#define BX_CONFIG_BMAP_Y 32
-
-static const unsigned char bx_config_bmap[(BX_CONFIG_BMAP_X * BX_CONFIG_BMAP_Y)/8] = {
-  0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x80, 0x01, 0xfc, 0x7f, 0xc0, 0x03, 
-  0xfc, 0xff, 0xc1, 0x03, 0xfc, 0xff, 0xc1, 0x03, 0xfc, 0x7f, 0xc0, 0x03, 
-  0x84, 0x07, 0xc0, 0x03, 0x80, 0x07, 0xc0, 0x03, 0x80, 0x07, 0xc0, 0x03, 
-  0x80, 0x07, 0xc0, 0x03, 0x80, 0x07, 0xc0, 0x03, 0x80, 0x07, 0xc0, 0x03, 
-  0x80, 0x07, 0xc0, 0x03, 0x80, 0x07, 0xc0, 0x03, 0x80, 0x07, 0xc0, 0x03, 
-  0x80, 0x07, 0xc0, 0x03, 0x80, 0x07, 0xc0, 0x03, 0x80, 0x07, 0xc0, 0x03, 
-  0x80, 0x07, 0xc0, 0x03, 0x80, 0x07, 0xe0, 0x07, 0x80, 0x07, 0xf0, 0x0f, 
-  0x80, 0x07, 0x70, 0x0e, 0x80, 0x07, 0x30, 0x0c, 0x80, 0x07, 0x30, 0x0c, 
-  0x80, 0x07, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x38, 0x27, 0xba, 0x1c, 
-  0x84, 0x68, 0x8a, 0x02, 0x84, 0xa8, 0xba, 0x32, 0x84, 0x28, 0x8b, 0x22, 
-  0x38, 0x27, 0x8a, 0x1c, 0x00, 0x00, 0x00, 0x00
-  };
diff --git a/tools/ioemu/gui/bitmaps/configbutton.xpm b/tools/ioemu/gui/bitmaps/configbutton.xpm
deleted file mode 100644 (file)
index ef2f933..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/* XPM */
-static char *configbutton_xpm[] = {
-/* width height num_colors chars_per_pixel */
-"    32    32        2            1",
-/* colors */
-". c None",
-"# c #000000",
-/* pixels */
-"................................",
-"..#....................##.......",
-"..#############.......####......",
-"..###############.....####......",
-"..###############.....####......",
-"..#############.......####......",
-"..#....####...........####......",
-".......####...........####......",
-".......####...........####......",
-".......####...........####......",
-".......####...........####......",
-".......####...........####......",
-".......####...........####......",
-".......####...........####......",
-".......####...........####......",
-".......####...........####......",
-".......####...........####......",
-".......####...........####......",
-".......####...........####......",
-".......####..........######.....",
-".......####.........########....",
-".......####.........###..###....",
-".......####.........##....##....",
-".......####.........##....##....",
-".......####..........#....#.....",
-"................................",
-"...###..###..#...#.###.#..###...",
-"..#....#...#.##..#.#...#.#......",
-"..#....#...#.#.#.#.###.#.#..##..",
-"..#....#...#.#..##.#...#.#...#..",
-"...###..###..#...#.#...#..###...",
-"................................"
-};
diff --git a/tools/ioemu/gui/bitmaps/copy.h b/tools/ioemu/gui/bitmaps/copy.h
deleted file mode 100644 (file)
index 78546c9..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: copy.h,v 1.1 2002/03/11 15:04:58 bdenney Exp $
-/////////////////////////////////////////////////////////////////////////
-#define BX_COPY_BMAP_X 32
-#define BX_COPY_BMAP_Y 32
-
-static unsigned char bx_copy_bmap[(BX_COPY_BMAP_X*BX_COPY_BMAP_Y)] = {
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
-  0x80, 0x60, 0x4e, 0x02, 0x80, 0x90, 0x52, 0x02, 0x80, 0x90, 0x52, 0x02,
-  0x00, 0x6f, 0x8e, 0x03, 0x00, 0x00, 0x02, 0x02, 0xf8, 0x3f, 0x02, 0x02,
-  0x08, 0x20, 0xc0, 0x01, 0xe8, 0x2b, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00,
-  0xe8, 0x2e, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00, 0xe8, 0x39, 0x00, 0x00,
-  0x08, 0x24, 0x00, 0x00, 0x88, 0x20, 0x00, 0x00, 0xe8, 0xaf, 0xff, 0x03,
-  0x08, 0xa0, 0x00, 0x02, 0xf8, 0xbf, 0xbe, 0x02, 0x00, 0x80, 0x00, 0x02,
-  0x80, 0x88, 0xee, 0x02, 0x80, 0x90, 0x00, 0x02, 0x00, 0xbf, 0x9e, 0x03,
-  0x00, 0x90, 0x40, 0x02, 0x00, 0x88, 0x08, 0x02, 0x00, 0x80, 0xfe, 0x02,
-  0x00, 0x80, 0x00, 0x02, 0x00, 0x80, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
diff --git a/tools/ioemu/gui/bitmaps/copy.xpm b/tools/ioemu/gui/bitmaps/copy.xpm
deleted file mode 100644 (file)
index 5e0138e..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/* XPM */
-static char *copy_xpm[] = {
-/* width height num_colors chars_per_pixel */
-"    32    32        2            1",
-/* colors */
-". c None",
-"# c #000000",
-/* pixels */
-"................................",
-"........####....................",
-".......#........................",
-".......#.....##..###..#..#......",
-".......#....#..#.#..#.#..#......",
-".......#....#..#.#..#.#..#......",
-"........####.##..###...###......",
-".................#.......#......",
-"...###########...#.......#......",
-"...#.........#........###.......",
-"...#.#####.#.#..................",
-"...#.........#..................",
-"...#.###.###.#..................",
-"...#.........#..................",
-"...#.####..###..................",
-"...#......#..#..................",
-"...#...#.....#..................",
-"...#.#######.#.###########......",
-"...#.........#.#.........#......",
-"...###########.#.#####.#.#......",
-"...............#.........#......",
-".......#...#...#.###.###.#......",
-".......#....#..#.........#......",
-"........######.#.####..###......",
-"............#..#......#..#......",
-"...........#...#...#.....#......",
-"...............#.#######.#......",
-"...............#.........#......",
-"...............###########......",
-"................................",
-"................................",
-"................................"
-};
diff --git a/tools/ioemu/gui/bitmaps/floppya.h b/tools/ioemu/gui/bitmaps/floppya.h
deleted file mode 100644 (file)
index 86ba90f..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: floppya.h,v 1.2 2001/10/03 13:10:37 bdenney Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-#define BX_FLOPPYA_BMAP_X 32
-#define BX_FLOPPYA_BMAP_Y 32
-
-static const unsigned char bx_floppya_bmap[(BX_FLOPPYA_BMAP_X * BX_FLOPPYA_BMAP_Y)/8] = {
-   0x00, 0x80, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x40, 0x11, 0x00,
-   0x00, 0xc0, 0x01, 0x00, 0x00, 0x60, 0x13, 0x00, 0x00, 0x60, 0x03, 0x00,
-   0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0x07, 0xe0, 0x01, 0x80, 0x07,
-   0x20, 0xfd, 0xbf, 0x04, 0x20, 0x01, 0x80, 0x04, 0xe0, 0xfd, 0xbf, 0x07,
-   0xe0, 0x01, 0x80, 0x07, 0xe0, 0xfd, 0xbf, 0x07, 0xe0, 0x01, 0x80, 0x07,
-   0xe0, 0xfd, 0xbf, 0x07, 0xe0, 0x01, 0x80, 0x07, 0xe0, 0xfd, 0xbf, 0x07,
-   0xe0, 0x01, 0x80, 0x07, 0xe0, 0xfd, 0xbf, 0x07, 0xe0, 0x01, 0x80, 0x07,
-   0xe0, 0xff, 0xff, 0x07, 0xe0, 0xff, 0xff, 0x07, 0xe0, 0xff, 0xff, 0x07,
-   0xe0, 0xff, 0xff, 0x07, 0xe0, 0xaf, 0xea, 0x07, 0xe0, 0xf7, 0xd5, 0x07,
-   0xe0, 0xef, 0xea, 0x07, 0xe0, 0xf7, 0xd5, 0x07, 0xc0, 0xef, 0xea, 0x07,
-   0x80, 0x57, 0xd5, 0x07, 0x00, 0xaf, 0xea, 0x07
-  };
-
-static const unsigned char bx_floppya_eject_bmap[(BX_FLOPPYA_BMAP_X * BX_FLOPPYA_BMAP_Y)/8] = {
-   0x01, 0x80, 0x00, 0x80, 0x02, 0x40, 0x01, 0x40, 0x04, 0x40, 0x11, 0x20,
-   0x08, 0xc0, 0x01, 0x10, 0x10, 0x60, 0x13, 0x08, 0x20, 0x60, 0x03, 0x04,
-   0x40, 0x00, 0x00, 0x02, 0xe0, 0xff, 0xff, 0x07, 0xe0, 0x01, 0x80, 0x07,
-   0x20, 0xff, 0xff, 0x04, 0x20, 0x05, 0xa0, 0x04, 0xe0, 0xfd, 0xbf, 0x07,
-   0xe0, 0x11, 0x88, 0x07, 0xe0, 0xfd, 0xbf, 0x07, 0xe0, 0x41, 0x82, 0x07,
-   0xe0, 0xfd, 0xbf, 0x07, 0xe0, 0x81, 0x81, 0x07, 0xe0, 0xfd, 0xbf, 0x07,
-   0xe0, 0x21, 0x84, 0x07, 0xe0, 0xfd, 0xbf, 0x07, 0xe0, 0x09, 0x90, 0x07,
-   0xe0, 0xff, 0xff, 0x07, 0xe0, 0xff, 0xff, 0x07, 0xe0, 0xff, 0xff, 0x07,
-   0xe0, 0xff, 0xff, 0x07, 0xe0, 0xaf, 0xea, 0x07, 0xe0, 0xf7, 0xd5, 0x07,
-   0xf0, 0xef, 0xea, 0x0f, 0xe8, 0xf7, 0xd5, 0x17, 0xc4, 0xef, 0xea, 0x27,
-   0x82, 0x57, 0xd5, 0x47, 0x01, 0xaf, 0xea, 0x87
-  };
diff --git a/tools/ioemu/gui/bitmaps/floppya.xpm b/tools/ioemu/gui/bitmaps/floppya.xpm
deleted file mode 100644 (file)
index 637f198..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/* XPM */
-static char *floppya_xpm[] = {
-/* width height num_colors chars_per_pixel */
-"    32    32        2            1",
-/* colors */
-". c None",
-"# c #000000",
-/* pixels */
-"...............#................",
-"..............#.#...............",
-"..............#.#...#...........",
-"..............###...............",
-".............##.##..#...........",
-".............##.##..............",
-"................................",
-".....######################.....",
-".....####..............####.....",
-".....#..#.############.#..#.....",
-".....#..#..............#..#.....",
-".....####.############.####.....",
-".....####..............####.....",
-".....####.############.####.....",
-".....####..............####.....",
-".....####.############.####.....",
-".....####..............####.....",
-".....####.############.####.....",
-".....####..............####.....",
-".....####.############.####.....",
-".....####..............####.....",
-".....######################.....",
-".....######################.....",
-".....######################.....",
-".....######################.....",
-".....#######.#.#.#.#.######.....",
-".....######.#####.#.#.#####.....",
-".....#######.###.#.#.######.....",
-".....######.#####.#.#.#####.....",
-"......######.###.#.#.######.....",
-".......####.#.#.#.#.#.#####.....",
-"........####.#.#.#.#.######....."
-};
diff --git a/tools/ioemu/gui/bitmaps/floppyb.h b/tools/ioemu/gui/bitmaps/floppyb.h
deleted file mode 100644 (file)
index 70c7597..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: floppyb.h,v 1.2 2001/10/03 13:10:37 bdenney Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-#define BX_FLOPPYB_BMAP_X 32
-#define BX_FLOPPYB_BMAP_Y 32
-
-static const unsigned char bx_floppyb_bmap[(BX_FLOPPYB_BMAP_X * BX_FLOPPYB_BMAP_Y)/8] = {
-   0x00, 0xe0, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0xe0, 0x08, 0x00,
-   0x00, 0x20, 0x01, 0x00, 0x00, 0x20, 0x09, 0x00, 0x00, 0xe0, 0x00, 0x00,
-   0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0x07, 0xe0, 0x01, 0x80, 0x07,
-   0x20, 0xfd, 0xbf, 0x04, 0x20, 0x01, 0x80, 0x04, 0xe0, 0xfd, 0xbf, 0x07,
-   0xe0, 0x01, 0x80, 0x07, 0xe0, 0xfd, 0xbf, 0x07, 0xe0, 0x01, 0x80, 0x07,
-   0xe0, 0xfd, 0xbf, 0x07, 0xe0, 0x01, 0x80, 0x07, 0xe0, 0xfd, 0xbf, 0x07,
-   0xe0, 0x01, 0x80, 0x07, 0xe0, 0xfd, 0xbf, 0x07, 0xe0, 0x01, 0x80, 0x07,
-   0xe0, 0xff, 0xff, 0x07, 0xe0, 0xff, 0xff, 0x07, 0xe0, 0xff, 0xff, 0x07,
-   0xe0, 0xff, 0xff, 0x07, 0xe0, 0xaf, 0xea, 0x07, 0xe0, 0xf7, 0xd5, 0x07,
-   0xe0, 0xef, 0xea, 0x07, 0xe0, 0xf7, 0xd5, 0x07, 0xc0, 0xef, 0xea, 0x07,
-   0x80, 0x57, 0xd5, 0x07, 0x00, 0xaf, 0xea, 0x07
-  };
-
-static const unsigned char bx_floppyb_eject_bmap[(BX_FLOPPYB_BMAP_X * BX_FLOPPYB_BMAP_Y)/8] = {
-   0x01, 0xe0, 0x00, 0x80, 0x02, 0x20, 0x01, 0x40, 0x04, 0xe0, 0x08, 0x20,
-   0x08, 0x20, 0x01, 0x10, 0x10, 0x20, 0x09, 0x08, 0x20, 0xe0, 0x00, 0x04,
-   0x40, 0x00, 0x00, 0x02, 0xe0, 0xff, 0xff, 0x07, 0xe0, 0x01, 0x80, 0x07,
-   0x20, 0xff, 0xff, 0x04, 0x20, 0x05, 0xa0, 0x04, 0xe0, 0xfd, 0xbf, 0x07,
-   0xe0, 0x11, 0x88, 0x07, 0xe0, 0xfd, 0xbf, 0x07, 0xe0, 0x41, 0x82, 0x07,
-   0xe0, 0xfd, 0xbf, 0x07, 0xe0, 0x81, 0x81, 0x07, 0xe0, 0xfd, 0xbf, 0x07,
-   0xe0, 0x21, 0x84, 0x07, 0xe0, 0xfd, 0xbf, 0x07, 0xe0, 0x09, 0x90, 0x07,
-   0xe0, 0xff, 0xff, 0x07, 0xe0, 0xff, 0xff, 0x07, 0xe0, 0xff, 0xff, 0x07,
-   0xe0, 0xff, 0xff, 0x07, 0xe0, 0xaf, 0xea, 0x07, 0xe0, 0xf7, 0xd5, 0x07,
-   0xf0, 0xef, 0xea, 0x0f, 0xe8, 0xf7, 0xd5, 0x17, 0xc4, 0xef, 0xea, 0x27,
-   0x82, 0x57, 0xd5, 0x47, 0x01, 0xaf, 0xea, 0x87
-  };
diff --git a/tools/ioemu/gui/bitmaps/floppyb.xpm b/tools/ioemu/gui/bitmaps/floppyb.xpm
deleted file mode 100644 (file)
index f4e20e5..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/* XPM */
-static char *floppyb_xpm[] = {
-/* width height num_colors chars_per_pixel */
-"    32    32        2            1",
-/* colors */
-". c None",
-"# c #000000",
-/* pixels */
-".............###................",
-".............#..#...............",
-".............###...#............",
-".............#..#...............",
-".............#..#..#............",
-".............###................",
-"................................",
-".....######################.....",
-".....####..............####.....",
-".....#..#.############.#..#.....",
-".....#..#..............#..#.....",
-".....####.############.####.....",
-".....####..............####.....",
-".....####.############.####.....",
-".....####..............####.....",
-".....####.############.####.....",
-".....####..............####.....",
-".....####.############.####.....",
-".....####..............####.....",
-".....####.############.####.....",
-".....####..............####.....",
-".....######################.....",
-".....######################.....",
-".....######################.....",
-".....######################.....",
-".....#######.#.#.#.#.######.....",
-".....######.#####.#.#.#####.....",
-".....#######.###.#.#.######.....",
-".....######.#####.#.#.#####.....",
-"......######.###.#.#.######.....",
-".......####.#.#.#.#.#.#####.....",
-"........####.#.#.#.#.######....."
-};
diff --git a/tools/ioemu/gui/bitmaps/mouse.h b/tools/ioemu/gui/bitmaps/mouse.h
deleted file mode 100644 (file)
index cc8f364..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: mouse.h,v 1.2 2001/10/03 13:10:37 bdenney Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-#define BX_MOUSE_BMAP_X 32
-#define BX_MOUSE_BMAP_Y 32
-
-static unsigned char bx_mouse_bmap[(BX_MOUSE_BMAP_X * BX_MOUSE_BMAP_Y)/8] = {
-   0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xf8, 0x1f, 0x00,
-   0x00, 0x0c, 0x30, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0x06, 0x40, 0x00,
-   0xf8, 0xff, 0xc0, 0x00, 0x0c, 0x80, 0xc1, 0x00, 0x24, 0x22, 0xc1, 0x00,
-   0x74, 0x77, 0x81, 0x00, 0x74, 0x77, 0x81, 0x01, 0x74, 0x77, 0x81, 0x01,
-   0x74, 0x77, 0x01, 0x01, 0x74, 0x77, 0x01, 0x03, 0x74, 0x77, 0x01, 0x06,
-   0x24, 0x22, 0x01, 0x0c, 0x0c, 0x80, 0x01, 0x38, 0x04, 0x00, 0x01, 0x00,
-   0x0c, 0x80, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x0c, 0x80, 0x01, 0x00,
-   0x04, 0x00, 0x01, 0x00, 0x0c, 0x80, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00,
-   0x0c, 0x80, 0x01, 0x00, 0x14, 0x40, 0x01, 0x00, 0x2c, 0xa0, 0x01, 0x00,
-   0x54, 0x55, 0x01, 0x00, 0xac, 0xaa, 0x01, 0x00, 0xf8, 0xff, 0x00, 0x00,
-   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-   };
-
-static unsigned char bx_nomouse_bmap[(BX_MOUSE_BMAP_X * BX_MOUSE_BMAP_Y)/8] = {
-   0x01, 0x00, 0x00, 0x80, 0x02, 0xe0, 0x07, 0x40, 0x04, 0xf8, 0x1f, 0x20,
-   0x08, 0x0c, 0x30, 0x10, 0x10, 0x06, 0x60, 0x08, 0x20, 0x06, 0x40, 0x04,
-   0xf8, 0xff, 0xc0, 0x02, 0x8c, 0x80, 0xc1, 0x01, 0x24, 0x23, 0xc1, 0x00,
-   0x74, 0x77, 0xc1, 0x00, 0x74, 0x77, 0xa1, 0x01, 0x74, 0x7f, 0x91, 0x01,
-   0x74, 0x77, 0x09, 0x01, 0x74, 0x77, 0x05, 0x03, 0x74, 0x77, 0x03, 0x06,
-   0x24, 0xa2, 0x01, 0x0c, 0x0c, 0x80, 0x01, 0x38, 0x04, 0x40, 0x03, 0x00,
-   0x0c, 0xa0, 0x05, 0x00, 0x04, 0x10, 0x09, 0x00, 0x0c, 0x88, 0x11, 0x00,
-   0x04, 0x04, 0x21, 0x00, 0x0c, 0x82, 0x41, 0x00, 0x04, 0x01, 0x81, 0x00,
-   0x8c, 0x80, 0x01, 0x01, 0x54, 0x40, 0x01, 0x02, 0x2c, 0xa0, 0x01, 0x04,
-   0x54, 0x55, 0x01, 0x08, 0xac, 0xaa, 0x01, 0x10, 0xfc, 0xff, 0x00, 0x20,
-   0x02, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x80
-   };
diff --git a/tools/ioemu/gui/bitmaps/mouse.xpm b/tools/ioemu/gui/bitmaps/mouse.xpm
deleted file mode 100644 (file)
index dea3327..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/* XPM */
-static char *mouse_xpm[] = {
-/* width height num_colors chars_per_pixel */
-"    32    32        2            1",
-/* colors */
-". c None",
-"# c #000000",
-/* pixels */
-"................................",
-".............######.............",
-"...........##########...........",
-"..........##........##..........",
-".........##..........##.........",
-".........##...........#.........",
-"...#############......##........",
-"..##...........##.....##........",
-"..#..#...#...#..#.....##........",
-"..#.###.###.###.#......#........",
-"..#.###.###.###.#......##.......",
-"..#.###.###.###.#......##.......",
-"..#.###.###.###.#.......#.......",
-"..#.###.###.###.#.......##......",
-"..#.###.###.###.#........##.....",
-"..#..#...#...#..#.........##....",
-"..##...........##..........###..",
-"..#.............#...............",
-"..##...........##...............",
-"..#.............#...............",
-"..##...........##...............",
-"..#.............#...............",
-"..##...........##...............",
-"..#.............#...............",
-"..##...........##...............",
-"..#.#.........#.#...............",
-"..##.#.......#.##...............",
-"..#.#.#.#.#.#.#.#...............",
-"..##.#.#.#.#.#.##...............",
-"...#############................",
-"................................",
-"................................"
-};
diff --git a/tools/ioemu/gui/bitmaps/paste.h b/tools/ioemu/gui/bitmaps/paste.h
deleted file mode 100644 (file)
index f574dad..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: paste.h,v 1.1 2002/03/11 15:04:58 bdenney Exp $
-/////////////////////////////////////////////////////////////////////////
-#define BX_PASTE_BMAP_X 32
-#define BX_PASTE_BMAP_Y 32
-
-static unsigned char bx_paste_bmap[(BX_PASTE_BMAP_X*BX_PASTE_BMAP_Y)] = {
-  0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x10, 0x00, 0x20, 0x9a, 0x93, 0x03,
-  0x20, 0x66, 0x78, 0x04, 0xe0, 0xa5, 0xd3, 0x07, 0x20, 0x24, 0x54, 0x00,
-  0x20, 0xd8, 0x93, 0x03, 0x00, 0x80, 0x01, 0x00, 0x00, 0xc0, 0x02, 0x00,
-  0x00, 0x7c, 0x3f, 0x00, 0xc0, 0x83, 0xc1, 0x03, 0x20, 0x02, 0x40, 0x04,
-  0x20, 0x01, 0x80, 0x04, 0x20, 0x01, 0x80, 0x04, 0xa0, 0xff, 0xff, 0x05,
-  0x20, 0x00, 0x00, 0x04, 0x20, 0x00, 0x00, 0x04, 0x20, 0xf8, 0x3f, 0x04,
-  0x20, 0x08, 0x20, 0x04, 0x20, 0xe8, 0x2b, 0x04, 0x20, 0x08, 0x20, 0x04,
-  0x20, 0xe8, 0x2e, 0x04, 0x20, 0x08, 0x20, 0x04, 0x20, 0xe8, 0x39, 0x04,
-  0x20, 0x08, 0x24, 0x04, 0x20, 0x88, 0x20, 0x04, 0x20, 0xe8, 0x2f, 0x04,
-  0x20, 0x08, 0x20, 0x04, 0x20, 0xf8, 0x3f, 0x04, 0x20, 0x00, 0x00, 0x04,
-  0xc0, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, };
diff --git a/tools/ioemu/gui/bitmaps/paste.xpm b/tools/ioemu/gui/bitmaps/paste.xpm
deleted file mode 100644 (file)
index 5c83b01..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/* XPM */
-static char *paste_xpm[] = {
-/* width height num_colors chars_per_pixel */
-"    32    32        2            1",
-/* colors */
-". c None",
-"# c #000000",
-/* pixels */
-"................................",
-".....####...........#...........",
-".....#...#.##..###..#..###......",
-".....#...##..##....####...#.....",
-".....####.#..#.###..#.#####.....",
-".....#....#..#....#.#.#.........",
-".....#.....##.####..#..###......",
-"...............##...............",
-"..............##.#..............",
-"..........#####.######..........",
-"......####.....##.....####......",
-".....#...#............#...#.....",
-".....#..#..............#..#.....",
-".....#..#..............#..#.....",
-".....#.##################.#.....",
-".....#....................#.....",
-".....#....................#.....",
-".....#.....###########....#.....",
-".....#.....#.........#....#.....",
-".....#.....#.#####.#.#....#.....",
-".....#.....#.........#....#.....",
-".....#.....#.###.###.#....#.....",
-".....#.....#.........#....#.....",
-".....#.....#.####..###....#.....",
-".....#.....#......#..#....#.....",
-".....#.....#...#.....#....#.....",
-".....#.....#.#######.#....#.....",
-".....#.....#.........#....#.....",
-".....#.....###########....#.....",
-".....#....................#.....",
-"......####################......",
-"................................"
-};
diff --git a/tools/ioemu/gui/bitmaps/power.h b/tools/ioemu/gui/bitmaps/power.h
deleted file mode 100644 (file)
index ba72d6a..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: power.h,v 1.2 2001/10/03 13:10:37 bdenney Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-#define BX_POWER_BMAP_X 32
-#define BX_POWER_BMAP_Y 32
-
-static const unsigned char bx_power_bmap[(BX_POWER_BMAP_X * BX_POWER_BMAP_Y)/8] = {
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00,
-  0x24, 0x67, 0x66, 0x34, 0xa4, 0x28, 0x92, 0x48, 0x9a, 0xa8, 0xfa, 0x04,
-  0x82, 0x64, 0x09, 0x04, 0x07, 0xa3, 0x70, 0x0e, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0xf8, 0x03, 0x00, 0x00, 0xfe, 0x0f, 0x00, 0x00, 0x0f, 0x1e, 0x00,
-  0x80, 0x03, 0x38, 0x00, 0xc0, 0x00, 0x60, 0x00, 0xe0, 0xe0, 0xe0, 0x00,
-  0x60, 0xe0, 0xc0, 0x00, 0x70, 0xe0, 0xc0, 0x01, 0x30, 0xe0, 0x80, 0x01,
-  0x30, 0xe0, 0x80, 0x01, 0x30, 0xe0, 0x80, 0x01, 0x30, 0xe0, 0x80, 0x01,
-  0x30, 0xe0, 0x80, 0x01, 0x70, 0xe0, 0xc0, 0x01, 0x60, 0xe0, 0xc0, 0x00,
-  0xe0, 0xe0, 0xe0, 0x00, 0xc0, 0x00, 0x60, 0x00, 0x80, 0x03, 0x38, 0x00,
-  0x00, 0x0f, 0x1e, 0x00, 0x00, 0xfe, 0x0f, 0x00, 0x00, 0xf8, 0x03, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-  };
diff --git a/tools/ioemu/gui/bitmaps/power.xpm b/tools/ioemu/gui/bitmaps/power.xpm
deleted file mode 100644 (file)
index ff7e9e8..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/* XPM */
-static char *power_xpm[] = {
-/* width height num_colors chars_per_pixel */
-"    32    32        2            1",
-/* colors */
-". c None",
-"# c #000000",
-/* pixels */
-"................................",
-"................................",
-".####...........................",
-"..#..#..###..##..##..##...#.##..",
-"..#..#.#...#.#...#..#..#...#..#.",
-".#.##..#...#.#.#.#.#####..#.....",
-".#.....#..#..##.#..#......#.....",
-"###.....##...#.#....###..###....",
-"................................",
-"...........#######..............",
-".........###########............",
-"........####.....####...........",
-".......###.........###..........",
-"......##.............##.........",
-".....###.....###.....###........",
-".....##......###......##........",
-"....###......###......###.......",
-"....##.......###.......##.......",
-"....##.......###.......##.......",
-"....##.......###.......##.......",
-"....##.......###.......##.......",
-"....##.......###.......##.......",
-"....###......###......###.......",
-".....##......###......##........",
-".....###.....###.....###........",
-"......##.............##.........",
-".......###.........###..........",
-"........####.....####...........",
-".........###########............",
-"...........#######..............",
-"................................",
-"................................"
-};
diff --git a/tools/ioemu/gui/bitmaps/reset.h b/tools/ioemu/gui/bitmaps/reset.h
deleted file mode 100644 (file)
index 046f80a..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: reset.h,v 1.2 2001/10/03 13:10:37 bdenney Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-#define BX_RESET_BMAP_X 32
-#define BX_RESET_BMAP_Y 32
-
-static const unsigned char bx_reset_bmap[(BX_RESET_BMAP_X * BX_RESET_BMAP_Y)/8] = {
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x3c, 0x00, 0x00, 0x10,
-  0x48, 0x0c, 0xc7, 0x7c, 0x48, 0x92, 0x20, 0x11, 0x34, 0x1f, 0xf3, 0x09,
-  0x24, 0x41, 0x12, 0x48, 0x6e, 0xce, 0xe1, 0x30, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00,
-  0x00, 0xe0, 0x0f, 0x00, 0x00, 0xf0, 0x1f, 0x00, 0x00, 0xe0, 0x3f, 0x00,
-  0x00, 0xc7, 0x38, 0x00, 0x00, 0x87, 0x38, 0x00, 0x00, 0x07, 0x38, 0x00,
-  0x00, 0x07, 0x38, 0x00, 0x00, 0x07, 0x38, 0x00, 0x00, 0x07, 0x38, 0x00,
-  0x00, 0x07, 0x38, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0xfe, 0x1f, 0x00,
-  0x00, 0xfc, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-  };
diff --git a/tools/ioemu/gui/bitmaps/reset.xpm b/tools/ioemu/gui/bitmaps/reset.xpm
deleted file mode 100644 (file)
index d47ea6c..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/* XPM */
-static char *reset_xpm[] = {
-/* width height num_colors chars_per_pixel */
-"    32    32        2            1",
-/* colors */
-". c None",
-"# c #000000",
-/* pixels */
-"................................",
-".............................#..",
-"..####......................#...",
-"...#..#...##....###...##..#####.",
-"...#..#..#..#..#.....#..#...#...",
-"..#.##..#####...##..#####..#....",
-"..#..#..#.....#..#..#......#..#.",
-".###.##..###..###....###....##..",
-"................................",
-"................................",
-"................................",
-"................................",
-"................................",
-"...............#................",
-"..............##................",
-".............#######............",
-"............#########...........",
-".............#########..........",
-"........###...##...###..........",
-"........###....#...###..........",
-"........###........###..........",
-"........###........###..........",
-"........###........###..........",
-"........###........###..........",
-"........###........###..........",
-"........##############..........",
-".........############...........",
-"..........##########............",
-"................................",
-"................................",
-"................................",
-"................................"
-};
diff --git a/tools/ioemu/gui/bitmaps/snapshot.h b/tools/ioemu/gui/bitmaps/snapshot.h
deleted file mode 100644 (file)
index cced8ff..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: snapshot.h,v 1.2 2001/10/03 13:10:37 bdenney Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-#define BX_SNAPSHOT_BMAP_X 32
-#define BX_SNAPSHOT_BMAP_Y 32
-
-static const unsigned char bx_snapshot_bmap[(BX_SNAPSHOT_BMAP_X * BX_SNAPSHOT_BMAP_Y)/8] = {
-  0x00, 0x00, 0x20, 0x40, 0x77, 0xe6, 0xee, 0xec, 0x91, 0xa8, 0xa2, 0x52,
-  0x96, 0xac, 0xac, 0x52, 0x94, 0xaa, 0xa8, 0x52, 0xb7, 0xee, 0xae, 0xcc,
-  0x00, 0x20, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0x08, 0x10, 0x00,
-  0x7c, 0x0f, 0x10, 0x1f, 0xfa, 0x07, 0xa0, 0x2e, 0x42, 0x07, 0xa0, 0x50,
-  0xa3, 0x03, 0xc0, 0xe0, 0xff, 0xee, 0x77, 0xbf, 0x01, 0xf9, 0x9f, 0x40,
-  0x01, 0x1d, 0xb8, 0xa0, 0xff, 0xe5, 0xa7, 0xff, 0xff, 0xba, 0x5a, 0xff,
-  0xff, 0x55, 0xb5, 0xff, 0xff, 0x8d, 0xaa, 0xff, 0xff, 0x16, 0x55, 0xff,
-  0xff, 0xa2, 0x6a, 0xff, 0xff, 0x46, 0x55, 0xff, 0xff, 0xaa, 0x6a, 0xff,
-  0xff, 0x56, 0x55, 0xff, 0xfe, 0xae, 0x6a, 0x7f, 0x00, 0x55, 0xb5, 0x00,
-  0x00, 0xbd, 0xba, 0x00, 0x00, 0xfa, 0x5f, 0x00, 0x00, 0xe4, 0x27, 0x00,
-  0x00, 0x18, 0x18, 0x00, 0x00, 0xe0, 0x07, 0x00
-  };
diff --git a/tools/ioemu/gui/bitmaps/snapshot.xpm b/tools/ioemu/gui/bitmaps/snapshot.xpm
deleted file mode 100644 (file)
index c17305b..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/* XPM */
-static char *snapshot_xpm[] = {
-/* width height num_colors chars_per_pixel */
-"    32    32        2            1",
-/* colors */
-". c None",
-"# c #000000",
-/* pixels */
-".....................#........#.",
-"###.###..##..###.###.###..##.###",
-"#...#..#...#.#.#.#...#.#.#..#.#.",
-".##.#..#..##.#.#..##.#.#.#..#.#.",
-"..#.#..#.#.#.#.#...#.#.#.#..#.#.",
-"###.##.#.###.###.###.#.#..##..##",
-".............#..................",
-"............########............",
-"...........#........#...........",
-"..#####.####........#...#####...",
-".#.########..........#.#.###.#..",
-".#....#.###..........#.#....#.#.",
-"##...#.###............##.....###",
-"########.###.######.###.######.#",
-"#.......#..##########..#......#.",
-"#.......#.###......###.#.....#.#",
-"#########.#..######..#.#########",
-"########.#.###.#.#.##.#.########",
-"#########.#.#.#.#.#.##.#########",
-"#########.##...#.#.#.#.#########",
-"########.##.#...#.#.#.#.########",
-"########.#...#.#.#.#.##.########",
-"########.##...#.#.#.#.#.########",
-"########.#.#.#.#.#.#.##.########",
-"########.##.#.#.#.#.#.#.########",
-".#######.###.#.#.#.#.##.#######.",
-"........#.#.#.#.#.#.##.#........",
-"........#.####.#.#.###.#........",
-".........#.##########.#.........",
-"..........#..######..#..........",
-"...........##......##...........",
-".............######............."
-};
diff --git a/tools/ioemu/gui/bitmaps/userbutton.h b/tools/ioemu/gui/bitmaps/userbutton.h
deleted file mode 100644 (file)
index c93f506..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: userbutton.h,v 1.1 2002/08/09 06:16:43 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-#define BX_USER_BMAP_X 32
-#define BX_USER_BMAP_Y 32
-
-static const unsigned char bx_user_bmap[BX_USER_BMAP_X*BX_USER_BMAP_Y/8] = {
-  0x00, 0x00, 0x00, 0x00, 0x84, 0x78, 0x9e, 0x07, 0x84, 0x04, 0x82, 0x08, 
-  0x84, 0x04, 0x82, 0x08, 0x84, 0x38, 0x9e, 0x07, 0x84, 0x40, 0x82, 0x01, 
-  0x84, 0x40, 0x82, 0x06, 0x78, 0x3c, 0x9e, 0x08, 0x00, 0x00, 0x00, 0x00, 
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1c, 
-  0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x80, 0x00, 
-  0x00, 0x00, 0x80, 0x00, 0xfe, 0xff, 0xff, 0x3f, 0x02, 0x00, 0x00, 0x20, 
-  0xaa, 0xaa, 0x2a, 0x2a, 0x02, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00, 0x20, 
-  0xaa, 0xaa, 0xaa, 0x2a, 0x52, 0x55, 0x11, 0x25, 0xaa, 0xaa, 0xaa, 0x2a, 
-  0x52, 0x55, 0x01, 0x25, 0xaa, 0xaa, 0x82, 0x2a, 0x52, 0x55, 0x11, 0x25, 
-  0xaa, 0xbf, 0xaa, 0x2a, 0x02, 0x00, 0x00, 0x20, 0xfe, 0xff, 0xff, 0x3f, 
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-  };
diff --git a/tools/ioemu/gui/bitmaps/userbutton.xpm b/tools/ioemu/gui/bitmaps/userbutton.xpm
deleted file mode 100644 (file)
index a5d1f99..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/* XPM */
-static char *userbutton_xpm[] = {
-/* columns rows colors chars-per-pixel */
-"32 32 2 1",
-". c None",
-"# c #000000",
-/* pixels */
-"................................",
-"..#....#...####..####..####.....",
-"..#....#..#......#.....#...#....",
-"..#....#..#......#.....#...#....",
-"..#....#...###...####..####.....",
-"..#....#......#..#.....##.......",
-"..#....#......#..#.....#.##.....",
-"...####...####...####..#...#....",
-"................................",
-"................................",
-".............................#..",
-"..........................###...",
-".........................#......",
-"........................#.......",
-".......................#........",
-".......................#........",
-".#############################..",
-".#...........................#..",
-".#.#.#.#.#.#.#.#.#.#.#...#.#.#..",
-".#...........................#..",
-".#...........................#..",
-".#.#.#.#.#.#.#.#.#.#.#.#.#.#.#..",
-".#..#.#.#.#.#.#.#...#...#.#..#..",
-".#.#.#.#.#.#.#.#.#.#.#.#.#.#.#..",
-".#..#.#.#.#.#.#.#.......#.#..#..",
-".#.#.#.#.#.#.#.#.#.....#.#.#.#..",
-".#..#.#.#.#.#.#.#...#...#.#..#..",
-".#.#.#.#######.#.#.#.#.#.#.#.#..",
-".#...........................#..",
-".#############################..",
-"................................",
-"................................"
-};
diff --git a/tools/ioemu/gui/gui.cc b/tools/ioemu/gui/gui.cc
deleted file mode 100644 (file)
index d3c2383..0000000
+++ /dev/null
@@ -1,601 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: gui.cc,v 1.73 2003/12/18 20:04:48 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-#include <signal.h>
-#include "bochs.h"
-#include "gui/bitmaps/floppya.h"
-#include "gui/bitmaps/floppyb.h"
-#include "gui/bitmaps/mouse.h"
-#include "gui/bitmaps/reset.h"
-#include "gui/bitmaps/power.h"
-#include "gui/bitmaps/snapshot.h"
-#include "gui/bitmaps/copy.h"
-#include "gui/bitmaps/paste.h"
-#include "gui/bitmaps/configbutton.h"
-#include "gui/bitmaps/cdromd.h"
-#include "gui/bitmaps/userbutton.h"
-#if BX_WITH_MACOS
-#  include <Disks.h>
-#endif
-
-bx_gui_c *bx_gui = NULL;
-
-#define BX_GUI_THIS bx_gui->
-#define LOG_THIS BX_GUI_THIS
-
-bx_gui_c::bx_gui_c(void)
-{
-  put("GUI"); // Init in specific_init
-  settype(GUILOG);
-}
-
-bx_gui_c::~bx_gui_c()
-{
-}
-
-  void
-bx_gui_c::init(int argc, char **argv, unsigned tilewidth, unsigned tileheight)
-{
-  specific_init(argc, argv, tilewidth, tileheight, BX_HEADER_BAR_Y);
-
-  // Define some bitmaps to use in the headerbar
-  BX_GUI_THIS floppyA_bmap_id = create_bitmap(bx_floppya_bmap,
-                          BX_FLOPPYA_BMAP_X, BX_FLOPPYA_BMAP_Y);
-  BX_GUI_THIS floppyA_eject_bmap_id = create_bitmap(bx_floppya_eject_bmap,
-                          BX_FLOPPYA_BMAP_X, BX_FLOPPYA_BMAP_Y);
-  BX_GUI_THIS floppyB_bmap_id = create_bitmap(bx_floppyb_bmap,
-                          BX_FLOPPYB_BMAP_X, BX_FLOPPYB_BMAP_Y);
-  BX_GUI_THIS floppyB_eject_bmap_id = create_bitmap(bx_floppyb_eject_bmap,
-                          BX_FLOPPYB_BMAP_X, BX_FLOPPYB_BMAP_Y);
-  BX_GUI_THIS cdromD_bmap_id = create_bitmap(bx_cdromd_bmap,
-                          BX_CDROMD_BMAP_X, BX_CDROMD_BMAP_Y);
-  BX_GUI_THIS cdromD_eject_bmap_id = create_bitmap(bx_cdromd_eject_bmap,
-                          BX_CDROMD_BMAP_X, BX_CDROMD_BMAP_Y);
-  BX_GUI_THIS mouse_bmap_id = create_bitmap(bx_mouse_bmap,
-                          BX_MOUSE_BMAP_X, BX_MOUSE_BMAP_Y);
-  BX_GUI_THIS nomouse_bmap_id = create_bitmap(bx_nomouse_bmap,
-                          BX_MOUSE_BMAP_X, BX_MOUSE_BMAP_Y);
-
-
-  BX_GUI_THIS power_bmap_id = create_bitmap(bx_power_bmap, BX_POWER_BMAP_X, BX_POWER_BMAP_Y);
-  BX_GUI_THIS reset_bmap_id = create_bitmap(bx_reset_bmap, BX_RESET_BMAP_X, BX_RESET_BMAP_Y);
-  BX_GUI_THIS snapshot_bmap_id = create_bitmap(bx_snapshot_bmap, BX_SNAPSHOT_BMAP_X, BX_SNAPSHOT_BMAP_Y);
-  BX_GUI_THIS copy_bmap_id = create_bitmap(bx_copy_bmap, BX_COPY_BMAP_X, BX_COPY_BMAP_Y);
-  BX_GUI_THIS paste_bmap_id = create_bitmap(bx_paste_bmap, BX_PASTE_BMAP_X, BX_PASTE_BMAP_Y);
-  BX_GUI_THIS config_bmap_id = create_bitmap(bx_config_bmap, BX_CONFIG_BMAP_X, BX_CONFIG_BMAP_Y);
-  BX_GUI_THIS user_bmap_id = create_bitmap(bx_user_bmap, BX_USER_BMAP_X, BX_USER_BMAP_Y);
-
-
-  // Add the initial bitmaps to the headerbar, and enable callback routine, for use
-  // when that bitmap is clicked on
-
-  // Floppy A:
-  BX_GUI_THIS floppyA_status = DEV_floppy_get_media_status(0);
-  if (BX_GUI_THIS floppyA_status)
-    BX_GUI_THIS floppyA_hbar_id = headerbar_bitmap(BX_GUI_THIS floppyA_bmap_id,
-                          BX_GRAVITY_LEFT, floppyA_handler);
-  else
-    BX_GUI_THIS floppyA_hbar_id = headerbar_bitmap(BX_GUI_THIS floppyA_eject_bmap_id,
-                          BX_GRAVITY_LEFT, floppyA_handler);
-
-  // Floppy B:
-  BX_GUI_THIS floppyB_status = DEV_floppy_get_media_status(1);
-  if (BX_GUI_THIS floppyB_status)
-    BX_GUI_THIS floppyB_hbar_id = headerbar_bitmap(BX_GUI_THIS floppyB_bmap_id,
-                          BX_GRAVITY_LEFT, floppyB_handler);
-  else
-    BX_GUI_THIS floppyB_hbar_id = headerbar_bitmap(BX_GUI_THIS floppyB_eject_bmap_id,
-                          BX_GRAVITY_LEFT, floppyB_handler);
-
-  // CDROM, 
-  // valgrinds says that the harddrive object is not be initialised yet, 
-  // so we just set the bitmap to ejected for now
-#if 0
-  if (DEV_hd_present()) {
-    Bit32u handle = DEV_hd_get_first_cd_handle();
-    BX_GUI_THIS cdromD_status = DEV_hd_get_cd_media_status(handle);
-  }
-
-  if (BX_GUI_THIS cdromD_status)
-    BX_GUI_THIS cdromD_hbar_id = headerbar_bitmap(BX_GUI_THIS cdromD_bmap_id,
-                          BX_GRAVITY_LEFT, cdromD_handler);
-  else
-#endif
-    BX_GUI_THIS cdromD_hbar_id = headerbar_bitmap(BX_GUI_THIS cdromD_eject_bmap_id,
-                          BX_GRAVITY_LEFT, cdromD_handler);
-
-  // Mouse button
-  if (bx_options.Omouse_enabled->get ())
-    BX_GUI_THIS mouse_hbar_id = headerbar_bitmap(BX_GUI_THIS mouse_bmap_id,
-                          BX_GRAVITY_LEFT, toggle_mouse_enable);
-  else
-    BX_GUI_THIS mouse_hbar_id = headerbar_bitmap(BX_GUI_THIS nomouse_bmap_id,
-                          BX_GRAVITY_LEFT, toggle_mouse_enable);
-
-  // These are the buttons on the right side.  They are created in order
-  // of right to left.
-
-  // Power button
-  BX_GUI_THIS power_hbar_id = headerbar_bitmap(BX_GUI_THIS power_bmap_id,
-                          BX_GRAVITY_RIGHT, power_handler);
-  // Reset button
-  BX_GUI_THIS reset_hbar_id = headerbar_bitmap(BX_GUI_THIS reset_bmap_id,
-                          BX_GRAVITY_RIGHT, reset_handler);
-  // Configure button
-  BX_GUI_THIS config_hbar_id = headerbar_bitmap(BX_GUI_THIS config_bmap_id,
-                          BX_GRAVITY_RIGHT, config_handler);
-  // Snapshot button
-  BX_GUI_THIS snapshot_hbar_id = headerbar_bitmap(BX_GUI_THIS snapshot_bmap_id,
-                          BX_GRAVITY_RIGHT, snapshot_handler);
-  // Paste button
-  BX_GUI_THIS paste_hbar_id = headerbar_bitmap(BX_GUI_THIS paste_bmap_id,
-                          BX_GRAVITY_RIGHT, paste_handler);
-  // Copy button
-  BX_GUI_THIS copy_hbar_id = headerbar_bitmap(BX_GUI_THIS copy_bmap_id,
-                          BX_GRAVITY_RIGHT, copy_handler);
-  // User button
-  BX_GUI_THIS user_hbar_id = headerbar_bitmap(BX_GUI_THIS user_bmap_id,
-                          BX_GRAVITY_RIGHT, userbutton_handler);
-
-  if(bx_options.Otext_snapshot_check->get()) {
-    bx_pc_system.register_timer(this, bx_gui_c::snapshot_checker, (unsigned) 1000000, 1, 1, "snap_chk");
-  }
-
-  BX_GUI_THIS charmap_updated = 0;
-
-  show_headerbar();
-}
-
-void
-bx_gui_c::update_drive_status_buttons (void) {
-  BX_GUI_THIS floppyA_status = 
-    DEV_floppy_get_media_status(0)
-    && bx_options.floppya.Ostatus->get ();
-  BX_GUI_THIS floppyB_status = 
-      DEV_floppy_get_media_status(1)
-      && bx_options.floppyb.Ostatus->get ();
-  Bit32u handle = DEV_hd_get_first_cd_handle();
-  BX_GUI_THIS cdromD_status = DEV_hd_get_cd_media_status(handle);
-  if (BX_GUI_THIS floppyA_status)
-    replace_bitmap(BX_GUI_THIS floppyA_hbar_id, BX_GUI_THIS floppyA_bmap_id);
-  else {
-#if BX_WITH_MACOS
-    // If we are using the Mac floppy driver, eject the disk
-    // from the floppy drive.  This doesn't work in MacOS X.
-    if (!strcmp(bx_options.floppya.Opath->getptr (), SuperDrive))
-      DiskEject(1);
-#endif
-    replace_bitmap(BX_GUI_THIS floppyA_hbar_id, BX_GUI_THIS floppyA_eject_bmap_id);
-    }
-  if (BX_GUI_THIS floppyB_status)
-    replace_bitmap(BX_GUI_THIS floppyB_hbar_id, BX_GUI_THIS floppyB_bmap_id);
-  else {
-#if BX_WITH_MACOS
-    // If we are using the Mac floppy driver, eject the disk
-    // from the floppy drive.  This doesn't work in MacOS X.
-    if (!strcmp(bx_options.floppyb.Opath->getptr (), SuperDrive))
-      DiskEject(1);
-#endif
-    replace_bitmap(BX_GUI_THIS floppyB_hbar_id, BX_GUI_THIS floppyB_eject_bmap_id);
-    }
-  if (BX_GUI_THIS cdromD_status)
-    replace_bitmap(BX_GUI_THIS cdromD_hbar_id, BX_GUI_THIS cdromD_bmap_id);
-  else {
-    replace_bitmap(BX_GUI_THIS cdromD_hbar_id, BX_GUI_THIS cdromD_eject_bmap_id);
-    }
-}
-
-  void
-bx_gui_c::floppyA_handler(void)
-{
-  if (bx_options.floppya.Odevtype->get() == BX_FLOPPY_NONE)
-    return; // no primary floppy device present
-#ifdef WIN32
-  if (strcmp(bx_options.Osel_displaylib->get_choice(bx_options.Osel_displaylib->get()),
-              "rfb")) {
-    // instead of just toggling the status, call win32dialog to bring up
-    // a dialog asking what disk image you want to switch to.
-    int ret = SIM->ask_param (BXP_FLOPPYA_PATH);
-    if (ret > 0) {
-      BX_GUI_THIS update_drive_status_buttons ();
-    }
-    return;
-  }
-#endif
-  BX_GUI_THIS floppyA_status = !BX_GUI_THIS floppyA_status;
-  DEV_floppy_set_media_status(0, BX_GUI_THIS floppyA_status);
-  BX_GUI_THIS update_drive_status_buttons ();
-}
-
-  void
-bx_gui_c::floppyB_handler(void)
-{
-  if (bx_options.floppyb.Odevtype->get() == BX_FLOPPY_NONE)
-    return; // no secondary floppy device present
-#ifdef WIN32
-  if (strcmp(bx_options.Osel_displaylib->get_choice(bx_options.Osel_displaylib->get()),
-              "rfb")) {
-    // instead of just toggling the status, call win32dialog to bring up
-    // a dialog asking what disk image you want to switch to.
-    int ret = SIM->ask_param (BXP_FLOPPYB_PATH);
-    if (ret > 0) {
-      BX_GUI_THIS update_drive_status_buttons ();
-    }
-    return;
-  }
-#endif
-  BX_GUI_THIS floppyB_status = !BX_GUI_THIS floppyB_status;
-  DEV_floppy_set_media_status(1, BX_GUI_THIS floppyB_status);
-  BX_GUI_THIS update_drive_status_buttons ();
-}
-
-  void
-bx_gui_c::cdromD_handler(void)
-{
-  Bit32u handle = DEV_hd_get_first_cd_handle();
-  if (!strcmp(bx_options.Osel_config->get_choice(bx_options.Osel_config->get()),
-              "wx")) {
-    // instead of just toggling the status, call wxWindows to bring up 
-    // a dialog asking what disk image you want to switch to.
-    // BBD: for now, find the first cdrom and call ask_param on that.
-    // Since we could have multiple cdroms now, maybe we should be adding
-    // one cdrom button for each?
-    bx_param_c *cdrom = SIM->get_first_cdrom ();
-    if (cdrom == NULL)
-      return;  // no cdrom found
-    int ret = SIM->ask_param (cdrom->get_id ());
-    if (ret < 0) return;  // cancelled
-    // eject and then insert the disk.  If the new path is invalid,
-    // the status will return 0.
-    unsigned status = DEV_hd_set_cd_media_status(handle, 0);
-    printf ("eject disk, new_status is %d\n", status);
-    status = DEV_hd_set_cd_media_status(handle, 1);
-    printf ("insert disk, new_status is %d\n", status);
-    fflush (stdout);
-    BX_GUI_THIS cdromD_status = status;
-  } else {
-    BX_GUI_THIS cdromD_status =
-      DEV_hd_set_cd_media_status(handle, !BX_GUI_THIS cdromD_status);
-  }
-  BX_GUI_THIS update_drive_status_buttons ();
-}
-
-  void
-bx_gui_c::reset_handler(void)
-{
-  BX_INFO(( "system RESET callback." ));
-  bx_pc_system.ResetSignal( PCS_SET ); /* XXX is this right? */
-  for (int i=0; i<BX_SMP_PROCESSORS; i++)
-      BX_CPU(i)->reset(BX_RESET_HARDWARE);
-}
-
-#ifdef BX_USE_VMX
-char xm_destroy[PATH_MAX];
-#endif
-
-  void
-bx_gui_c::power_handler(void)
-{
-  // the user pressed power button, so there's no doubt they want bochs
-  // to quit.  Change panics to fatal for the GUI and then do a panic.
-  bx_user_quit = 1;
-  LOG_THIS setonoff(LOGLEV_PANIC, ACT_FATAL);
-  BX_INFO(("POWER button turned off."));
-  // shouldn't reach this point, but if you do, QUIT!!!
-  fprintf (stderr, "Bochs is exiting because you pressed the power button.\n");
-  snprintf(xm_destroy, PATH_MAX, "xm destroy %d", domid);
-  BX_INFO(("executing: %s\n", xm_destroy));
-  if (system(xm_destroy) != 0) {
-        BX_PANIC(("failed\n"));
-  }
-  BX_EXIT (1);
-}
-
-Bit32s
-bx_gui_c::make_text_snapshot (char **snapshot, Bit32u *length)
-{
-  Bit8u* raw_snap = NULL;
-  char *clean_snap;
-  unsigned line_addr, txt_addr, txHeight, txWidth;
-
-  DEV_vga_get_text_snapshot(&raw_snap, &txHeight, &txWidth);
-  if (txHeight <= 0) return -1;
-  clean_snap = (char*) malloc(txHeight*(txWidth+2)+1);
-  txt_addr = 0;
-  for (unsigned i=0; i<txHeight; i++) {
-    line_addr = i * txWidth * 2;
-    for (unsigned j=0; j<(txWidth*2); j+=2) {
-      clean_snap[txt_addr++] = raw_snap[line_addr+j];
-    }
-    while ((txt_addr > 0) && (clean_snap[txt_addr-1] == ' ')) txt_addr--;
-#ifdef WIN32
-    if(!(bx_options.Otext_snapshot_check->get())) {
-      clean_snap[txt_addr++] = 13;
-    }
-#endif
-    clean_snap[txt_addr++] = 10;
-  }
-  clean_snap[txt_addr] = 0;
-  *snapshot = clean_snap;
-  *length = txt_addr;
-  return 0;
-}
-
-// create a text snapshot and copy to the system clipboard.  On guis that
-// we haven't figured out how to support yet, dump to a file instead.
-  void
-bx_gui_c::copy_handler(void)
-{
-  Bit32u len;
-  char *text_snapshot;
-  if (make_text_snapshot (&text_snapshot, &len) < 0) {
-    BX_INFO(( "copy button failed, mode not implemented"));
-    return;
-  }
-  if (!BX_GUI_THIS set_clipboard_text(text_snapshot, len)) {
-    // platform specific code failed, use portable code instead
-    FILE *fp = fopen("copy.txt", "w");
-    fwrite(text_snapshot, 1, len, fp);
-    fclose(fp);
-  }
-  free(text_snapshot);
-}
-
-// Check the current text snapshot against file snapchk.txt.
-  void
-bx_gui_c::snapshot_checker(void * this_ptr)
-{
-  char filename[BX_PATHNAME_LEN];
-  strcpy(filename,"snapchk.txt");
-  FILE *fp = fopen(filename, "rb");
-  if(fp) {
-    char *text_snapshot;
-    Bit32u len;
-    if (make_text_snapshot (&text_snapshot, &len) < 0) {
-      return;
-    }
-    char *compare_snapshot = (char *) malloc((len+1) * sizeof(char));
-    fread(compare_snapshot, 1, len, fp);
-    fclose(fp);
-    strcpy(filename,"snapmask.txt");
-    fp=fopen(filename, "rb");
-    if(fp) {
-      char *mask_snapshot = (char *) malloc((len+1) * sizeof(char));
-      unsigned i;
-      bx_bool flag = 1;
-      fread(mask_snapshot, 1, len, fp);
-      fclose(fp);
-      for(i=0;i<len;i++) {
-       if((text_snapshot[i] != compare_snapshot[i]) &&
-          (compare_snapshot[i] == mask_snapshot[i])) {
-         flag = 0;
-         break;
-       }
-      }
-      if(flag) {
-       if(!memcmp(text_snapshot,compare_snapshot,len)) {
-         BX_PASS(("Test Passed."));
-       } else {
-         BX_PASS(("Test Passed with Mask."));
-       }
-      }
-    } else {
-      if(!memcmp(text_snapshot,compare_snapshot,len)) {
-       BX_PASS(("Test Passed."));
-      }
-    }
-    free(compare_snapshot);
-    free(text_snapshot);
-  }
-}
-
-// create a text snapshot and dump it to a file
-  void
-bx_gui_c::snapshot_handler(void)
-{
-  char *text_snapshot;
-  Bit32u len;
-  if (make_text_snapshot (&text_snapshot, &len) < 0) {
-    BX_ERROR(( "snapshot button failed, mode not implemented"));
-    return;
-  }
-  //FIXME
-  char filename[BX_PATHNAME_LEN];
-#ifdef WIN32
-  if (strcmp(bx_options.Osel_displaylib->get_choice(bx_options.Osel_displaylib->get()),
-              "rfb")) {
-#else
-  if (!strcmp(bx_options.Osel_config->get_choice(bx_options.Osel_config->get()),
-              "wx")) {
-#endif
-    int ret = SIM->ask_filename (filename, sizeof(filename),
-                                 "Save snapshot as...", "snapshot.txt",
-                                 bx_param_string_c::SAVE_FILE_DIALOG);
-    if (ret < 0) { // cancelled
-      free(text_snapshot);
-      return;
-    }
-  } else {
-    strcpy (filename, "snapshot.txt");
-  }
-  FILE *fp = fopen(filename, "wb");
-  fwrite(text_snapshot, 1, len, fp);
-  fclose(fp);
-  free(text_snapshot);
-}
-
-// Read ASCII chars from the system clipboard and paste them into bochs.
-// Note that paste cannot work with the key mapping tables loaded.
-  void
-bx_gui_c::paste_handler(void)
-{
-  Bit32s nbytes;
-  Bit8u *bytes;
-  if (!bx_keymap.isKeymapLoaded ()) {
-    BX_ERROR (("keyboard_mapping disabled, so paste cannot work"));
-    return;
-  }
-  if (!BX_GUI_THIS get_clipboard_text(&bytes, &nbytes)) {
-    BX_ERROR (("paste not implemented on this platform"));
-    return;
-  }
-  BX_INFO (("pasting %d bytes", nbytes));
-  DEV_kbd_paste_bytes (bytes, nbytes);
-}
-
-
-  void
-bx_gui_c::config_handler(void)
-{
-  if (strcmp(bx_options.Osel_displaylib->get_choice(bx_options.Osel_displaylib->get()),
-              "rfb")) {
-    SIM->configuration_interface (NULL, CI_RUNTIME_CONFIG);
-  }
-}
-
-  void
-bx_gui_c::toggle_mouse_enable(void)
-{
-  int old = bx_options.Omouse_enabled->get ();
-  BX_DEBUG (("toggle mouse_enabled, now %d", !old));
-  bx_options.Omouse_enabled->set (!old);
-}
-
-  void
-bx_gui_c::userbutton_handler(void)
-{
-  unsigned shortcut[4];
-  unsigned p;
-  char *user_shortcut;
-  int i, len, ret = 1;
-
-  len = 0;
-#ifdef WIN32
-  if (strcmp(bx_options.Osel_displaylib->get_choice(bx_options.Osel_displaylib->get()),
-              "rfb")) {
-#else
-  if (!strcmp(bx_options.Osel_config->get_choice(bx_options.Osel_config->get()),
-              "wx")) {
-#endif
-    ret = SIM->ask_param (BXP_USER_SHORTCUT);
-  }
-  user_shortcut = bx_options.Ouser_shortcut->getptr();
-  if ((ret > 0) && user_shortcut[0] && (strcmp(user_shortcut, "none"))) {
-    len = 0;
-    p = 0;
-    while ((p < strlen(user_shortcut)) && (len < 3)) {
-      if (!strncmp(user_shortcut+p, "alt", 3)) {
-        shortcut[len++] = BX_KEY_ALT_L;
-        p += 3;
-      } else if (!strncmp(user_shortcut+p, "ctrl", 4)) {
-        shortcut[len++] = BX_KEY_CTRL_L;
-        p += 4;
-      } else if (!strncmp(user_shortcut+p, "del", 3)) {
-        shortcut[len++] = BX_KEY_DELETE;
-        p += 3;
-      } else if (!strncmp(user_shortcut+p, "esc", 3)) {
-        shortcut[len++] = BX_KEY_ESC;
-        p += 3;
-      } else if (!strncmp(user_shortcut+p, "f1", 2)) {
-        shortcut[len++] = BX_KEY_F1;
-        p += 2;
-      } else if (!strncmp(user_shortcut+p, "f4", 2)) {
-        shortcut[len++] = BX_KEY_F4;
-        p += 2;
-      } else if (!strncmp(user_shortcut+p, "tab", 3)) {
-        shortcut[len++] = BX_KEY_TAB;
-        p += 3;
-      } else if (!strncmp(user_shortcut+p, "win", 3)) {
-        shortcut[len++] = BX_KEY_WIN_L;
-        p += 3;
-      } else if (!strncmp(user_shortcut+p, "bksp", 4)) {
-        shortcut[len++] = BX_KEY_BACKSPACE;
-        p += 4;
-      } else {
-        BX_ERROR(("Unknown shortcut %s ignored", user_shortcut));
-        return;
-      }
-    }
-    i = 0;
-    while (i < len) {
-      DEV_kbd_gen_scancode(shortcut[i++]);
-    }
-    i--;
-    while (i >= 0) {
-      DEV_kbd_gen_scancode(shortcut[i--] | BX_KEY_RELEASED);
-    }
-  }
-}
-
-  void
-bx_gui_c::mouse_enabled_changed (bx_bool val)
-{
-  // This is only called when SIM->get_init_done is 1.  Note that VAL
-  // is the new value of mouse_enabled, which may not match the old
-  // value which is still in bx_options.Omouse_enabled->get ().
-  BX_DEBUG (("replacing the mouse bitmaps"));
-  if (val)
-    BX_GUI_THIS replace_bitmap(BX_GUI_THIS mouse_hbar_id, BX_GUI_THIS mouse_bmap_id);
-  else
-    BX_GUI_THIS replace_bitmap(BX_GUI_THIS mouse_hbar_id, BX_GUI_THIS nomouse_bmap_id);
-  // give the GUI a chance to respond to the event.  Most guis will hide
-  // the native mouse cursor and do something to trap the mouse inside the
-  // bochs VGA display window.
-  BX_GUI_THIS mouse_enabled_changed_specific (val);
-}
-
-void
-bx_gui_c::init_signal_handlers ()
-{
-#if BX_GUI_SIGHANDLER
-  if (bx_gui_sighandler) 
-  {
-    Bit32u mask = bx_gui->get_sighandler_mask ();
-    for (Bit32u sig=0; sig<32; sig++)
-    {
-      if (mask & (1<<sig))
-        signal (sig, bx_signal_handler);
-    }
-  }
-#endif
-}
-
-  void
-bx_gui_c::set_text_charmap(Bit8u *fbuffer)
-{
-  memcpy(& BX_GUI_THIS vga_charmap, fbuffer, 0x2000);
-  for (unsigned i=0; i<256; i++) BX_GUI_THIS char_changed[i] = 1;
-  BX_GUI_THIS charmap_updated = 1;
-}
-
-  void
-bx_gui_c::set_text_charbyte(Bit16u address, Bit8u data)
-{
-  BX_GUI_THIS vga_charmap[address] = data;
-  BX_GUI_THIS char_changed[address >> 5] = 1;
-  BX_GUI_THIS charmap_updated = 1;
-}
diff --git a/tools/ioemu/gui/gui.h b/tools/ioemu/gui/gui.h
deleted file mode 100644 (file)
index 14a44ca..0000000
+++ /dev/null
@@ -1,352 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: gui.h,v 1.40 2003/06/28 08:04:31 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-typedef struct {
-  Bit8u cs_start;
-  Bit8u cs_end;
-  Bit16u line_offset;
-  Bit16u line_compare;
-  Bit8u h_panning;
-  Bit8u v_panning;
-  bx_bool line_graphics;
-} bx_vga_tminfo_t;
-
-
-BOCHSAPI extern class bx_gui_c *bx_gui;
-
-
-// The bx_gui_c class provides data and behavior that is common to
-// all guis.  Each gui implementation will override the abstract methods.
-class BOCHSAPI bx_gui_c : public logfunctions {
-public:
-  bx_gui_c (void);
-  virtual ~bx_gui_c ();
-  // Define the following functions in the module for your particular GUI
-  // (x.cc, beos.cc, ...)
-  virtual void specific_init(int argc, char **argv,
-                 unsigned x_tilesize, unsigned y_tilesize, unsigned header_bar_y) = 0;
-  virtual void text_update(Bit8u *old_text, Bit8u *new_text,
-                          unsigned long cursor_x, unsigned long cursor_y,
-                          bx_vga_tminfo_t tm_info, unsigned rows) = 0;
-  virtual void graphics_tile_update(Bit8u *snapshot, unsigned x, unsigned y) = 0;
-  virtual void handle_events(void) = 0;
-  virtual void flush(void) = 0;
-  virtual void clear_screen(void) = 0;
-  virtual bx_bool palette_change(unsigned index, unsigned red, unsigned green, unsigned blue) = 0;
-  virtual void dimension_update(unsigned x, unsigned y, unsigned fheight=0, unsigned fwidth=0, unsigned bpp=8) = 0;
-  virtual unsigned create_bitmap(const unsigned char *bmap, unsigned xdim, unsigned ydim) = 0;
-  virtual unsigned headerbar_bitmap(unsigned bmap_id, unsigned alignment, void (*f)(void)) = 0;
-  virtual void replace_bitmap(unsigned hbar_id, unsigned bmap_id) = 0;
-  virtual void show_headerbar(void) = 0;
-  virtual int get_clipboard_text(Bit8u **bytes, Bit32s *nbytes)  = 0;
-  virtual int set_clipboard_text(char *snapshot, Bit32u len) = 0;
-  virtual void mouse_enabled_changed_specific (bx_bool val) = 0;
-  virtual void exit(void) = 0;
-  // set_display_mode() changes the mode between the configuration interface
-  // and the simulation.  This is primarily intended for display libraries
-  // which have a full-screen mode such as SDL, term, and svgalib.  The display
-  // mode is set to DISP_MODE_CONFIG before displaying any configuration menus,
-  // for panics that requires user input, when entering the debugger, etc.  It
-  // is set to DISP_MODE_SIM when the Bochs simulation resumes.  The
-  // enum is defined in gui/siminterface.h.
-  virtual void set_display_mode (disp_mode_t newmode) { /* default=no action*/ }
-  // These are only needed for the term gui. For all other guis they will
-  // have no effect.
-  // returns 32-bit bitmask in which 1 means the GUI should handle that signal
-  virtual Bit32u get_sighandler_mask () {return 0;}
-  // called when registered signal arrives
-  virtual void sighandler (int sig) {}
-#if BX_USE_IDLE_HACK
-  // this is called from the CPU model when the HLT instruction is executed.
-  virtual void sim_is_idle(void) {}
-#endif
-
-  // The following function(s) are defined already, and your
-  // GUI code calls them
-  static void key_event(Bit32u key);
-  static void set_text_charmap(Bit8u *fbuffer);
-  static void set_text_charbyte(Bit16u address, Bit8u data);
-
-  void init(int argc, char **argv,
-                 unsigned x_tilesize, unsigned y_tilesize);
-  void update_drive_status_buttons (void);
-  static void     mouse_enabled_changed (bx_bool val);
-  static void init_signal_handlers ();
-
-
-protected:
-  // And these are defined and used privately in gui.cc
-  static void floppyA_handler(void);
-  static void floppyB_handler(void);
-  static void cdromD_handler(void);
-  static void reset_handler(void);
-  static void power_handler(void);
-  static void copy_handler(void);
-  static void paste_handler(void);
-  static void snapshot_handler(void);
-  static void snapshot_checker(void *);
-  static void config_handler(void);
-  static void toggle_mouse_enable(void);
-  static void userbutton_handler(void);
-  static Bit32s make_text_snapshot (char **snapshot, Bit32u *length);
-
-  bx_bool floppyA_status;
-  bx_bool floppyB_status;
-  bx_bool cdromD_status;
-  unsigned floppyA_bmap_id, floppyA_eject_bmap_id, floppyA_hbar_id;
-  unsigned floppyB_bmap_id, floppyB_eject_bmap_id, floppyB_hbar_id;
-  unsigned cdromD_bmap_id, cdromD_eject_bmap_id, cdromD_hbar_id;
-  unsigned power_bmap_id,    power_hbar_id;
-  unsigned reset_bmap_id,    reset_hbar_id;
-  unsigned copy_bmap_id, copy_hbar_id;
-  unsigned paste_bmap_id, paste_hbar_id;
-  unsigned snapshot_bmap_id, snapshot_hbar_id;
-  unsigned config_bmap_id, config_hbar_id;
-  unsigned mouse_bmap_id, nomouse_bmap_id, mouse_hbar_id;
-  unsigned user_bmap_id, user_hbar_id;
-
-  unsigned char vga_charmap[0x2000];
-  bx_bool charmap_updated;
-  bx_bool char_changed[256];
-  disp_mode_t disp_mode;
-  };
-
-
-// Add this macro in the class declaration of each GUI, to define all the
-// required virtual methods.  Example:
-//   
-//    class bx_rfb_gui_c : public bx_gui_c {
-//    public:
-//      bx_rfb_gui_c (void) {}
-//      DECLARE_GUI_VIRTUAL_METHODS()
-//    };
-// Then, each method must be defined later in the file.
-#define DECLARE_GUI_VIRTUAL_METHODS()                                         \
-  virtual void specific_init(int argc, char **argv,                           \
-                 unsigned x_tilesize, unsigned y_tilesize,                    \
-                unsigned header_bar_y);                                      \
-  virtual void text_update(Bit8u *old_text, Bit8u *new_text,                  \
-                          unsigned long cursor_x, unsigned long cursor_y,     \
-                          bx_vga_tminfo_t tm_info, unsigned rows);            \
-  virtual void graphics_tile_update(Bit8u *snapshot, unsigned x, unsigned y); \
-  virtual void handle_events(void);                                           \
-  virtual void flush(void);                                                   \
-  virtual void clear_screen(void);                                            \
-  virtual bx_bool palette_change(unsigned index,                              \
-      unsigned red, unsigned green, unsigned blue);                           \
-  virtual void dimension_update(unsigned x, unsigned y, unsigned fheight=0,   \
-                                unsigned fwidth=0, unsigned bpp=8);           \
-  virtual unsigned create_bitmap(const unsigned char *bmap,                   \
-      unsigned xdim, unsigned ydim);                                          \
-  virtual unsigned headerbar_bitmap(unsigned bmap_id, unsigned alignment,     \
-      void (*f)(void));                                                       \
-  virtual void replace_bitmap(unsigned hbar_id, unsigned bmap_id);            \
-  virtual void show_headerbar(void);                                          \
-  virtual int get_clipboard_text(Bit8u **bytes, Bit32s *nbytes);              \
-  virtual int set_clipboard_text(char *snapshot, Bit32u len);                 \
-  virtual void mouse_enabled_changed_specific (bx_bool val);                  \
-  virtual void exit(void);                                                    \
-  /* end of DECLARE_GUI_VIRTUAL_METHODS */
-
-#define BX_MAX_PIXMAPS 16
-#define BX_MAX_HEADERBAR_ENTRIES 11
-#define BX_HEADER_BAR_Y 32
-
-// align pixmaps towards left or right side of header bar
-#define BX_GRAVITY_LEFT 10
-#define BX_GRAVITY_RIGHT 11
-
-#define BX_KEY_PRESSED  0x00000000
-#define BX_KEY_RELEASED 0x80000000
-
-#define BX_KEY_UNHANDLED 0x10000000
-
-#define BX_KEY_CTRL_L   0
-#define BX_KEY_SHIFT_L  1
-
-#define BX_KEY_F1     2
-#define BX_KEY_F2     3
-#define BX_KEY_F3     4
-#define BX_KEY_F4     5
-#define BX_KEY_F5     6
-#define BX_KEY_F6     7
-#define BX_KEY_F7     8
-#define BX_KEY_F8     9
-#define BX_KEY_F9    10
-#define BX_KEY_F10   11
-#define BX_KEY_F11   12
-#define BX_KEY_F12   13
-
-#define BX_KEY_CTRL_R    14
-#define BX_KEY_SHIFT_R   15
-#define BX_KEY_CAPS_LOCK 16
-#define BX_KEY_NUM_LOCK  17
-#define BX_KEY_ALT_L     18
-#define BX_KEY_ALT_R     19
-
-#define BX_KEY_A     20
-#define BX_KEY_B     21
-#define BX_KEY_C     22
-#define BX_KEY_D     23
-#define BX_KEY_E     24
-#define BX_KEY_F     25
-#define BX_KEY_G     26
-#define BX_KEY_H     27
-#define BX_KEY_I     28
-#define BX_KEY_J     29
-#define BX_KEY_K     30
-#define BX_KEY_L     31
-#define BX_KEY_M     32
-#define BX_KEY_N     33
-#define BX_KEY_O     34
-#define BX_KEY_P     35
-#define BX_KEY_Q     36
-#define BX_KEY_R     37
-#define BX_KEY_S     38
-#define BX_KEY_T     39
-#define BX_KEY_U     40
-#define BX_KEY_V     41
-#define BX_KEY_W     42
-#define BX_KEY_X     43
-#define BX_KEY_Y     44
-#define BX_KEY_Z     45
-
-#define BX_KEY_0     46
-#define BX_KEY_1     47
-#define BX_KEY_2     48
-#define BX_KEY_3     49
-#define BX_KEY_4     50
-#define BX_KEY_5     51
-#define BX_KEY_6     52
-#define BX_KEY_7     53
-#define BX_KEY_8     54
-#define BX_KEY_9     55
-
-#define BX_KEY_ESC    56
-
-#define BX_KEY_SPACE         57
-#define BX_KEY_SINGLE_QUOTE  58
-#define BX_KEY_COMMA         59
-#define BX_KEY_PERIOD        60
-#define BX_KEY_SLASH         61
-
-#define BX_KEY_SEMICOLON     62
-#define BX_KEY_EQUALS        63
-
-#define BX_KEY_LEFT_BRACKET  64
-#define BX_KEY_BACKSLASH     65
-#define BX_KEY_RIGHT_BRACKET 66
-#define BX_KEY_MINUS         67
-#define BX_KEY_GRAVE         68
-
-#define BX_KEY_BACKSPACE     69
-#define BX_KEY_ENTER         70
-#define BX_KEY_TAB           71
-
-#define BX_KEY_LEFT_BACKSLASH 72
-#define BX_KEY_PRINT         73
-#define BX_KEY_SCRL_LOCK     74
-#define BX_KEY_PAUSE         75
-
-#define BX_KEY_INSERT        76
-#define BX_KEY_DELETE        77
-#define BX_KEY_HOME          78
-#define BX_KEY_END           79
-#define BX_KEY_PAGE_UP       80
-#define BX_KEY_PAGE_DOWN     81
-
-#define BX_KEY_KP_ADD        82
-#define BX_KEY_KP_SUBTRACT   83
-#define BX_KEY_KP_END        84
-#define BX_KEY_KP_DOWN       85
-#define BX_KEY_KP_PAGE_DOWN  86
-#define BX_KEY_KP_LEFT       87
-#define BX_KEY_KP_RIGHT      88
-#define BX_KEY_KP_HOME       89
-#define BX_KEY_KP_UP         90
-#define BX_KEY_KP_PAGE_UP    91
-#define BX_KEY_KP_INSERT     92
-#define BX_KEY_KP_DELETE     93
-#define BX_KEY_KP_5          94
-
-#define BX_KEY_UP            95
-#define BX_KEY_DOWN          96
-#define BX_KEY_LEFT          97
-#define BX_KEY_RIGHT         98
-
-#define BX_KEY_KP_ENTER      99
-#define BX_KEY_KP_MULTIPLY  100
-#define BX_KEY_KP_DIVIDE    101
-
-#define BX_KEY_WIN_L        102
-#define BX_KEY_WIN_R        103
-#define BX_KEY_MENU         104
-
-#define BX_KEY_ALT_SYSREQ   105
-#define BX_KEY_CTRL_BREAK   106
-
-#define BX_KEY_INT_BACK     107
-#define BX_KEY_INT_FORWARD  108
-#define BX_KEY_INT_STOP     109
-#define BX_KEY_INT_MAIL     110
-#define BX_KEY_INT_SEARCH   111
-#define BX_KEY_INT_FAV      112
-#define BX_KEY_INT_HOME     113
-
-#define BX_KEY_POWER_MYCOMP 114
-#define BX_KEY_POWER_CALC   115
-#define BX_KEY_POWER_SLEEP  116
-#define BX_KEY_POWER_POWER  117
-#define BX_KEY_POWER_WAKE   118
-
-#define BX_KEY_NBKEYS       119
-// If you add BX_KEYs Please update 
-// - BX_KEY_NBKEYS
-// - the scancodes table in the file iodev/scancodes.cc
-// - the bx_key_symbol table in the file gui/keymap.cc
-
-
-/////////////// GUI plugin support
-
-// Define macro to supply gui plugin code.  This macro is called once in GUI to
-// supply the plugin initialization methods.  Since it is nearly identical for
-// each gui module, the macro is easier to maintain than pasting the same code
-// in each one.
-//
-// Each gui should declare a class pointer called "theGui" which is derived
-// from bx_gui_c, before calling this macro.  For example, the SDL port
-// says:
-//   static bx_sdl_gui_c *theGui;
-
-#define IMPLEMENT_GUI_PLUGIN_CODE(gui_name)                           \
-  int lib##gui_name##_LTX_plugin_init(plugin_t *plugin,               \
-          plugintype_t type, int argc, char *argv[]) {                \
-    genlog->info("installing %s module as the Bochs GUI", #gui_name); \
-    theGui = new bx_##gui_name##_gui_c ();                            \
-    bx_gui = theGui;                                                  \
-    return(0); /* Success */                                          \
-  }                                                                   \
-  void lib##gui_name##_LTX_plugin_fini(void) { }
diff --git a/tools/ioemu/gui/icon_bochs.h b/tools/ioemu/gui/icon_bochs.h
deleted file mode 100644 (file)
index 36669fe..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: icon_bochs.h,v 1.3 2001/10/03 13:10:37 bdenney Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2001  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-#define bochs_icon_width 32
-#define bochs_icon_height 32
-static unsigned char bochs_icon_bits[] = {
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00,
-  0xe0, 0xff, 0xff, 0x07, 0xf8, 0xff, 0xff, 0x1f, 0xf8, 0xff, 0xff, 0x1f,
-  0xfc, 0xc7, 0xe3, 0x3f, 0xfc, 0xc7, 0xe3, 0x3f, 0xfc, 0xc3, 0xc3, 0x3f,
-  0xfc, 0xc3, 0xc3, 0x3f, 0xf8, 0xc1, 0x83, 0x1f, 0xf0, 0xc0, 0x03, 0x0f,
-  0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00,
-  0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00,
-  0x00, 0xc0, 0x03, 0x00, 0x00, 0xc0, 0x03, 0x00, 0xf0, 0xc0, 0x03, 0x0f,
-  0xf8, 0xc1, 0x83, 0x1f, 0xfc, 0xc3, 0xc3, 0x3f, 0xfc, 0xc3, 0xc3, 0x3f,
-  0xfc, 0xc7, 0xe3, 0x3f, 0xfc, 0xc7, 0xe3, 0x3f, 0xf8, 0xff, 0xff, 0x1f,
-  0xf8, 0xff, 0xff, 0x1f, 0xe0, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
diff --git a/tools/ioemu/gui/icon_bochs.xpm b/tools/ioemu/gui/icon_bochs.xpm
deleted file mode 100644 (file)
index f895743..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/* XPM */
-static char *icon_bochs_xpm[] = {
-/* columns rows colors chars-per-pixel */
-"32 32 7 1",
-"  c black",
-". c #800000",
-"X c #808000",
-"o c yellow",
-"O c #808080",
-"+ c #c0c0c0",
-"@ c None",
-/* pixels */
-"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@",
-"@@@@@@@@@@.    +@@@+  +@@@@@@@@@",
-"@@@@@@@@    Oo  @+     .@@@@@@@@",
-"@@@@@@    ooooo    ooo.  @@@@@@@",
-"@@@@   oooooo.    oooooX   @@@@@",
-"@+  XoooooO   XX   ooooooo  O@@@",
-"+  oooooO   XXXX X  ooooooo   @@",
-"@   ooo   XXXXXX XX   ooooooX   ",
-"@@.     XXXXXXXX XXX   Xooooo.  ",
-"@@@@  OXXXXXXXXX XXXXXO   oO  .@",
-"@@@@    .XXXXXXX XXXXXXX.    @@@",
-"@+   oo   XXXX    XXXXXXXX   @@@",
-"@   ooooo          XXXXXX      O",
-"@@O  oooooo  OXXXX.  XX  Oooo   ",
-"@@@@  .ooooo.  XXXXX    oooo  O@",
-"@@@@    Oooooo   XX.  .ooo   @@@",
-"@@@@ XX   oooooo    .oooo.  @@@@",
-"@@@@ ooXX   .        ooO  o @@@@",
-"@@@@ oooXX.   .Xo XX    XXo @@@@",
-"@@@@ ooooXXXXXXXo XXXX.XXoo @@@@",
-"@@@+ oooooooooooo XooXXXooo @@@@",
-"@@@. oooooooooooo Xooooooo  @@@@",
-"@@@+   oooooooooo XoooooX .@@@@@",
-"@@@@@O  XoooooooX ooooo  +@@@@@@",
-"@@@@@@@   ooooooX oooX  @@@@@@@@",
-"@@@@@@@@@   ooooX oo   @@@@@@@@@",
-"@@@@@@@@@@.  Ooo.    O@@@@@@@@@@",
-"@@@@@@@@@@@@        @@@@@@@@@@@@",
-"@@@@@@@@@@@@@@O   O@@@@@@@@@@@@@",
-"@@@@@@@@@@@@@@@@+@@@@@@@@@@@@@@@",
-"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@",
-"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
-};
diff --git a/tools/ioemu/gui/keymap.cc b/tools/ioemu/gui/keymap.cc
deleted file mode 100644 (file)
index 8013693..0000000
+++ /dev/null
@@ -1,330 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: keymap.cc,v 1.16 2003/10/11 10:43:24 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002 MandrakeSoft S.A.
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-/////////////////////////////////////////////////////////////////////////
-//
-// Todo
-//  . Currently supported by sdl, wxGTK and x11. Check if other guis need mapping.
-//  . Tables look-up should be optimised.
-//
-
-#include "bochs.h"
-
-// Table of bochs "BX_KEY_*" symbols
-// the table must be in BX_KEY_* order
-char *bx_key_symbol[BX_KEY_NBKEYS] = {
-  "BX_KEY_CTRL_L",         "BX_KEY_SHIFT_L",        "BX_KEY_F1",
-  "BX_KEY_F2",             "BX_KEY_F3",             "BX_KEY_F4",
-  "BX_KEY_F5",             "BX_KEY_F6",             "BX_KEY_F7",
-  "BX_KEY_F8",             "BX_KEY_F9",             "BX_KEY_F10",
-  "BX_KEY_F11",            "BX_KEY_F12",            "BX_KEY_CTRL_R",
-  "BX_KEY_SHIFT_R",        "BX_KEY_CAPS_LOCK",      "BX_KEY_NUM_LOCK",
-  "BX_KEY_ALT_L",          "BX_KEY_ALT_R",          "BX_KEY_A",
-  "BX_KEY_B",              "BX_KEY_C",              "BX_KEY_D",
-  "BX_KEY_E",              "BX_KEY_F",              "BX_KEY_G",
-  "BX_KEY_H",              "BX_KEY_I",              "BX_KEY_J",
-  "BX_KEY_K",              "BX_KEY_L",              "BX_KEY_M",
-  "BX_KEY_N",              "BX_KEY_O",              "BX_KEY_P",
-  "BX_KEY_Q",              "BX_KEY_R",              "BX_KEY_S",
-  "BX_KEY_T",              "BX_KEY_U",              "BX_KEY_V",
-  "BX_KEY_W",              "BX_KEY_X",              "BX_KEY_Y",
-  "BX_KEY_Z",              "BX_KEY_0",              "BX_KEY_1",
-  "BX_KEY_2",              "BX_KEY_3",              "BX_KEY_4",
-  "BX_KEY_5",              "BX_KEY_6",              "BX_KEY_7",
-  "BX_KEY_8",              "BX_KEY_9",              "BX_KEY_ESC",
-  "BX_KEY_SPACE",          "BX_KEY_SINGLE_QUOTE",   "BX_KEY_COMMA",
-  "BX_KEY_PERIOD",         "BX_KEY_SLASH",          "BX_KEY_SEMICOLON",
-  "BX_KEY_EQUALS",         "BX_KEY_LEFT_BRACKET",   "BX_KEY_BACKSLASH",
-  "BX_KEY_RIGHT_BRACKET",  "BX_KEY_MINUS",          "BX_KEY_GRAVE",
-  "BX_KEY_BACKSPACE",      "BX_KEY_ENTER",          "BX_KEY_TAB",
-  "BX_KEY_LEFT_BACKSLASH", "BX_KEY_PRINT",          "BX_KEY_SCRL_LOCK",
-  "BX_KEY_PAUSE",          "BX_KEY_INSERT",         "BX_KEY_DELETE",
-  "BX_KEY_HOME",           "BX_KEY_END",            "BX_KEY_PAGE_UP",
-  "BX_KEY_PAGE_DOWN",      "BX_KEY_KP_ADD",         "BX_KEY_KP_SUBTRACT",
-  "BX_KEY_KP_END",         "BX_KEY_KP_DOWN",        "BX_KEY_KP_PAGE_DOWN",
-  "BX_KEY_KP_LEFT",        "BX_KEY_KP_RIGHT",       "BX_KEY_KP_HOME",
-  "BX_KEY_KP_UP",          "BX_KEY_KP_PAGE_UP",     "BX_KEY_KP_INSERT",
-  "BX_KEY_KP_DELETE",      "BX_KEY_KP_5",           "BX_KEY_UP",
-  "BX_KEY_DOWN",           "BX_KEY_LEFT",           "BX_KEY_RIGHT",
-  "BX_KEY_KP_ENTER",       "BX_KEY_KP_MULTIPLY",    "BX_KEY_KP_DIVIDE",
-  "BX_KEY_WIN_L",          "BX_KEY_WIN_R",          "BX_KEY_MENU",           
-  "BX_KEY_ALT_SYSREQ",     "BX_KEY_CTRL_BREAK",     "BX_KEY_INT_BACK",       
-  "BX_KEY_INT_FORWARD",    "BX_KEY_INT_STOP",       "BX_KEY_INT_MAIL",       
-  "BX_KEY_INT_SEARCH",     "BX_KEY_INT_FAV",        "BX_KEY_INT_HOME",       
-  "BX_KEY_POWER_MYCOMP",   "BX_KEY_POWER_CALC",     "BX_KEY_POWER_SLEEP",    
-  "BX_KEY_POWER_POWER",    "BX_KEY_POWER_WAKE",
-  };
-
-bx_keymap_c bx_keymap;
-
-#define LOG_THIS bx_keymap.
-
-bx_keymap_c::bx_keymap_c(void)
-{
-    put("KMAP");
-
-    keymapCount = 0;
-    keymapTable = (BXKeyEntry *)NULL;
-
-}
-
-bx_keymap_c::~bx_keymap_c(void)
-{
-    if(keymapTable != NULL) {
-      free(keymapTable);
-      keymapTable = (BXKeyEntry *)NULL;
-      }
-    keymapCount = 0;
-}
-
-    void
-bx_keymap_c::loadKeymap(Bit32u stringToSymbol(const char*))
-{
-  if(bx_options.keyboard.OuseMapping->get()) {
-    loadKeymap(stringToSymbol,bx_options.keyboard.Okeymap->getptr());
-    }
-}
-
-
-bx_bool 
-bx_keymap_c::isKeymapLoaded ()
-{
-  return (keymapCount > 0);
-}
-
-
-///////////////////
-// I'll add these to the keymap object in a minute.
-static unsigned char *lineptr = NULL;
-static int lineCount;
-
-static void
-init_parse ()
-{
-  lineCount = 0;
-}
-
-static void
-init_parse_line (char *line_to_parse)
-{
-  // chop off newline
-  lineptr = (unsigned char *)line_to_parse;
-  char *nl;
-  if( (nl = strchr(line_to_parse,'\n')) != NULL) {
-    *nl = 0;
-  }
-}
-
-static Bit32s
-get_next_word (char *output)
-{
-  char *copyp = output;
-  // find first nonspace
-  while (*lineptr && isspace (*lineptr))
-    lineptr++;
-  if (!*lineptr) 
-    return -1;  // nothing but spaces until end of line
-  if (*lineptr == '#')
-    return -1;  // nothing but a comment
-  // copy nonspaces into the output
-  while (*lineptr && !isspace (*lineptr))
-    *copyp++ = *lineptr++;
-  *copyp=0;  // null terminate the copy
-  // there must be at least one nonspace, since that's why we stopped the
-  // first loop!
-  BX_ASSERT (copyp != output);
-  return 0;
-}
-
-static Bit32s
-get_next_keymap_line (FILE *fp, char *bxsym, char *modsym, Bit32s *ascii, char *hostsym)
-{
-  char line[256];
-  char buf[256];
-  line[0] = 0;
-  while (1) {
-    lineCount++;
-    if (!fgets(line, sizeof(line)-1, fp)) return -1;  // EOF
-    init_parse_line (line);
-    if (get_next_word (bxsym) >= 0) {
-      modsym[0] = 0;
-      char *p;
-      if ((p = strchr (bxsym, '+')) != NULL) {
-       *p = 0;  // truncate bxsym.
-       p++;  // move one char beyond the +
-       strcpy (modsym, p);  // copy the rest to modsym
-      }
-      if (get_next_word (buf) < 0) {
-       BX_PANIC (("keymap line %d: expected 3 columns", lineCount));
-       return -1;
-      }
-      if (buf[0] == '\'' && buf[2] == '\'' && buf[3]==0) {
-       *ascii = (Bit8u) buf[1];
-      } else if (!strcmp(buf, "space")) {
-       *ascii = ' ';
-      } else if (!strcmp(buf, "return")) {
-       *ascii = '\n';
-      } else if (!strcmp(buf, "tab")) {
-       *ascii = '\t';
-      } else if (!strcmp(buf, "backslash")) {
-       *ascii = '\\';
-      } else if (!strcmp(buf, "apostrophe")) {
-       *ascii = '\'';
-      } else if (!strcmp(buf, "none")) {
-       *ascii = -1;
-      } else {
-       BX_PANIC (("keymap line %d: ascii equivalent is \"%s\" but it must be char constant like 'x', or one of space,tab,return,none", lineCount, buf));
-      }
-      if (get_next_word (hostsym) < 0) {
-        BX_PANIC (("keymap line %d: expected 3 columns", lineCount));
-       return -1;
-      }
-      return 0;
-    }
-    // no words on this line, keep reading.
-  }
-}
-
-    void
-bx_keymap_c::loadKeymap(Bit32u stringToSymbol(const char*), const char* filename)
-{
-    FILE   *keymapFile;
-    char baseSym[256], modSym[256], hostSym[256]; 
-    Bit32s ascii;
-    Bit32u baseKey, modKey, hostKey;
-    struct stat status;
-
-    if (stat(filename, &status)) {
-      BX_PANIC(("Can not stat keymap file '%s'.",filename));
-      }
-
-    if (!(S_ISREG(status.st_mode))) {
-      BX_PANIC(("Keymap file '%s' is not a file",filename));
-      }
-
-    if((keymapFile = fopen(filename,"r"))==NULL) {
-      BX_PANIC(("Can not open keymap file '%s'.",filename));
-      }
-    
-    BX_INFO(("Loading keymap from '%s'",filename));
-    init_parse ();
-
-    // Read keymap file one line at a time
-    while(1) {
-      if (get_next_keymap_line (keymapFile, 
-            baseSym, modSym, &ascii, hostSym) < 0) { break; }
-
-
-      // convert X_KEY_* symbols to values
-      baseKey = convertStringToBXKey(baseSym);
-      modKey = convertStringToBXKey(modSym);
-      hostKey = 0;
-      if (stringToSymbol != NULL)
-        hostKey = stringToSymbol(hostSym);
-
-      BX_DEBUG (("baseKey='%s' (%d), modSym='%s' (%d), ascii=%d, guisym='%s' (%d)", baseSym, baseKey, modSym, modKey, ascii, hostSym, hostKey));
-       
-      // Check if data is valid
-      if( baseKey==BX_KEYMAP_UNKNOWN ) {
-        BX_PANIC (("line %d: unknown BX_KEY constant '%s'",lineCount,baseSym));
-        continue;
-        }
-
-      if( hostKey==BX_KEYMAP_UNKNOWN ) {
-        BX_PANIC (("line %d: unknown host key name '%s'",lineCount,hostSym));
-        continue;
-        }
-
-      keymapTable=(BXKeyEntry*)realloc(keymapTable,(keymapCount+1) * sizeof(BXKeyEntry));
-      
-      if(keymapTable==NULL) 
-        BX_PANIC(("Can not allocate memory for keymap table."));
-
-      keymapTable[keymapCount].baseKey=baseKey;
-      keymapTable[keymapCount].modKey=modKey;
-      keymapTable[keymapCount].ascii=ascii;
-      keymapTable[keymapCount].hostKey=hostKey;
-      
-      keymapCount++;
-      }
-
-    BX_INFO(("Loaded %d symbols",keymapCount));
-
-    fclose(keymapFile);
-}
-
-    Bit32u
-bx_keymap_c::convertStringToBXKey(const char* string)
-{
-    Bit16u i;
-
-    // We look through the bx_key_symbol table to find the searched string
-    for (i=0; i<BX_KEY_NBKEYS; i++) {
-      if (strcmp(string,bx_key_symbol[i])==0) {
-        return i;
-        }
-      }
-  
-    // Key is not known
-    return BX_KEYMAP_UNKNOWN;
-}
-
-    BXKeyEntry *
-bx_keymap_c::findHostKey(Bit32u key)
-{
-    Bit16u i;
-
-    // We look through the keymap table to find the searched key
-    for (i=0; i<keymapCount; i++) {
-      if (keymapTable[i].hostKey == key) {
-       BX_DEBUG (("key 0x%02x matches hostKey for entry #%d", key, i));
-        return &keymapTable[i];
-        }
-      }
-    BX_DEBUG (("key %02x matches no entries", key));
-
-    // Return default
-    return NULL;
-}
-
-    BXKeyEntry *
-bx_keymap_c::findAsciiChar(Bit8u ch)
-{
-    Bit16u i;
-    BX_DEBUG (("findAsciiChar (0x%02x)", ch));
-
-    // We look through the keymap table to find the searched key
-    for (i=0; i<keymapCount; i++) {
-      if (keymapTable[i].ascii == ch) {
-       BX_DEBUG (("key %02x matches ascii for entry #%d", ch, i));
-        return &keymapTable[i];
-        }
-      }
-    BX_DEBUG (("key 0x%02x matches no entries", ch));
-
-    // Return default
-    return NULL;
-}
-
-    char *
-bx_keymap_c::getBXKeyName(Bit32u key)
-{
-    return bx_key_symbol[key & 0x7fffffff];
-}
diff --git a/tools/ioemu/gui/keymap.h b/tools/ioemu/gui/keymap.h
deleted file mode 100644 (file)
index 945729b..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: keymap.h,v 1.9 2003/07/12 08:17:10 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-/////////////////////////////////////////////////////////////////////////
-//
-// Methods of bx_keymap_c :
-//
-// - loadKeymap(Bit32u convertStringToSymbol(const char*));
-//   loads the configuration specified keymap file if keymapping is enabled
-//   using convertStringToSymbol to convert strings to client constants
-//
-// - loadKeymap(Bit32u convertStringToSymbol(const char*), const char* filename);
-//   loads the specified keymap file 
-//   using convertStringToSymbol to convert strings to client constants
-//
-// - isKeymapLoaded () returns true if the keymap contains any valid key
-//   entries.
-//
-// - convertStringToBXKey
-//   convert a null-terminate string to a BX_KEY code
-//
-// - findHostKey(Bit32u key)
-// - findAsciiChar(Bit8u ch)
-//   Each of these methods returns a pointer to a BXKeyEntry structure
-//   corresponding to a key.  findHostKey() finds an entry whose hostKey
-//   value matches the target value, and findAsciiChar() finds an entry
-//   whose ASCII code matches the search value.
-
-// In case of unknown symbol
-#define BX_KEYMAP_UNKNOWN   0xFFFFFFFF
-
-// Structure of an element of the keymap table
-typedef struct BOCHSAPI { 
-  Bit32u baseKey;   // base key
-  Bit32u modKey;   // modifier key that must be held down
-  Bit32s ascii;    // ascii equivalent, if any
-  Bit32u hostKey;  // value that the host's OS or library recognizes
-  } BXKeyEntry;
-
-class BOCHSAPI bx_keymap_c : public logfunctions {
-public:
-  bx_keymap_c(void);
-  ~bx_keymap_c(void);
-
-  void   loadKeymap(Bit32u(*)(const char*));
-  void   loadKeymap(Bit32u(*)(const char*),const char *filename);
-  bx_bool isKeymapLoaded ();
-
-  BXKeyEntry *findHostKey(Bit32u hostkeynum);
-  BXKeyEntry *findAsciiChar(Bit8u ascii);
-  char *getBXKeyName(Bit32u key);
-
-private:
-  Bit32u convertStringToBXKey(const char *);
-  BXKeyEntry *keymapTable;
-  Bit16u   keymapCount;
-  };
-
-BOCHSAPI extern bx_keymap_c bx_keymap;
diff --git a/tools/ioemu/gui/keymaps/convertmap.pl b/tools/ioemu/gui/keymaps/convertmap.pl
deleted file mode 100644 (file)
index 18c47be..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/usr/bin/perl
-# little utility script that I used to convert key map files from
-# the pre-March 11 format to the post-March 11 format.  It doesn't
-# do anything smart with the ascii equivalents and modifiers, so ATM those must
-# be added by hand.
-
-while (<STDIN>)
-{
-  chop;
-  s/^ *//;
-  if (/^#/ || /^ *$/) { print "$_\n"; next;}
-  ($key, $equals, $xksym) = split (/ +/);
-  printf ("%-45s %-10s %s\n", $key, 'none', "XK_$xksym");
-}
diff --git a/tools/ioemu/gui/keymaps/sdl-pc-de.map b/tools/ioemu/gui/keymaps/sdl-pc-de.map
deleted file mode 100644 (file)
index de4fd59..0000000
+++ /dev/null
@@ -1,222 +0,0 @@
-# Bochs Keymap file
-# $Id: sdl-pc-de.map,v 1.2 2002/10/24 21:06:55 bdenney Exp $
-# Target: PC(x86) keyboard, DE keymap, SDL gui on X11
-# Author: Volker Ruppert
-#
-# The keymap file describes the layout of a keyboard, and how it translates
-# into Bochs key codes.
-#
-# Format:
-#  BX_Keysym                ASCII_equivalent      Host_key_name
-#
-# Or, for keys that require modifiers:
-#  BX_Keysym+BX_Modifier    ASCII_equivalent      Host_key_name
-#
-# BX_Keysym and BX_Modifier must be present in the bx_key_symbol[] list in
-# gui/keymap.cc.  The BX_Modifier is usually a shift key press, but it
-# could be any key.  Presently a maximum of one modifier is supported, but this
-# could be changed in keymap.h (structure def has only one slot for modifier),
-# keymap.cc (parsing code), and iodev/keyboard.cc (simulate keypresses for >1
-# modifier).
-#
-# The ASCII_equivalent must be either apostrophe + one character + apostrophe,
-# or one of these keywords: space, return, tab, backslash, apostrophe, none.
-# This format is designed to look like a char constant in C, but it's a very
-# simple parser.  There's no concept of backslash being an escape char.  The
-# backslash and apostrophe entries are provided for aesthetic purposes only: no
-# C++ programmer wants to see '\' or '''. The parser doesn't care, but they are
-# ugly.
-#
-# Host_key_name is the name of the key combination according to the gui library
-# (X windows, SDL, etc).  Each GUI module must provide a function that converts
-# these host key names into numbers.  A pointer to the conversion function is
-# passed to loadKeymap(), and it is used when parsing the keymap file.  As the
-# keymap file is parsed, the conversion function is called for each host key
-# name, to convert it into a number.  Only the number is stored.  If the host
-# key name is not found, the conversion function returns BX_KEYMAP_UNKNOWN, and
-# the keymap code will panic, like this: 
-#
-#    [KMAP ] line 51: unknown host key name 'SDLK_PAREN_RIGHT' 
-#
-# If this happens, you must edit the keymap file, and either correct the host
-# key name or comment out that line.
-#
-
-BX_KEY_0                                      '0'        SDLK_0
-BX_KEY_0+BX_KEY_SHIFT_L                       '='        SDLK_EQUALS
-BX_KEY_1                                      '1'        SDLK_1
-BX_KEY_1+BX_KEY_SHIFT_L                       '!'        SDLK_EXCLAIM
-BX_KEY_2                                      '2'        SDLK_2
-BX_KEY_2+BX_KEY_ALT_R                         '²'        SDLK_2
-BX_KEY_2+BX_KEY_SHIFT_L                       '"'        SDLK_QUOTEDBL
-BX_KEY_3                                      '3'        SDLK_3
-BX_KEY_3+BX_KEY_SHIFT_L                       '§'        SDLK_3
-BX_KEY_4                                      '4'        SDLK_4
-BX_KEY_4+BX_KEY_SHIFT_L                       '$'        SDLK_DOLLAR
-BX_KEY_4+BX_KEY_ALT_R                         '¼'        SDLK_4
-BX_KEY_5                                      '5'        SDLK_5
-BX_KEY_5+BX_KEY_ALT_R                         '½'        SDLK_5
-BX_KEY_5+BX_KEY_SHIFT_L                       '%'        SDLK_5
-BX_KEY_6                                      '6'        SDLK_6
-BX_KEY_6+BX_KEY_SHIFT_L                       '&'        SDLK_AMPERSAND
-BX_KEY_7                                      '7'        SDLK_7
-BX_KEY_7+BX_KEY_ALT_R                         '{'        SDLK_7
-BX_KEY_7+BX_KEY_SHIFT_L                       '/'        SDLK_SLASH
-BX_KEY_8                                      '8'        SDLK_8
-BX_KEY_8+BX_KEY_ALT_R                         '['        SDLK_LEFTBRACKET
-BX_KEY_8+BX_KEY_SHIFT_L                       '('        SDLK_LEFTPAREN
-BX_KEY_9                                      '9'        SDLK_9
-BX_KEY_9+BX_KEY_ALT_R                         ']'        SDLK_RIGHTBRACKET
-BX_KEY_9+BX_KEY_SHIFT_L                       ')'        SDLK_RIGHTPAREN
-BX_KEY_A+BX_KEY_SHIFT_L                       'A'        SDLK_a
-BX_KEY_A                                      'a'        SDLK_a
-BX_KEY_A+BX_KEY_ALT_R                         'æ'        SDLK_a
-BX_KEY_B+BX_KEY_SHIFT_L                       'B'        SDLK_b
-BX_KEY_B                                      'b'        SDLK_b
-BX_KEY_C+BX_KEY_SHIFT_L                       'C'        SDLK_c
-BX_KEY_C                                      'c'        SDLK_c
-BX_KEY_C+BX_KEY_ALT_R                         '¢'        SDLK_c
-BX_KEY_D+BX_KEY_SHIFT_L                       'D'        SDLK_d
-BX_KEY_D                                      'd'        SDLK_d
-BX_KEY_E+BX_KEY_SHIFT_L                       'E'        SDLK_e
-BX_KEY_E+BX_KEY_ALT_R                         none       SDLK_EURO
-BX_KEY_E                                      'e'        SDLK_e
-BX_KEY_F+BX_KEY_SHIFT_L                       'F'        SDLK_f
-BX_KEY_F                                      'f'        SDLK_f
-BX_KEY_G+BX_KEY_SHIFT_L                       'G'        SDLK_g
-BX_KEY_G                                      'g'        SDLK_g
-BX_KEY_H+BX_KEY_SHIFT_L                       'H'        SDLK_h
-BX_KEY_H                                      'h'        SDLK_h
-BX_KEY_I+BX_KEY_SHIFT_L                       'I'        SDLK_i
-BX_KEY_I                                      'i'        SDLK_i
-BX_KEY_J+BX_KEY_SHIFT_L                       'J'        SDLK_j
-BX_KEY_J                                      'j'        SDLK_j
-BX_KEY_K+BX_KEY_SHIFT_L                       'K'        SDLK_k
-BX_KEY_K                                      'k'        SDLK_k
-BX_KEY_L+BX_KEY_SHIFT_L                       'L'        SDLK_l
-BX_KEY_L                                      'l'        SDLK_l
-BX_KEY_M+BX_KEY_SHIFT_L                       'M'        SDLK_m
-BX_KEY_M                                      'm'        SDLK_m
-BX_KEY_M+BX_KEY_ALT_R                         'µ'        SDLK_m
-BX_KEY_N+BX_KEY_SHIFT_L                       'N'        SDLK_n
-BX_KEY_N                                      'n'        SDLK_n
-BX_KEY_O+BX_KEY_SHIFT_L                       'O'        SDLK_o
-BX_KEY_O                                      'o'        SDLK_o
-BX_KEY_O+BX_KEY_ALT_R                         'ø'        SDLK_o
-BX_KEY_P+BX_KEY_SHIFT_L                       'P'        SDLK_p
-BX_KEY_P                                      'p'        SDLK_p
-BX_KEY_Q+BX_KEY_SHIFT_L                       'Q'        SDLK_q
-BX_KEY_Q+BX_KEY_ALT_R                         '@'        SDLK_AT
-BX_KEY_Q                                      'q'        SDLK_q
-BX_KEY_R+BX_KEY_SHIFT_L                       'R'        SDLK_r
-BX_KEY_R+BX_KEY_ALT_R                         '¶'        SDLK_r
-BX_KEY_R                                      'r'        SDLK_r
-BX_KEY_S+BX_KEY_SHIFT_L                       'S'        SDLK_s
-BX_KEY_S                                      's'        SDLK_s
-BX_KEY_T+BX_KEY_SHIFT_L                       'T'        SDLK_t
-BX_KEY_T                                      't'        SDLK_t
-BX_KEY_U+BX_KEY_SHIFT_L                       'U'        SDLK_u
-BX_KEY_U                                      'u'        SDLK_u
-BX_KEY_V+BX_KEY_SHIFT_L                       'V'        SDLK_v
-BX_KEY_V                                      'v'        SDLK_v
-BX_KEY_W+BX_KEY_SHIFT_L                       'W'        SDLK_w
-BX_KEY_W                                      'w'        SDLK_w
-BX_KEY_X+BX_KEY_SHIFT_L                       'X'        SDLK_x
-BX_KEY_X+BX_KEY_ALT_R                         '»'        SDLK_x
-BX_KEY_X                                      'x'        SDLK_x
-BX_KEY_Y+BX_KEY_SHIFT_L                       'Z'        SDLK_z
-BX_KEY_Y                                      'z'        SDLK_z
-BX_KEY_Z+BX_KEY_SHIFT_L                       'Y'        SDLK_y
-BX_KEY_Z+BX_KEY_ALT_R                         '«'        SDLK_y
-BX_KEY_Z                                      'y'        SDLK_y
-BX_KEY_F1                                     none       SDLK_F1
-BX_KEY_F2                                     none       SDLK_F2
-BX_KEY_F3                                     none       SDLK_F3
-BX_KEY_F4                                     none       SDLK_F4
-BX_KEY_F5                                     none       SDLK_F5
-BX_KEY_F6                                     none       SDLK_F6
-BX_KEY_F7                                     none       SDLK_F7
-BX_KEY_F8                                     none       SDLK_F8
-BX_KEY_F9                                     none       SDLK_F9
-BX_KEY_F10                                    none       SDLK_F10
-BX_KEY_F11                                    none       SDLK_F11
-BX_KEY_F12                                    none       SDLK_F12
-BX_KEY_ALT_L                                  none       SDLK_LALT
-BX_KEY_ALT_L                                  none       SDLK_LMETA
-BX_KEY_ALT_R                                  none       SDLK_RALT
-BX_KEY_ALT_R                                  none       SDLK_MODE
-BX_KEY_BACKSLASH                              apostrophe SDLK_QUOTE
-BX_KEY_BACKSLASH                              '#'        SDLK_HASH
-BX_KEY_BACKSPACE                              none       SDLK_BACKSPACE
-BX_KEY_CAPS_LOCK                              none       SDLK_CAPSLOCK
-BX_KEY_COMMA                                  ','        SDLK_COMMA
-BX_KEY_COMMA+BX_KEY_SHIFT_L                   ';'        SDLK_SEMICOLON
-BX_KEY_CTRL_L                                 none       SDLK_LCTRL
-BX_KEY_CTRL_R                                 none       SDLK_RCTRL
-BX_KEY_DELETE                                 none       SDLK_DELETE
-BX_KEY_DOWN                                   none       SDLK_DOWN
-BX_KEY_END                                    none       SDLK_END
-BX_KEY_ENTER                                  return     SDLK_RETURN
-BX_KEY_EQUALS                                 none       SDLK_WORLD_20
-BX_KEY_EQUALS+BX_KEY_ALT_R                    '¸'        SDLK_WORLD_20
-BX_KEY_EQUALS+BX_KEY_SHIFT_L                  '`'        SDLK_WORLD_20
-BX_KEY_ESC                                    none       SDLK_ESCAPE
-BX_KEY_GRAVE                                  '^'        SDLK_CARET
-BX_KEY_GRAVE+BX_KEY_SHIFT_L                   '°'        SDLK_CARET
-BX_KEY_GRAVE+BX_KEY_ALT_R                     '¬'        SDLK_CARET
-BX_KEY_HOME                                   none       SDLK_HOME
-BX_KEY_INSERT                                 none       SDLK_INSERT
-BX_KEY_KP_5                                   none       SDLK_KP5
-BX_KEY_KP_ADD                                 none       SDLK_KP_PLUS
-BX_KEY_KP_DELETE                              none       SDLK_KP_PERIOD
-BX_KEY_KP_DIVIDE                              none       SDLK_KP_DIVIDE
-BX_KEY_KP_DOWN                                none       SDLK_KP2
-BX_KEY_KP_END                                 none       SDLK_KP1
-BX_KEY_KP_ENTER                               none       SDLK_KP_ENTER
-BX_KEY_KP_HOME                                none       SDLK_KP7
-BX_KEY_KP_INSERT                              none       SDLK_KP0
-BX_KEY_KP_LEFT                                none       SDLK_KP4
-BX_KEY_KP_MULTIPLY                            none       SDLK_KP_MULTIPLY
-BX_KEY_KP_PAGE_DOWN                           none       SDLK_KP3
-BX_KEY_KP_PAGE_UP                             none       SDLK_KP9
-BX_KEY_KP_RIGHT                               none       SDLK_KP6
-BX_KEY_KP_SUBTRACT                            none       SDLK_KP_MINUS
-BX_KEY_KP_UP                                  none       SDLK_KP8
-BX_KEY_LEFT                                   none       SDLK_LEFT
-BX_KEY_LEFT_BACKSLASH+BX_KEY_ALT_R            '|'        SDLK_LESS
-BX_KEY_LEFT_BACKSLASH+BX_KEY_SHIFT_L          '>'        SDLK_GREATER
-BX_KEY_LEFT_BACKSLASH                         '<'        SDLK_LESS
-BX_KEY_LEFT_BRACKET+BX_KEY_SHIFT_L            'Ü'        SDLK_WORLD_92
-BX_KEY_LEFT_BRACKET                           'ü'        SDLK_WORLD_92
-BX_KEY_MENU                                   none       SDLK_MENU
-BX_KEY_MINUS+BX_KEY_ALT_L                     backslash  SDLK_BACKSLASH
-BX_KEY_MINUS+BX_KEY_SHIFT_L                   '?'        SDLK_QUESTION
-BX_KEY_MINUS                                  'ß'        SDLK_WORLD_63
-BX_KEY_NUM_LOCK                               none       SDLK_NUMLOCK
-BX_KEY_PAGE_DOWN                              none       SDLK_PAGEDOWN
-BX_KEY_PAGE_UP                                none       SDLK_PAGEUP
-BX_KEY_PAUSE                                  none       SDLK_BREAK
-BX_KEY_PAUSE                                  none       SDLK_PAUSE
-BX_KEY_PERIOD+BX_KEY_SHIFT_L                  ':'        SDLK_COLON
-BX_KEY_PERIOD                                 '.'        SDLK_PERIOD
-BX_KEY_PERIOD+BX_KEY_ALT_L                    '·'        SDLK_PERIOD
-BX_KEY_PRINT                                  none       SDLK_PRINT
-BX_KEY_PRINT                                  none       SDLK_SYSREQ
-BX_KEY_RIGHT                                  none       SDLK_RIGHT
-BX_KEY_RIGHT_BRACKET+BX_KEY_ALT_R             '~'        SDLK_PLUS
-BX_KEY_RIGHT_BRACKET+BX_KEY_SHIFT_L           '*'        SDLK_PLUS
-BX_KEY_RIGHT_BRACKET                          '+'        SDLK_PLUS
-BX_KEY_SCRL_LOCK                              none       SDLK_SCROLLOCK
-BX_KEY_SEMICOLON+BX_KEY_SHIFT_L               'Ö'        SDLK_WORLD_86
-BX_KEY_SEMICOLON                              'ö'        SDLK_WORLD_86
-BX_KEY_SHIFT_L                                none       SDLK_LSHIFT
-BX_KEY_SHIFT_R                                none       SDLK_RSHIFT
-BX_KEY_SINGLE_QUOTE+BX_KEY_SHIFT_L            'Ä'        SDLK_WORLD_68
-BX_KEY_SINGLE_QUOTE                           'ä'        SDLK_WORLD_68
-BX_KEY_SLASH                                  '-'        SDLK_MINUS
-BX_KEY_SLASH+BX_KEY_SHIFT_L                   '_'        SDLK_UNDERSCORE
-BX_KEY_SPACE                                  space      SDLK_SPACE
-BX_KEY_TAB                                    tab        SDLK_TAB
-BX_KEY_UP                                     none       SDLK_UP
-BX_KEY_WIN_L                                  none       SDLK_LSUPER
-BX_KEY_WIN_R                                  none       SDLK_RSUPER
diff --git a/tools/ioemu/gui/keymaps/sdl-pc-us.map b/tools/ioemu/gui/keymaps/sdl-pc-us.map
deleted file mode 100644 (file)
index 3440992..0000000
+++ /dev/null
@@ -1,211 +0,0 @@
-# Bochs Keymap file
-# $Id: sdl-pc-us.map,v 1.2 2002/10/24 21:06:55 bdenney Exp $
-# Target: PC(x86) keyboard, US keymap, SDL gui
-# Author: Bryce Denney
-#
-# The keymap file describes the layout of a keyboard, and how it translates
-# into Bochs key codes.
-#
-# Format:
-#  BX_Keysym                ASCII_equivalent      Host_key_name
-#
-# Or, for keys that require modifiers:
-#  BX_Keysym+BX_Modifier    ASCII_equivalent      Host_key_name
-#
-# BX_Keysym and BX_Modifier must be present in the bx_key_symbol[] list in
-# gui/keymap.cc.  The BX_Modifier is usually a shift key press, but it
-# could be any key.  Presently a maximum of one modifier is supported, but this
-# could be changed in keymap.h (structure def has only one slot for modifier),
-# keymap.cc (parsing code), and iodev/keyboard.cc (simulate keypresses for >1
-# modifier).
-#
-# The ASCII_equivalent must be either apostrophe + one character + apostrophe,
-# or one of these keywords: space, return, tab, backslash, apostrophe, none.
-# This format is designed to look like a char constant in C, but it's a very
-# simple parser.  There's no concept of backslash being an escape char.  The
-# backslash and apostrophe entries are provided for aesthetic purposes only: no
-# C++ programmer wants to see '\' or '''. The parser doesn't care, but they are
-# ugly.
-#
-# Host_key_name is the name of the key combination according to the gui library
-# (X windows, SDL, etc).  Each GUI module must provide a function that converts
-# these host key names into numbers.  A pointer to the conversion function is
-# passed to loadKeymap(), and it is used when parsing the keymap file.  As the
-# keymap file is parsed, the conversion function is called for each host key
-# name, to convert it into a number.  Only the number is stored.  If the host
-# key name is not found, the conversion function returns BX_KEYMAP_UNKNOWN, and
-# the keymap code will panic, like this: 
-#
-#    [KMAP ] line 51: unknown host key name 'SDLK_PAREN_RIGHT' 
-#
-# If this happens, you must edit the keymap file, and either correct the host
-# key name or comment out that line.
-#
-
-BX_KEY_0                                      '0'        SDLK_0
-BX_KEY_0+BX_KEY_SHIFT_L                       ')'        SDLK_RIGHTPAREN
-BX_KEY_1                                      '1'        SDLK_1
-BX_KEY_1+BX_KEY_SHIFT_L                       '!'        SDLK_EXCLAIM
-BX_KEY_2                                      '2'        SDLK_2
-BX_KEY_2+BX_KEY_SHIFT_L                       '@'        SDLK_AT
-BX_KEY_3                                      '3'        SDLK_3
-BX_KEY_3+BX_KEY_SHIFT_L                       '#'        SDLK_HASH
-BX_KEY_4                                      '4'        SDLK_4
-BX_KEY_4+BX_KEY_SHIFT_L                       '$'        SDLK_DOLLAR
-BX_KEY_5                                      '5'        SDLK_5
-#BX_KEY_5+BX_KEY_SHIFT_L                       '%'        SDLK_PERCENT
-BX_KEY_6                                      '6'        SDLK_6
-BX_KEY_6+BX_KEY_SHIFT_L                       '^'        SDLK_CARET
-BX_KEY_7                                      '7'        SDLK_7
-BX_KEY_7+BX_KEY_SHIFT_L                       '&'        SDLK_AMPERSAND
-BX_KEY_8                                      '8'        SDLK_8
-BX_KEY_8+BX_KEY_SHIFT_L                       '*'        SDLK_ASTERISK
-BX_KEY_9                                      '9'        SDLK_9
-BX_KEY_9+BX_KEY_SHIFT_L                       '('        SDLK_LEFTPAREN
-BX_KEY_A+BX_KEY_SHIFT_L                       'A'        SDLK_a
-BX_KEY_A                                      'a'        SDLK_a
-BX_KEY_B+BX_KEY_SHIFT_L                       'B'        SDLK_b
-BX_KEY_B                                      'b'        SDLK_b
-BX_KEY_C+BX_KEY_SHIFT_L                       'C'        SDLK_c
-BX_KEY_C                                      'c'        SDLK_c
-BX_KEY_D+BX_KEY_SHIFT_L                       'D'        SDLK_d
-BX_KEY_D                                      'd'        SDLK_d
-BX_KEY_E+BX_KEY_SHIFT_L                       'E'        SDLK_e
-BX_KEY_E                                      'e'        SDLK_e
-BX_KEY_F+BX_KEY_SHIFT_L                       'F'        SDLK_f
-BX_KEY_F                                      'f'        SDLK_f
-BX_KEY_G+BX_KEY_SHIFT_L                       'G'        SDLK_g
-BX_KEY_G                                      'g'        SDLK_g
-BX_KEY_H+BX_KEY_SHIFT_L                       'H'        SDLK_h
-BX_KEY_H                                      'h'        SDLK_h
-BX_KEY_I+BX_KEY_SHIFT_L                       'I'        SDLK_i
-BX_KEY_I                                      'i'        SDLK_i
-BX_KEY_J+BX_KEY_SHIFT_L                       'J'        SDLK_j
-BX_KEY_J                                      'j'        SDLK_j
-BX_KEY_K+BX_KEY_SHIFT_L                       'K'        SDLK_k
-BX_KEY_K                                      'k'        SDLK_k
-BX_KEY_L+BX_KEY_SHIFT_L                       'L'        SDLK_l
-BX_KEY_L                                      'l'        SDLK_l
-BX_KEY_M+BX_KEY_SHIFT_L                       'M'        SDLK_m
-BX_KEY_M                                      'm'        SDLK_m
-BX_KEY_N+BX_KEY_SHIFT_L                       'N'        SDLK_n
-BX_KEY_N                                      'n'        SDLK_n
-BX_KEY_O+BX_KEY_SHIFT_L                       'O'        SDLK_o
-BX_KEY_O                                      'o'        SDLK_o
-BX_KEY_P+BX_KEY_SHIFT_L                       'P'        SDLK_p
-BX_KEY_P                                      'p'        SDLK_p
-BX_KEY_Q+BX_KEY_SHIFT_L                       'Q'        SDLK_q
-BX_KEY_Q                                      'q'        SDLK_q
-BX_KEY_R+BX_KEY_SHIFT_L                       'R'        SDLK_r
-BX_KEY_R                                      'r'        SDLK_r
-BX_KEY_S+BX_KEY_SHIFT_L                       'S'        SDLK_s
-BX_KEY_S                                      's'        SDLK_s
-BX_KEY_T+BX_KEY_SHIFT_L                       'T'        SDLK_t
-BX_KEY_T                                      't'        SDLK_t
-BX_KEY_U+BX_KEY_SHIFT_L                       'U'        SDLK_u
-BX_KEY_U                                      'u'        SDLK_u
-BX_KEY_V+BX_KEY_SHIFT_L                       'V'        SDLK_v
-BX_KEY_V                                      'v'        SDLK_v
-BX_KEY_W+BX_KEY_SHIFT_L                       'W'        SDLK_w
-BX_KEY_W                                      'w'        SDLK_w
-BX_KEY_X+BX_KEY_SHIFT_L                       'X'        SDLK_x
-BX_KEY_X                                      'x'        SDLK_x
-BX_KEY_Y+BX_KEY_SHIFT_L                       'Y'        SDLK_y
-BX_KEY_Y                                      'y'        SDLK_y
-BX_KEY_Z+BX_KEY_SHIFT_L                       'Z'        SDLK_z
-BX_KEY_Z                                      'z'        SDLK_z
-BX_KEY_F1                                     none       SDLK_F1
-BX_KEY_F2                                     none       SDLK_F2
-BX_KEY_F3                                     none       SDLK_F3
-BX_KEY_F4                                     none       SDLK_F4
-BX_KEY_F5                                     none       SDLK_F5
-BX_KEY_F6                                     none       SDLK_F6
-BX_KEY_F7                                     none       SDLK_F7
-BX_KEY_F8                                     none       SDLK_F8
-BX_KEY_F9                                     none       SDLK_F9
-BX_KEY_F10                                    none       SDLK_F10
-BX_KEY_F11                                    none       SDLK_F11
-BX_KEY_F12                                    none       SDLK_F12
-BX_KEY_ALT_L                                  none       SDLK_LALT
-BX_KEY_ALT_L                                  none       SDLK_LMETA
-BX_KEY_ALT_R                                  none       SDLK_MODE
-#BX_KEY_ALT_R                                  none       SDLK_Multi_key
-BX_KEY_BACKSLASH                              backslash  SDLK_BACKSLASH
-#BX_KEY_BACKSLASH+BX_KEY_SHIFT_L               '|'        SDLK_bar
-BX_KEY_BACKSPACE                              none       SDLK_BACKSPACE
-BX_KEY_CAPS_LOCK                              none       SDLK_CAPSLOCK
-BX_KEY_COMMA                                  ','        SDLK_COMMA
-BX_KEY_COMMA+BX_KEY_SHIFT_L                   '<'        SDLK_LESS
-BX_KEY_CTRL_L                                 none       SDLK_LCTRL
-BX_KEY_CTRL_R                                 none       SDLK_RCTRL
-BX_KEY_DELETE                                 none       SDLK_DELETE
-BX_KEY_DOWN                                   none       SDLK_DOWN
-BX_KEY_END                                    none       SDLK_END
-BX_KEY_ENTER                                  return     SDLK_RETURN
-BX_KEY_EQUALS                                 '='        SDLK_EQUALS
-BX_KEY_EQUALS+BX_KEY_SHIFT_L                  '+'        SDLK_PLUS
-BX_KEY_ESC                                    none       SDLK_ESCAPE
-#BX_KEY_GRAVE+BX_KEY_SHIFT_L                   '~'        SDLK_asciitilde
-BX_KEY_GRAVE                                  '`'        SDLK_BACKQUOTE
-BX_KEY_HOME                                   none       SDLK_HOME
-BX_KEY_INSERT                                 none       SDLK_INSERT
-BX_KEY_KP_5                                   none       SDLK_KP5
-#BX_KEY_KP_5                                   none       SDLK_KP_BEGIN
-BX_KEY_KP_ADD                                 none       SDLK_KP_PLUS
-BX_KEY_KP_DELETE                              none       SDLK_KP_PERIOD
-#BX_KEY_KP_DELETE                              none       SDLK_KP_DELETE
-BX_KEY_KP_DIVIDE                              none       SDLK_KP_DIVIDE
-BX_KEY_KP_DOWN                                none       SDLK_KP2
-#BX_KEY_KP_DOWN                                none       SDLK_KP_DOWN
-BX_KEY_KP_END                                 none       SDLK_KP1
-#BX_KEY_KP_END                                 none       SDLK_KP_END
-BX_KEY_KP_ENTER                               none       SDLK_KP_ENTER
-BX_KEY_KP_HOME                                none       SDLK_KP7
-#BX_KEY_KP_HOME                                none       SDLK_KP_HOME
-BX_KEY_KP_INSERT                              none       SDLK_KP0
-#BX_KEY_KP_INSERT                              none       SDLK_KP_INSERT
-BX_KEY_KP_LEFT                                none       SDLK_KP4
-#BX_KEY_KP_LEFT                                none       SDLK_KP_LEFT
-BX_KEY_KP_MULTIPLY                            none       SDLK_KP_MULTIPLY
-BX_KEY_KP_PAGE_DOWN                           none       SDLK_KP3
-#BX_KEY_KP_PAGE_DOWN                           none       SDLK_KP_PAGE_DOWN
-BX_KEY_KP_PAGE_UP                             none       SDLK_KP9
-#BX_KEY_KP_PAGE_UP                             none       SDLK_KP_PAGE_UP
-BX_KEY_KP_RIGHT                               none       SDLK_KP6
-#BX_KEY_KP_RIGHT                               none       SDLK_KP_Right
-BX_KEY_KP_SUBTRACT                            none       SDLK_KP_MINUS
-BX_KEY_KP_UP                                  none       SDLK_KP8
-#BX_KEY_KP_UP                                  none       SDLK_KP_Up
-BX_KEY_LEFT                                   none       SDLK_LEFT
-#BX_KEY_LEFT_BRACKET+BX_KEY_SHIFT_L            '{'        SDLK_BRACELEFT
-BX_KEY_LEFT_BRACKET                           '['        SDLK_LEFTBRACKET
-BX_KEY_MENU                                   none       SDLK_MENU
-BX_KEY_MINUS                                  '-'        SDLK_MINUS
-BX_KEY_MINUS+BX_KEY_SHIFT_L                   '_'        SDLK_UNDERSCORE
-BX_KEY_NUM_LOCK                               none       SDLK_NUMLOCK
-BX_KEY_PAGE_DOWN                              none       SDLK_PAGEDOWN
-BX_KEY_PAGE_UP                                none       SDLK_PAGEUP
-BX_KEY_PAUSE                                  none       SDLK_BREAK
-BX_KEY_PAUSE                                  none       SDLK_PAUSE
-BX_KEY_PERIOD+BX_KEY_SHIFT_L                  '>'        SDLK_GREATER
-BX_KEY_PERIOD                                 '.'        SDLK_PERIOD
-BX_KEY_PRINT                                  none       SDLK_PRINT
-BX_KEY_PRINT                                  none       SDLK_SYSREQ
-BX_KEY_RIGHT                                  none       SDLK_RIGHT
-#BX_KEY_RIGHT_BRACKET+BX_KEY_SHIFT_L           '}'        SDLK_BRACERIGHT
-BX_KEY_RIGHT_BRACKET                          ']'        SDLK_RIGHTBRACKET
-BX_KEY_SCRL_LOCK                              none       SDLK_SCROLLOCK
-BX_KEY_SEMICOLON+BX_KEY_SHIFT_L               ':'        SDLK_COLON
-BX_KEY_SEMICOLON                              ';'        SDLK_SEMICOLON
-BX_KEY_SHIFT_L                                none       SDLK_LSHIFT
-BX_KEY_SHIFT_R                                none       SDLK_RSHIFT
-BX_KEY_SINGLE_QUOTE                           apostrophe SDLK_QUOTE
-BX_KEY_SINGLE_QUOTE+BX_KEY_SHIFT_L            '"'        SDLK_QUOTEDBL
-BX_KEY_SLASH+BX_KEY_SHIFT_L                   '?'        SDLK_QUESTION
-BX_KEY_SLASH                                  '/'        SDLK_SLASH
-BX_KEY_SPACE                                  space      SDLK_SPACE
-#BX_KEY_TAB                                    none       SDLK_ISO_LEFT_TAB
-BX_KEY_TAB                                    tab        SDLK_TAB
-BX_KEY_UP                                     none       SDLK_UP
-BX_KEY_WIN_L                                  none       SDLK_LSUPER
-BX_KEY_WIN_R                                  none       SDLK_LSUPER
diff --git a/tools/ioemu/gui/keymaps/x11-pc-be.map b/tools/ioemu/gui/keymaps/x11-pc-be.map
deleted file mode 100644 (file)
index 0a607e0..0000000
+++ /dev/null
@@ -1,220 +0,0 @@
-# Bochs Keymap file
-# $Id: x11-pc-be.map,v 1.2 2003/07/29 13:31:11 bdenney Exp $
-# Target: PC(x86) keyboard, BE keymap
-# Author: Wouter Verhelst,
-# based on FR keymap by Christophe Bothamy, Bryce Denney
-#
-# The keymap file describes the layout of a keyboard, and how it translates
-# into Bochs key codes.
-#
-# Format:
-#  BX_Keysym                ASCII_equivalent      Xwin_Keysym
-#
-# Or, for keys that require modifiers:
-#  BX_Keysym+BX_Modifier    ASCII_equivalent    Xwin_Keysym
-#
-# BX_Keysym and BX_Modifier must be present in the bx_key_symbol[] list in
-# gui/keymap.cc.  The BX_Modifier is usually a shift key press, but it
-# could be any key.  Presently a maximum of one modifier is supported, but this
-# could be changed in keymap.h (structure def has only one slot for modifier),
-# keymap.cc (parsing code), and iodev/keyboard.cc (simulate keypresses for >1
-# modifier).
-#
-# The ASCII_equivalent must be either apostrophe + one character + apostrophe,
-# or one of these keywords: space, return, tab, backslash, apostrophe, none.
-# This format is designed to look like a char constant in C, but it's a very
-# simple parser.  There's no concept of backslash being an escape char.  The
-# backslash and apostrophe entries are provided for aesthetic purposes only: no
-# C++ programmer wants to see '\' or '''. The parser doesn't care, but they are
-# ugly.
-#
-# Xwin_Keysym is the X windows equivalent of the key combination.  These
-# codes should match whatever you find in /usr/X11R6/include/X11/keysymdef.h.
-# If you're running X windows, Bochs will take each of these Xwin_Keysyms,
-# pull off the XK_ in front, and use XStringToKeysym() to change them into
-# numerical codes.  If this lookup fails, you will get a panic and you need
-# to edit the keymap file.
-
-BX_KEY_0+BX_KEY_SHIFT_L                       '0'        XK_0
-BX_KEY_0                                      'à'        XK_agrave
-BX_KEY_0+BX_KEY_ALT_R                         '}'        XK_braceright
-BX_KEY_1+BX_KEY_SHIFT_L                       '1'        XK_1
-BX_KEY_1                                      '&'        XK_ampersand
-BX_KEY_1+BX_KEY_ALT_R                         '|'        XK_bar
-BX_KEY_2+BX_KEY_SHIFT_L                       '2'        XK_2
-BX_KEY_2+BX_KEY_ALT_R                         '@'        XK_at
-BX_KEY_2                                      'é'        XK_eacute
-BX_KEY_3+BX_KEY_SHIFT_L                       '3'        XK_3
-BX_KEY_3+BX_KEY_ALT_R                         '#'        XK_numbersign
-BX_KEY_3                                      '"'        XK_quotedbl
-BX_KEY_4+BX_KEY_SHIFT_L                       '4'        XK_4
-BX_KEY_4                                      apostrophe XK_apostrophe
-BX_KEY_5+BX_KEY_SHIFT_L                       '5'        XK_5
-BX_KEY_5                                      '('        XK_parenleft
-BX_KEY_6+BX_KEY_SHIFT_L                       '6'        XK_6
-BX_KEY_6+BX_KEY_ALT_R                         '^'        XK_asciicircum
-BX_KEY_6                                      '§'        XK_section
-BX_KEY_7+BX_KEY_SHIFT_L                       '7'        XK_7
-BX_KEY_7                                      'è'        XK_egrave
-BX_KEY_8+BX_KEY_SHIFT_L                       '8'        XK_8
-BX_KEY_8                                      '!'        XK_exclam
-BX_KEY_9+BX_KEY_SHIFT_L                       '9'        XK_9
-BX_KEY_9+BX_KEY_ALT_R                         '{'        XK_braceleft
-BX_KEY_9                                      'ç'        XK_ccedilla
-BX_KEY_A+BX_KEY_SHIFT_L                       'Q'        XK_Q
-BX_KEY_A                                      'q'        XK_q
-BX_KEY_B+BX_KEY_SHIFT_L                       'B'        XK_B
-BX_KEY_B                                      'b'        XK_b
-BX_KEY_C+BX_KEY_SHIFT_L                       'C'        XK_C
-BX_KEY_C                                      'c'        XK_c
-BX_KEY_D+BX_KEY_SHIFT_L                       'D'        XK_D
-BX_KEY_D                                      'd'        XK_d
-BX_KEY_E+BX_KEY_SHIFT_L                       'E'        XK_E
-BX_KEY_E                                      'e'        XK_e
-BX_KEY_E+BX_KEY_ALT_R                         none       XK_EuroSign
-BX_KEY_F+BX_KEY_SHIFT_L                       'F'        XK_F
-BX_KEY_F                                      'f'        XK_f
-BX_KEY_G+BX_KEY_SHIFT_L                       'G'        XK_G
-BX_KEY_G                                      'g'        XK_g
-BX_KEY_H+BX_KEY_SHIFT_L                       'H'        XK_H
-BX_KEY_H                                      'h'        XK_h
-BX_KEY_I+BX_KEY_SHIFT_L                       'I'        XK_I
-BX_KEY_I                                      'i'        XK_i
-BX_KEY_J+BX_KEY_SHIFT_L                       'J'        XK_J
-BX_KEY_J                                      'j'        XK_j
-BX_KEY_K+BX_KEY_SHIFT_L                       'K'        XK_K
-BX_KEY_K                                      'k'        XK_k
-BX_KEY_L+BX_KEY_SHIFT_L                       'L'        XK_L
-BX_KEY_L                                      'l'        XK_l
-BX_KEY_M+BX_KEY_SHIFT_L                       '?'        XK_question
-BX_KEY_M                                      ','        XK_comma
-BX_KEY_N+BX_KEY_SHIFT_L                       'N'        XK_N
-BX_KEY_N                                      'n'        XK_n
-BX_KEY_O+BX_KEY_SHIFT_L                       'O'        XK_O
-BX_KEY_O                                      'o'        XK_o
-BX_KEY_P+BX_KEY_SHIFT_L                       'P'        XK_P
-BX_KEY_P                                      'p'        XK_p
-BX_KEY_Q+BX_KEY_SHIFT_L                       'A'        XK_A
-BX_KEY_Q                                      'a'        XK_a
-BX_KEY_R+BX_KEY_SHIFT_L                       'R'        XK_R
-BX_KEY_R                                      'r'        XK_r
-BX_KEY_S+BX_KEY_SHIFT_L                       'S'        XK_S
-BX_KEY_S                                      's'        XK_s
-BX_KEY_T+BX_KEY_SHIFT_L                       'T'        XK_T
-BX_KEY_T                                      't'        XK_t
-BX_KEY_U+BX_KEY_SHIFT_L                       'U'        XK_U
-BX_KEY_U                                      'u'        XK_u
-BX_KEY_V+BX_KEY_SHIFT_L                       'V'        XK_V
-BX_KEY_V                                      'v'        XK_v
-BX_KEY_W+BX_KEY_SHIFT_L                       'Z'        XK_Z
-BX_KEY_W                                      'z'        XK_z
-BX_KEY_X+BX_KEY_SHIFT_L                       'X'        XK_X
-BX_KEY_X                                      'x'        XK_x
-BX_KEY_Y+BX_KEY_SHIFT_L                       'Y'        XK_Y
-BX_KEY_Y                                      'y'        XK_y
-BX_KEY_Z+BX_KEY_SHIFT_L                       'W'        XK_W
-BX_KEY_Z                                      'w'        XK_w
-BX_KEY_F1                                     none       XK_F1
-BX_KEY_F2                                     none       XK_F2
-BX_KEY_F3                                     none       XK_F3
-BX_KEY_F4                                     none       XK_F4
-BX_KEY_F5                                     none       XK_F5
-BX_KEY_F6                                     none       XK_F6
-BX_KEY_F7                                     none       XK_F7
-BX_KEY_F8                                     none       XK_F8
-BX_KEY_F9                                     none       XK_F9
-BX_KEY_F10                                    none       XK_F10
-BX_KEY_F11                                    none       XK_F11
-BX_KEY_F12                                    none       XK_F12
-BX_KEY_ALT_L                                  none       XK_Alt_L
-BX_KEY_ALT_L                                  none       XK_Meta_L
-BX_KEY_ALT_R                                  none       XK_Alt_R
-BX_KEY_ALT_R                                  none       XK_Mode_switch
-BX_KEY_ALT_R                                  none       XK_Multi_key
-BX_KEY_BACKSLASH                              'µ'        XK_mu
-BX_KEY_BACKSLASH+BX_KEY_SHIFT_L               '£'        XK_sterling
-BX_KEY_BACKSLASH+BX_KEY_ALT_R                 '`'        XK_dead_grave
-BX_KEY_BACKSPACE                              none       XK_BackSpace
-BX_KEY_CAPS_LOCK                              none       XK_Caps_Lock
-BX_KEY_COMMA+BX_KEY_SHIFT_L                   '.'        XK_period
-BX_KEY_COMMA                                  ';'        XK_semicolon
-BX_KEY_CTRL_L                                 none       XK_Control_L
-BX_KEY_CTRL_R                                 none       XK_Control_R
-BX_KEY_DELETE                                 none       XK_Delete
-BX_KEY_DOWN                                   none       XK_Down
-BX_KEY_END                                    none       XK_End
-BX_KEY_ENTER                                  return     XK_Return
-BX_KEY_EQUALS                                 '-'        XK_minus
-BX_KEY_EQUALS+BX_KEY_SHIFT_L                  '_'        XK_underscore
-BX_KEY_ESC                                    none       XK_Escape
-BX_KEY_GRAVE                                  '²'        XK_twosuperior
-BX_KEY_GRAVE+BX_KEY_SHIFT_L                   '³'        XK_threesuperior
-BX_KEY_HOME                                   none       XK_Home
-BX_KEY_INSERT                                 none       XK_Insert
-BX_KEY_KP_5                                   none       XK_KP_5
-BX_KEY_KP_5                                   none       XK_KP_Begin
-BX_KEY_KP_ADD                                 none       XK_KP_Add
-BX_KEY_KP_DELETE                              none       XK_KP_Decimal
-BX_KEY_KP_DELETE                              none       XK_KP_Delete
-BX_KEY_KP_DIVIDE                              none       XK_KP_Divide
-BX_KEY_KP_DOWN                                none       XK_KP_2
-BX_KEY_KP_DOWN                                none       XK_KP_Down
-BX_KEY_KP_END                                 none       XK_KP_1
-BX_KEY_KP_END                                 none       XK_KP_End
-BX_KEY_KP_ENTER                               none       XK_KP_Enter
-BX_KEY_KP_HOME                                none       XK_KP_7
-BX_KEY_KP_HOME                                none       XK_KP_Home
-BX_KEY_KP_INSERT                              none       XK_KP_0
-BX_KEY_KP_INSERT                              none       XK_KP_Insert
-BX_KEY_KP_LEFT                                none       XK_KP_4
-BX_KEY_KP_LEFT                                none       XK_KP_Left
-BX_KEY_KP_MULTIPLY                            none       XK_KP_Multiply
-BX_KEY_KP_PAGE_DOWN                           none       XK_KP_3
-BX_KEY_KP_PAGE_DOWN                           none       XK_KP_Page_Down
-BX_KEY_KP_PAGE_UP                             none       XK_KP_9
-BX_KEY_KP_PAGE_UP                             none       XK_KP_Page_Up
-BX_KEY_KP_RIGHT                               none       XK_KP_6
-BX_KEY_KP_RIGHT                               none       XK_KP_Right
-BX_KEY_KP_SUBTRACT                            none       XK_KP_Subtract
-BX_KEY_KP_UP                                  none       XK_KP_8
-BX_KEY_KP_UP                                  none       XK_KP_Up
-BX_KEY_LEFT                                   none       XK_Left
-BX_KEY_LEFT_BACKSLASH+BX_KEY_SHIFT_L          '>'        XK_greater
-BX_KEY_LEFT_BACKSLASH                         '<'        XK_less
-BX_KEY_LEFT_BACKSLASH+BX_KEY_ALT_R            backslash  XK_backslash
-BX_KEY_LEFT_BRACKET                           none       XK_dead_circumflex
-BX_KEY_LEFT_BRACKET+BX_KEY_SHIFT_L            none       XK_dead_diaeresis
-BX_KEY_LEFT_BRACKET+BX_KEY_ALT_R              '['        XK_bracketleft
-BX_KEY_MENU                                   none       XK_Menu
-BX_KEY_MINUS+BX_KEY_SHIFT_L                   '°'        XK_degree
-BX_KEY_MINUS                                  ')'        XK_parenright
-BX_KEY_NUM_LOCK                               none       XK_Num_Lock
-BX_KEY_PAGE_DOWN                              none       XK_Page_Down
-BX_KEY_PAGE_UP                                none       XK_Page_Up
-BX_KEY_PAUSE                                  none       XK_Break
-BX_KEY_PAUSE                                  none       XK_Pause
-BX_KEY_PERIOD                                 ':'        XK_colon
-BX_KEY_PERIOD+BX_KEY_SHIFT_L                  '/'        XK_slash
-BX_KEY_PRINT                                  none       XK_Print
-BX_KEY_PRINT                                  none       XK_Sys_Req
-BX_KEY_RIGHT                                  none       XK_Right
-BX_KEY_RIGHT_BRACKET                          '$'        XK_dollar
-BX_KEY_RIGHT_BRACKET+BX_KEY_SHIFT_L           '*'        XK_asterisk
-BX_KEY_RIGHT_BRACKET+BX_KEY_ALT_R             ']'        XK_bracketright
-BX_KEY_SCRL_LOCK                              none       XK_Scroll_Lock
-BX_KEY_SEMICOLON+BX_KEY_SHIFT_L               'M'        XK_M
-BX_KEY_SEMICOLON                              'm'        XK_m
-BX_KEY_SHIFT_L                                none       XK_Shift_L
-BX_KEY_SHIFT_R                                none       XK_Shift_R
-BX_KEY_SINGLE_QUOTE+BX_KEY_SHIFT_L            '%'        XK_percent
-BX_KEY_SINGLE_QUOTE+BX_KEY_ALT_R              none       XK_dead_acute
-BX_KEY_SINGLE_QUOTE                           'ù'        XK_ugrave
-BX_KEY_SLASH                                  '='        XK_equal
-BX_KEY_SLASH+BX_KEY_SHIFT_L                   '+'        XK_plus
-BX_KEY_SLASH+BX_KEY_ALT_R                     none       XK_dead_tilde
-BX_KEY_SPACE                                  space      XK_space
-BX_KEY_TAB                                    none       XK_ISO_Left_Tab
-BX_KEY_TAB                                    tab        XK_Tab
-BX_KEY_UP                                     none       XK_Up
-BX_KEY_WIN_L                                  none       XK_Super_L
-BX_KEY_WIN_R                                  none       XK_Super_R
diff --git a/tools/ioemu/gui/keymaps/x11-pc-da.map b/tools/ioemu/gui/keymaps/x11-pc-da.map
deleted file mode 100644 (file)
index 41ead2b..0000000
+++ /dev/null
@@ -1,247 +0,0 @@
-# Bochs Keymap file
-# $Id: x11-pc-da.map,v 0.9 2002/09/02
-# Target: PC(x86) keyboard, DA keymap
-# Author: Andreas Ott
-#
-# The keymap file describes the layout of a keyboard, and how it translates
-# into Bochs key codes.
-#
-# Format:
-#  BX_Keysym                ASCII_equivalent      Xwin_Keysym
-#
-# Or, for keys that require modifiers:
-#  BX_Keysym+BX_Modifier    ASCII_equivalent    Xwin_Keysym
-#
-# BX_Keysym and BX_Modifier must be present in the bx_key_symbol[] list in
-# gui/keymap.cc.  The BX_Modifier is usually a shift key press, but it
-# could be any key.  Presently a maximum of one modifier is supported, but this
-# could be changed in keymap.h (structure def has only one slot for modifier),
-# keymap.cc (parsing code), and iodev/keyboard.cc (simulate keypresses for >1
-# modifier).
-#
-# The ASCII_equivalent must be either apostrophe + one character + apostrophe,
-# or one of these keywords: space, return, tab, backslash, apostrophe, none.
-# This format is designed to look like a char constant in C, but it's a very
-# simple parser.  There's no concept of backslash being an escape char.  The
-# backslash and apostrophe entries are provided for aesthetic purposes only: no
-# C++ programmer wants to see '\' or '''. The parser doesn't care, but they are
-# ugly.
-#
-# Xwin_Keysym is the X windows equivalent of the key combination.  These
-# codes should match whatever you find in /usr/X11R6/include/X11/keysymdef.h.
-# If you're running X windows, Bochs will take each of these Xwin_Keysyms,
-# pull off the XK_ in front, and use XStringToKeysym() to change them into
-# numerical codes.  If this lookup fails, you will get a panic and you need
-# to edit the keymap file.
-
-BX_KEY_0                                      '0'        XK_0
-BX_KEY_0+BX_KEY_ALT_R                         '}'        XK_braceright
-BX_KEY_0+BX_KEY_SHIFT_L                       '='        XK_equal
-BX_KEY_1                                      '1'        XK_1
-BX_KEY_1+BX_KEY_SHIFT_L                       '!'        XK_exclam
-BX_KEY_1+BX_KEY_ALT_R                         '¡'        XK_exclamdown
-BX_KEY_2                                      '2'        XK_2
-BX_KEY_2+BX_KEY_SHIFT_L                       '='        XK_quotedbl
-BX_KEY_2+BX_KEY_ALT_R                         '@'        XK_at # XK_twosuperior
-BX_KEY_3                                      '3'        XK_3
-BX_KEY_3+BX_KEY_SHIFT_L                       '#'        XK_numbersign
-BX_KEY_3+BX_KEY_ALT_R                         '£'        XK_sterling
-BX_KEY_4                                      '4'        XK_4
-BX_KEY_4+BX_KEY_SHIFT_L                       '¤'        XK_currency
-BX_KEY_4+BX_KEY_ALT_R                         '$'        XK_dollar
-BX_KEY_5                                      '5'        XK_5
-BX_KEY_5+BX_KEY_ALT_R                         '½'        XK_onehalf
-BX_KEY_5+BX_KEY_SHIFT_L                       '%'        XK_percent
-BX_KEY_6                                      '6'        XK_6
-BX_KEY_6+BX_KEY_SHIFT_L                       '&'        XK_ampersand
-BX_KEY_6+BX_KEY_ALT_R                         '¥'        XK_yen
-BX_KEY_7                                      '7'        XK_7
-BX_KEY_7+BX_KEY_ALT_R                         '{'        XK_braceleft
-BX_KEY_7+BX_KEY_SHIFT_L                       '/'        XK_slash
-BX_KEY_8                                      '8'        XK_8
-BX_KEY_8+BX_KEY_ALT_R                         '['        XK_bracketleft
-BX_KEY_8+BX_KEY_SHIFT_L                       '('        XK_parenleft
-BX_KEY_9                                      '9'        XK_9
-BX_KEY_9+BX_KEY_ALT_R                         ']'        XK_bracketright
-BX_KEY_9+BX_KEY_SHIFT_L                       ')'        XK_parenright
-BX_KEY_A+BX_KEY_SHIFT_L                       'A'        XK_A
-BX_KEY_A                                      'a'        XK_a
-BX_KEY_A+BX_KEY_ALT_R                         'ª'        XK_ordfeminine
-BX_KEY_B+BX_KEY_SHIFT_L                       'B'        XK_B
-BX_KEY_B                                      'b'        XK_b
-BX_KEY_B+BX_KEY_ALT_R                         none       XK_rightdoublequotemark
-BX_KEY_C+BX_KEY_SHIFT_L                       'C'        XK_C
-BX_KEY_C                                      'c'        XK_c
-BX_KEY_C+BX_KEY_ALT_R                         '©'        XK_copyright
-BX_KEY_D+BX_KEY_SHIFT_L                       'D'        XK_D
-BX_KEY_D                                      'd'        XK_d
-BX_KEY_D+BX_KEY_ALT_R                         'ð'        XK_eth
-BX_KEY_E+BX_KEY_SHIFT_L                       'E'        XK_E
-BX_KEY_E+BX_KEY_ALT_R                         '?'        XK_EuroSign
-BX_KEY_E                                      'e'        XK_e
-BX_KEY_F+BX_KEY_SHIFT_L                       'F'        XK_F
-BX_KEY_F+BX_KEY_ALT_R                         '?'        XK_dstroke
-BX_KEY_F                                      'f'        XK_f
-BX_KEY_G+BX_KEY_SHIFT_L                       'G'        XK_G
-BX_KEY_G+BX_KEY_ALT_R                         '?'        XK_eng
-BX_KEY_G                                      'g'        XK_g
-BX_KEY_H+BX_KEY_SHIFT_L                       'H'        XK_H
-BX_KEY_H                                      'h'        XK_h
-BX_KEY_H+BX_KEY_ALT_R                         '?'        XK_hstroke
-BX_KEY_I+BX_KEY_SHIFT_L                       'I'        XK_I
-BX_KEY_I                                      'i'        XK_i
-BX_KEY_I+BX_KEY_ALT_R                         none       XK_rightarrow
-BX_KEY_J+BX_KEY_SHIFT_L                       'J'        XK_J
-BX_KEY_J                                      'j'        XK_j
-BX_KEY_K+BX_KEY_SHIFT_L                       'K'        XK_K
-BX_KEY_K                                      'k'        XK_k
-BX_KEY_K+BX_KEY_ALT_R                         none       XK_kra
-BX_KEY_L+BX_KEY_SHIFT_L                       'L'        XK_L
-BX_KEY_L                                      'l'        XK_l
-BX_KEY_M+BX_KEY_SHIFT_L                       'M'        XK_M
-BX_KEY_M                                      'm'        XK_m
-BX_KEY_M+BX_KEY_ALT_R                         'µ'        XK_mu
-BX_KEY_N+BX_KEY_SHIFT_L                       'N'        XK_N
-BX_KEY_N                                      'n'        XK_n
-BX_KEY_O+BX_KEY_SHIFT_L                       'O'        XK_O
-BX_KEY_O                                      'o'        XK_o
-BX_KEY_O+BX_KEY_ALT_R                         none       XK_oslash
-BX_KEY_P+BX_KEY_SHIFT_L                       'P'        XK_P
-BX_KEY_P                                      'p'        XK_p
-BX_KEY_P+BX_KEY_ALT_R                         'þ'        XK_thorn
-BX_KEY_Q+BX_KEY_SHIFT_L                       'Q'        XK_Q
-BX_KEY_Q+BX_KEY_ALT_R                         '@'        XK_at
-BX_KEY_Q                                      'q'        XK_q
-BX_KEY_R+BX_KEY_SHIFT_L                       'R'        XK_R
-BX_KEY_R+BX_KEY_ALT_R                         '®'        XK_registered
-BX_KEY_R                                      'r'        XK_r
-BX_KEY_S+BX_KEY_SHIFT_L                       'S'        XK_S
-BX_KEY_S                                      's'        XK_s
-BX_KEY_S+BX_KEY_ALT_R                         'ß'        XK_ssharp
-BX_KEY_T+BX_KEY_SHIFT_L                       'T'        XK_T
-BX_KEY_T                                      't'        XK_t
-BX_KEY_T+BX_KEY_ALT_R                         'þ'        XK_thorn
-BX_KEY_U+BX_KEY_SHIFT_L                       'U'        XK_U
-BX_KEY_U+BX_KEY_ALT_R                         none       XK_downarrow
-BX_KEY_U                                      'u'        XK_u
-BX_KEY_V+BX_KEY_SHIFT_L                       'V'        XK_V
-BX_KEY_V+BX_KEY_ALT_R                         none       XK_leftdoublequotemark
-BX_KEY_V                                      'v'        XK_v
-BX_KEY_W+BX_KEY_SHIFT_L                       'W'        XK_W
-BX_KEY_W+BX_KEY_ALT_R                         '?'        XK_lstroke
-BX_KEY_W                                      'w'        XK_w
-BX_KEY_X+BX_KEY_SHIFT_L                       'X'        XK_X
-BX_KEY_X+BX_KEY_ALT_R                         '»'        XK_guillemotright
-BX_KEY_X                                      'x'        XK_x
-BX_KEY_Y+BX_KEY_SHIFT_L                       'Y'        XK_Y
-BX_KEY_Y+BX_KEY_ALT_R                         none       XK_leftarrow
-BX_KEY_Y                                      'y'        XK_y
-BX_KEY_Z+BX_KEY_SHIFT_L                       'Z'        XK_Z
-BX_KEY_Z+BX_KEY_ALT_R                         '«'        XK_guillemotleft
-BX_KEY_Z                                      'z'        XK_z
-BX_KEY_F1                                     none       XK_F1
-BX_KEY_F2                                     none       XK_F2
-BX_KEY_F3                                     none       XK_F3
-BX_KEY_F4                                     none       XK_F4
-BX_KEY_F5                                     none       XK_F5
-BX_KEY_F6                                     none       XK_F6
-BX_KEY_F7                                     none       XK_F7
-BX_KEY_F8                                     none       XK_F8
-BX_KEY_F9                                     none       XK_F9
-BX_KEY_F10                                    none       XK_F10
-BX_KEY_F11                                    none       XK_F11
-BX_KEY_F12                                    none       XK_F12
-BX_KEY_ALT_L                                  none       XK_Alt_L
-BX_KEY_ALT_L                                  none       XK_Meta_L
-BX_KEY_ALT_R                                  none       XK_Mode_switch
-BX_KEY_ALT_R                                  none       XK_Multi_key
-BX_KEY_BACKSLASH                              apostrophe XK_apostrophe
-BX_KEY_BACKSLASH+BX_KEY_SHIFT_L               '*'        XK_asterisk
-BX_KEY_BACKSPACE                              none       XK_BackSpace
-BX_KEY_CAPS_LOCK                              none       XK_Caps_Lock
-BX_KEY_COMMA                                  ','        XK_comma
-BX_KEY_COMMA+BX_KEY_ALT_R                     none       XK_horizconnector
-BX_KEY_COMMA+BX_KEY_SHIFT_L                   ';'        XK_semicolon
-BX_KEY_CTRL_L                                 none       XK_Control_L
-BX_KEY_CTRL_R                                 none       XK_Control_R
-BX_KEY_DELETE                                 none       XK_Delete
-BX_KEY_DOWN                                   none       XK_Down
-BX_KEY_END                                    none       XK_End
-BX_KEY_ENTER                                  return     XK_Return
-BX_KEY_EQUALS                                 none       XK_acute
-BX_KEY_EQUALS+BX_KEY_ALT_R                    '|'        XK_bar
-BX_KEY_EQUALS+BX_KEY_SHIFT_L                  '`'        XK_grave
-BX_KEY_ESC                                    none       XK_Escape
-BX_KEY_GRAVE                                  '½'        XK_onehalf
-BX_KEY_GRAVE+BX_KEY_SHIFT_L                   '§'        XK_section
-BX_KEY_GRAVE+BX_KEY_ALT_R                     '¾'        XK_threequarters
-BX_KEY_HOME                                   none       XK_Home
-BX_KEY_INSERT                                 none       XK_Insert
-BX_KEY_KP_5                                   none       XK_KP_5
-BX_KEY_KP_5                                   none       XK_KP_Begin
-BX_KEY_KP_ADD                                 none       XK_KP_Add
-BX_KEY_KP_DELETE                              none       XK_KP_Decimal
-BX_KEY_KP_DELETE                              none       XK_KP_Delete
-BX_KEY_KP_DIVIDE                              none       XK_KP_Divide
-BX_KEY_KP_DOWN                                none       XK_KP_2
-BX_KEY_KP_DOWN                                none       XK_KP_Down
-BX_KEY_KP_END                                 none       XK_KP_1
-BX_KEY_KP_END                                 none       XK_KP_End
-BX_KEY_KP_ENTER                               none       XK_KP_Enter
-BX_KEY_KP_HOME                                none       XK_KP_7
-BX_KEY_KP_HOME                                none       XK_KP_Home
-BX_KEY_KP_INSERT                              none       XK_KP_0
-BX_KEY_KP_INSERT                              none       XK_KP_Insert
-BX_KEY_KP_LEFT                                none       XK_KP_4
-BX_KEY_KP_LEFT                                none       XK_KP_Left
-BX_KEY_KP_MULTIPLY                            none       XK_KP_Multiply
-BX_KEY_KP_PAGE_DOWN                           none       XK_KP_3
-BX_KEY_KP_PAGE_DOWN                           none       XK_KP_Page_Down
-BX_KEY_KP_PAGE_UP                             none       XK_KP_9
-BX_KEY_KP_PAGE_UP                             none       XK_KP_Page_Up
-BX_KEY_KP_RIGHT                               none       XK_KP_6
-BX_KEY_KP_RIGHT                               none       XK_KP_Right
-BX_KEY_KP_SUBTRACT                            none       XK_KP_Subtract
-BX_KEY_KP_UP                                  none       XK_KP_8
-BX_KEY_KP_UP                                  none       XK_KP_Up
-BX_KEY_LEFT                                   none       XK_Left
-BX_KEY_LEFT_BACKSLASH+BX_KEY_ALT_R            backslash  XK_backslash
-BX_KEY_LEFT_BACKSLASH+BX_KEY_SHIFT_L          '>'        XK_greater
-BX_KEY_LEFT_BACKSLASH                         '<'        XK_less
-BX_KEY_LEFT_BRACKET+BX_KEY_SHIFT_L            'Å'        XK_Aring
-BX_KEY_LEFT_BRACKET+BX_KEY_ALT_L              none       XK_diaeresis
-BX_KEY_LEFT_BRACKET                           'å'        XK_aring
-BX_KEY_MENU                                   none       XK_Menu
-BX_KEY_MINUS+BX_KEY_ALT_R                     '±'        XK_plusminus
-BX_KEY_MINUS+BX_KEY_SHIFT_L                   '?'        XK_question
-BX_KEY_MINUS                                  '+'        XK_plus
-BX_KEY_NUM_LOCK                               none       XK_Num_Lock
-BX_KEY_PAGE_DOWN                              none       XK_Page_Down
-BX_KEY_PAGE_UP                                none       XK_Page_Up
-BX_KEY_PAUSE                                  none       XK_Break
-BX_KEY_PAUSE                                  none       XK_Pause
-BX_KEY_PERIOD+BX_KEY_SHIFT_L                  ':'        XK_colon
-BX_KEY_PERIOD                                 '.'        XK_period
-BX_KEY_PERIOD+BX_KEY_ALT_R                    '·'        XK_periodcentered
-BX_KEY_PRINT                                  none       XK_Print
-BX_KEY_PRINT                                  none       XK_Sys_Req
-BX_KEY_RIGHT                                  none       XK_Right
-BX_KEY_RIGHT_BRACKET+BX_KEY_ALT_R             '~'        XK_asciitilde
-BX_KEY_RIGHT_BRACKET+BX_KEY_SHIFT_L           '^'        XK_asciicircum
-BX_KEY_RIGHT_BRACKET                          '"'        XK_diaeresis
-BX_KEY_SCRL_LOCK                              none       XK_Scroll_Lock
-BX_KEY_SEMICOLON+BX_KEY_SHIFT_L               'Æ'        XK_AE
-BX_KEY_SEMICOLON                              'æ'        XK_ae
-BX_KEY_SHIFT_L                                none       XK_Shift_L
-BX_KEY_SHIFT_R                                none       XK_Shift_R
-BX_KEY_SINGLE_QUOTE                           'ø'        XK_oslash
-BX_KEY_SINGLE_QUOTE+BX_KEY_SHIFT_L            'Ø'        XK_Ooblique
-BX_KEY_SLASH+BX_KEY_ALT_R                     '­'        XK_hyphen
-BX_KEY_SLASH                                  '-'        XK_minus
-BX_KEY_SLASH+BX_KEY_SHIFT_L                   '_'        XK_underscore
-BX_KEY_SPACE                                  space      XK_space
-BX_KEY_TAB                                    none       XK_ISO_Left_Tab
-BX_KEY_TAB                                    tab        XK_Tab
-BX_KEY_UP                                     none       XK_Up
-BX_KEY_WIN_L                                  none       XK_Super_L
-BX_KEY_WIN_R                                  none       XK_Super_R
diff --git a/tools/ioemu/gui/keymaps/x11-pc-de.map b/tools/ioemu/gui/keymaps/x11-pc-de.map
deleted file mode 100644 (file)
index 929ad06..0000000
+++ /dev/null
@@ -1,247 +0,0 @@
-# Bochs Keymap file
-# $Id: x11-pc-de.map,v 1.7 2002/10/24 21:06:56 bdenney Exp $
-# Target: PC(x86) keyboard, DE keymap
-# Author: Volker Ruppert
-#
-# The keymap file describes the layout of a keyboard, and how it translates
-# into Bochs key codes.
-#
-# Format:
-#  BX_Keysym                ASCII_equivalent      Xwin_Keysym
-#
-# Or, for keys that require modifiers:
-#  BX_Keysym+BX_Modifier    ASCII_equivalent    Xwin_Keysym
-#
-# BX_Keysym and BX_Modifier must be present in the bx_key_symbol[] list in
-# gui/keymap.cc.  The BX_Modifier is usually a shift key press, but it
-# could be any key.  Presently a maximum of one modifier is supported, but this
-# could be changed in keymap.h (structure def has only one slot for modifier),
-# keymap.cc (parsing code), and iodev/keyboard.cc (simulate keypresses for >1
-# modifier).
-#
-# The ASCII_equivalent must be either apostrophe + one character + apostrophe,
-# or one of these keywords: space, return, tab, backslash, apostrophe, none.
-# This format is designed to look like a char constant in C, but it's a very
-# simple parser.  There's no concept of backslash being an escape char.  The
-# backslash and apostrophe entries are provided for aesthetic purposes only: no
-# C++ programmer wants to see '\' or '''. The parser doesn't care, but they are
-# ugly.
-#
-# Xwin_Keysym is the X windows equivalent of the key combination.  These
-# codes should match whatever you find in /usr/X11R6/include/X11/keysymdef.h.
-# If you're running X windows, Bochs will take each of these Xwin_Keysyms,
-# pull off the XK_ in front, and use XStringToKeysym() to change them into
-# numerical codes.  If this lookup fails, you will get a panic and you need
-# to edit the keymap file.
-
-BX_KEY_0                                      '0'        XK_0
-BX_KEY_0+BX_KEY_ALT_R                         '}'        XK_braceright
-BX_KEY_0+BX_KEY_SHIFT_L                       '='        XK_equal
-BX_KEY_1                                      '1'        XK_1
-BX_KEY_1+BX_KEY_SHIFT_L                       '!'        XK_exclam
-BX_KEY_1+BX_KEY_ALT_R                         '¹'        XK_onesuperior
-BX_KEY_2                                      '2'        XK_2
-BX_KEY_2+BX_KEY_SHIFT_L                       '"'        XK_quotedbl
-BX_KEY_2+BX_KEY_ALT_R                         '²'        XK_twosuperior
-BX_KEY_3                                      '3'        XK_3
-BX_KEY_3+BX_KEY_SHIFT_L                       '§'        XK_section
-BX_KEY_3+BX_KEY_ALT_R                         '³'        XK_threesuperior
-BX_KEY_4                                      '4'        XK_4
-BX_KEY_4+BX_KEY_SHIFT_L                       '$'        XK_dollar
-BX_KEY_4+BX_KEY_ALT_R                         '¼'        XK_onequarter
-BX_KEY_5                                      '5'        XK_5
-BX_KEY_5+BX_KEY_ALT_R                         '½'        XK_onehalf
-BX_KEY_5+BX_KEY_SHIFT_L                       '%'        XK_percent
-BX_KEY_6                                      '6'        XK_6
-BX_KEY_6+BX_KEY_SHIFT_L                       '&'        XK_ampersand
-BX_KEY_6+BX_KEY_ALT_R                         '¾'        XK_threequarters
-BX_KEY_7                                      '7'        XK_7
-BX_KEY_7+BX_KEY_ALT_R                         '{'        XK_braceleft
-BX_KEY_7+BX_KEY_SHIFT_L                       '/'        XK_slash
-BX_KEY_8                                      '8'        XK_8
-BX_KEY_8+BX_KEY_ALT_R                         '['        XK_bracketleft
-BX_KEY_8+BX_KEY_SHIFT_L                       '('        XK_parenleft
-BX_KEY_9                                      '9'        XK_9
-BX_KEY_9+BX_KEY_ALT_R                         ']'        XK_bracketright
-BX_KEY_9+BX_KEY_SHIFT_L                       ')'        XK_parenright
-BX_KEY_A+BX_KEY_SHIFT_L                       'A'        XK_A
-BX_KEY_A                                      'a'        XK_a
-BX_KEY_A+BX_KEY_ALT_R                         'æ'        XK_ae
-BX_KEY_B+BX_KEY_SHIFT_L                       'B'        XK_B
-BX_KEY_B                                      'b'        XK_b
-BX_KEY_B+BX_KEY_ALT_R                         none       XK_rightdoublequotemark
-BX_KEY_C+BX_KEY_SHIFT_L                       'C'        XK_C
-BX_KEY_C                                      'c'        XK_c
-BX_KEY_C+BX_KEY_ALT_R                         '¢'        XK_cent
-BX_KEY_D+BX_KEY_SHIFT_L                       'D'        XK_D
-BX_KEY_D                                      'd'        XK_d
-BX_KEY_D+BX_KEY_ALT_R                         'ð'        XK_eth
-BX_KEY_E+BX_KEY_SHIFT_L                       'E'        XK_E
-BX_KEY_E+BX_KEY_ALT_R                         none       XK_EuroSign
-BX_KEY_E                                      'e'        XK_e
-BX_KEY_F+BX_KEY_SHIFT_L                       'F'        XK_F
-BX_KEY_F+BX_KEY_ALT_R                         none       XK_dstroke
-BX_KEY_F                                      'f'        XK_f
-BX_KEY_G+BX_KEY_SHIFT_L                       'G'        XK_G
-BX_KEY_G+BX_KEY_ALT_R                         none       XK_eng
-BX_KEY_G                                      'g'        XK_g
-BX_KEY_H+BX_KEY_SHIFT_L                       'H'        XK_H
-BX_KEY_H                                      'h'        XK_h
-BX_KEY_H+BX_KEY_ALT_R                         none       XK_hstroke
-BX_KEY_I+BX_KEY_SHIFT_L                       'I'        XK_I
-BX_KEY_I                                      'i'        XK_i
-BX_KEY_I+BX_KEY_ALT_R                         none       XK_rightarrow
-BX_KEY_J+BX_KEY_SHIFT_L                       'J'        XK_J
-BX_KEY_J                                      'j'        XK_j
-BX_KEY_K+BX_KEY_SHIFT_L                       'K'        XK_K
-BX_KEY_K                                      'k'        XK_k
-BX_KEY_K+BX_KEY_ALT_R                         none       XK_kra
-BX_KEY_L+BX_KEY_SHIFT_L                       'L'        XK_L
-BX_KEY_L                                      'l'        XK_l
-BX_KEY_M+BX_KEY_SHIFT_L                       'M'        XK_M
-BX_KEY_M                                      'm'        XK_m
-BX_KEY_M+BX_KEY_ALT_R                         'µ'        XK_mu
-BX_KEY_N+BX_KEY_SHIFT_L                       'N'        XK_N
-BX_KEY_N                                      'n'        XK_n
-BX_KEY_O+BX_KEY_SHIFT_L                       'O'        XK_O
-BX_KEY_O                                      'o'        XK_o
-BX_KEY_O+BX_KEY_ALT_R                         'ø'        XK_oslash
-BX_KEY_P+BX_KEY_SHIFT_L                       'P'        XK_P
-BX_KEY_P                                      'p'        XK_p
-BX_KEY_P+BX_KEY_ALT_R                         'þ'        XK_thorn
-BX_KEY_Q+BX_KEY_SHIFT_L                       'Q'        XK_Q
-BX_KEY_Q+BX_KEY_ALT_R                         '@'        XK_at
-BX_KEY_Q                                      'q'        XK_q
-BX_KEY_R+BX_KEY_SHIFT_L                       'R'        XK_R
-BX_KEY_R+BX_KEY_ALT_R                         '¶'        XK_paragraph
-BX_KEY_R                                      'r'        XK_r
-BX_KEY_S+BX_KEY_SHIFT_L                       'S'        XK_S
-BX_KEY_S                                      's'        XK_s
-BX_KEY_T+BX_KEY_SHIFT_L                       'T'        XK_T
-BX_KEY_T                                      't'        XK_t
-BX_KEY_T+BX_KEY_ALT_R                         none       XK_tslash
-BX_KEY_U+BX_KEY_SHIFT_L                       'U'        XK_U
-BX_KEY_U+BX_KEY_ALT_R                         none       XK_downarrow
-BX_KEY_U                                      'u'        XK_u
-BX_KEY_V+BX_KEY_SHIFT_L                       'V'        XK_V
-BX_KEY_V+BX_KEY_ALT_R                         none       XK_leftdoublequotemark
-BX_KEY_V                                      'v'        XK_v
-BX_KEY_W+BX_KEY_SHIFT_L                       'W'        XK_W
-BX_KEY_W+BX_KEY_ALT_R                         none       XK_lstroke
-BX_KEY_W                                      'w'        XK_w
-BX_KEY_X+BX_KEY_SHIFT_L                       'X'        XK_X
-BX_KEY_X+BX_KEY_ALT_R                         '»'        XK_guillemotright
-BX_KEY_X                                      'x'        XK_x
-BX_KEY_Y+BX_KEY_SHIFT_L                       'Z'        XK_Z
-BX_KEY_Y+BX_KEY_ALT_R                         none       XK_leftarrow
-BX_KEY_Y                                      'z'        XK_z
-BX_KEY_Z+BX_KEY_SHIFT_L                       'Y'        XK_Y
-BX_KEY_Z+BX_KEY_ALT_R                         '«'        XK_guillemotleft
-BX_KEY_Z                                      'y'        XK_y
-BX_KEY_F1                                     none       XK_F1
-BX_KEY_F2                                     none       XK_F2
-BX_KEY_F3                                     none       XK_F3
-BX_KEY_F4                                     none       XK_F4
-BX_KEY_F5                                     none       XK_F5
-BX_KEY_F6                                     none       XK_F6
-BX_KEY_F7                                     none       XK_F7
-BX_KEY_F8                                     none       XK_F8
-BX_KEY_F9                                     none       XK_F9
-BX_KEY_F10                                    none       XK_F10
-BX_KEY_F11                                    none       XK_F11
-BX_KEY_F12                                    none       XK_F12
-BX_KEY_ALT_L                                  none       XK_Alt_L
-BX_KEY_ALT_L                                  none       XK_Meta_L
-BX_KEY_ALT_R                                  none       XK_Alt_R
-BX_KEY_ALT_R                                  none       XK_Mode_switch
-BX_KEY_ALT_R                                  none       XK_Multi_key
-BX_KEY_BACKSLASH                              apostrophe XK_apostrophe
-BX_KEY_BACKSLASH                              '#'        XK_numbersign
-BX_KEY_BACKSPACE                              none       XK_BackSpace
-BX_KEY_CAPS_LOCK                              none       XK_Caps_Lock
-BX_KEY_COMMA                                  ','        XK_comma
-BX_KEY_COMMA+BX_KEY_ALT_R                     none       XK_horizconnector
-BX_KEY_COMMA+BX_KEY_SHIFT_L                   ';'        XK_semicolon
-BX_KEY_CTRL_L                                 none       XK_Control_L
-BX_KEY_CTRL_R                                 none       XK_Control_R
-BX_KEY_DELETE                                 none       XK_Delete
-BX_KEY_DOWN                                   none       XK_Down
-BX_KEY_END                                    none       XK_End
-BX_KEY_ENTER                                  return     XK_Return
-BX_KEY_EQUALS                                 none       XK_acute
-BX_KEY_EQUALS+BX_KEY_ALT_R                    '¸'        XK_cedilla
-BX_KEY_EQUALS+BX_KEY_SHIFT_L                  '`'        XK_grave
-BX_KEY_ESC                                    none       XK_Escape
-BX_KEY_GRAVE                                  '^'        XK_asciicircum
-BX_KEY_GRAVE+BX_KEY_SHIFT_L                   '°'        XK_degree
-BX_KEY_GRAVE+BX_KEY_ALT_R                     '¬'        XK_notsign
-BX_KEY_HOME                                   none       XK_Home
-BX_KEY_INSERT                                 none       XK_Insert
-BX_KEY_KP_5                                   none       XK_KP_5
-BX_KEY_KP_5                                   none       XK_KP_Begin
-BX_KEY_KP_ADD                                 none       XK_KP_Add
-BX_KEY_KP_DELETE                              none       XK_KP_Decimal
-BX_KEY_KP_DELETE                              none       XK_KP_Delete
-BX_KEY_KP_DIVIDE                              none       XK_KP_Divide
-BX_KEY_KP_DOWN                                none       XK_KP_2
-BX_KEY_KP_DOWN                                none       XK_KP_Down
-BX_KEY_KP_END                                 none       XK_KP_1
-BX_KEY_KP_END                                 none       XK_KP_End
-BX_KEY_KP_ENTER                               none       XK_KP_Enter
-BX_KEY_KP_HOME                                none       XK_KP_7
-BX_KEY_KP_HOME                                none       XK_KP_Home
-BX_KEY_KP_INSERT                              none       XK_KP_0
-BX_KEY_KP_INSERT                              none       XK_KP_Insert
-BX_KEY_KP_LEFT                                none       XK_KP_4
-BX_KEY_KP_LEFT                                none       XK_KP_Left
-BX_KEY_KP_MULTIPLY                            none       XK_KP_Multiply
-BX_KEY_KP_PAGE_DOWN                           none       XK_KP_3
-BX_KEY_KP_PAGE_DOWN                           none       XK_KP_Page_Down
-BX_KEY_KP_PAGE_UP                             none       XK_KP_9
-BX_KEY_KP_PAGE_UP                             none       XK_KP_Page_Up
-BX_KEY_KP_RIGHT                               none       XK_KP_6
-BX_KEY_KP_RIGHT                               none       XK_KP_Right
-BX_KEY_KP_SUBTRACT                            none       XK_KP_Subtract
-BX_KEY_KP_UP                                  none       XK_KP_8
-BX_KEY_KP_UP                                  none       XK_KP_Up
-BX_KEY_LEFT                                   none       XK_Left
-BX_KEY_LEFT_BACKSLASH+BX_KEY_ALT_R            '|'        XK_bar
-BX_KEY_LEFT_BACKSLASH+BX_KEY_SHIFT_L          '>'        XK_greater
-BX_KEY_LEFT_BACKSLASH                         '<'        XK_less
-BX_KEY_LEFT_BRACKET+BX_KEY_SHIFT_L            'Ü'        XK_Udiaeresis
-BX_KEY_LEFT_BRACKET+BX_KEY_ALT_L              none       XK_diaeresis
-BX_KEY_LEFT_BRACKET                           'ü'        XK_udiaeresis
-BX_KEY_MENU                                   none       XK_Menu
-BX_KEY_MINUS+BX_KEY_ALT_L                     backslash  XK_backslash
-BX_KEY_MINUS+BX_KEY_SHIFT_L                   '?'        XK_question
-BX_KEY_MINUS                                  'ß'        XK_ssharp
-BX_KEY_NUM_LOCK                               none       XK_Num_Lock
-BX_KEY_PAGE_DOWN                              none       XK_Page_Down
-BX_KEY_PAGE_UP                                none       XK_Page_Up
-BX_KEY_PAUSE                                  none       XK_Break
-BX_KEY_PAUSE                                  none       XK_Pause
-BX_KEY_PERIOD+BX_KEY_SHIFT_L                  ':'        XK_colon
-BX_KEY_PERIOD                                 '.'        XK_period
-BX_KEY_PERIOD+BX_KEY_ALT_L                    '·'        XK_periodcentered
-BX_KEY_PRINT                                  none       XK_Print
-BX_KEY_PRINT                                  none       XK_Sys_Req
-BX_KEY_RIGHT                                  none       XK_Right
-BX_KEY_RIGHT_BRACKET+BX_KEY_ALT_R             '~'        XK_asciitilde
-BX_KEY_RIGHT_BRACKET+BX_KEY_SHIFT_L           '*'        XK_asterisk
-BX_KEY_RIGHT_BRACKET                          '+'        XK_plus
-BX_KEY_SCRL_LOCK                              none       XK_Scroll_Lock
-BX_KEY_SEMICOLON+BX_KEY_SHIFT_L               'Ö'        XK_Odiaeresis
-BX_KEY_SEMICOLON                              'ö'        XK_odiaeresis
-BX_KEY_SHIFT_L                                none       XK_Shift_L
-BX_KEY_SHIFT_R                                none       XK_Shift_R
-BX_KEY_SINGLE_QUOTE+BX_KEY_SHIFT_L            'Ä'        XK_Adiaeresis
-BX_KEY_SINGLE_QUOTE                           'ä'        XK_adiaeresis
-BX_KEY_SLASH                                  none       XK_dead_belowdot
-BX_KEY_SLASH                                  '-'        XK_minus
-BX_KEY_SLASH+BX_KEY_SHIFT_L                   '_'        XK_underscore
-BX_KEY_SPACE                                  space      XK_space
-BX_KEY_TAB                                    none       XK_ISO_Left_Tab
-BX_KEY_TAB                                    tab        XK_Tab
-BX_KEY_UP                                     none       XK_Up
-BX_KEY_WIN_L                                  none       XK_Super_L
-BX_KEY_WIN_R                                  none       XK_Super_R
diff --git a/tools/ioemu/gui/keymaps/x11-pc-es.map b/tools/ioemu/gui/keymaps/x11-pc-es.map
deleted file mode 100644 (file)
index 3856044..0000000
+++ /dev/null
@@ -1,217 +0,0 @@
-# Bochs Keymap file
-# $Id: x11-pc-es.map,v 1.4 2002/09/25 08:00:24 bdenney Exp $
-# Target: PC(x86) keyboard, ES keymap
-# Author: Vicente Hernando Ara 
-#
-# The keymap file describes the layout of a keyboard, and how it translates
-# into Bochs key codes.
-#
-# Format:
-#  BX_Keysym                ASCII_equivalent      Xwin_Keysym
-#
-# Or, for keys that require modifiers:
-#  BX_Keysym+BX_Modifier    ASCII_equivalent    Xwin_Keysym
-#
-# BX_Keysym and BX_Modifier must be present in the bx_key_symbol[] list in
-# gui/keymap.cc.  The BX_Modifier is usually a shift key press, but it
-# could be any key.  Presently a maximum of one modifier is supported, but this
-# could be changed in keymap.h (structure def has only one slot for modifier),
-# keymap.cc (parsing code), and iodev/keyboard.cc (simulate keypresses for >1
-# modifier).
-#
-# The ASCII_equivalent must be either apostrophe + one character + apostrophe,
-# or one of these keywords: space, return, tab, backslash, apostrophe, none.
-# This format is designed to look like a char constant in C, but it's a very
-# simple parser.  There's no concept of backslash being an escape char.  The
-# backslash and apostrophe entries are provided for aesthetic purposes only: no
-# C++ programmer wants to see '\' or '''. The parser doesn't care, but they are
-# ugly.
-#
-# Xwin_Keysym is the X windows equivalent of the key combination.  These
-# codes should match whatever you find in /usr/X11R6/include/X11/keysymdef.h.
-# If you're running X windows, Bochs will take each of these Xwin_Keysyms,
-# pull off the XK_ in front, and use XStringToKeysym() to change them into
-# numerical codes.  If this lookup fails, you will get a panic and you need
-# to edit the keymap file.
-#
-BX_KEY_0                                      none       XK_0
-BX_KEY_0                                      none       XK_equal
-BX_KEY_1                                      none       XK_1
-BX_KEY_1                                      none       XK_bar
-BX_KEY_1                                      none       XK_exclam
-BX_KEY_2                                      none       XK_2
-BX_KEY_2                                      none       XK_at
-BX_KEY_2                                      none       XK_quotedbl
-BX_KEY_3                                      none       XK_3
-BX_KEY_3                                      none       XK_numbersign
-BX_KEY_3                                      none       XK_periodcentered
-BX_KEY_4                                      none       XK_4
-BX_KEY_4                                      none       XK_dollar
-BX_KEY_5                                      none       XK_5
-BX_KEY_5                                      none       XK_percent
-BX_KEY_6                                      none       XK_6
-BX_KEY_6                                      none       XK_ampersand
-BX_KEY_7                                      none       XK_7
-BX_KEY_7                                      none       XK_slash
-BX_KEY_8                                      none       XK_8
-BX_KEY_8                                      none       XK_parenleft
-BX_KEY_9                                      none       XK_9
-BX_KEY_9                                      none       XK_parenright
-BX_KEY_A                                      none       XK_A
-BX_KEY_A                                      none       XK_a
-BX_KEY_B                                      none       XK_B
-BX_KEY_B                                      none       XK_b
-BX_KEY_C                                      none       XK_C
-BX_KEY_C                                      none       XK_c
-BX_KEY_D                                      none       XK_D
-BX_KEY_D                                      none       XK_d
-BX_KEY_E                                      none       XK_E
-BX_KEY_E                                      none       XK_EuroSign
-BX_KEY_E                                      none       XK_e
-BX_KEY_F                                      none       XK_F
-BX_KEY_F                                      none       XK_f
-BX_KEY_G                                      none       XK_G
-BX_KEY_G                                      none       XK_g
-BX_KEY_H                                      none       XK_H
-BX_KEY_H                                      none       XK_h
-BX_KEY_I                                      none       XK_I
-BX_KEY_I                                      none       XK_i
-BX_KEY_J                                      none       XK_J
-BX_KEY_J                                      none       XK_j
-BX_KEY_K                                      none       XK_K
-BX_KEY_K                                      none       XK_k
-BX_KEY_L                                      none       XK_L
-BX_KEY_L                                      none       XK_l
-BX_KEY_M                                      none       XK_M
-BX_KEY_M                                      none       XK_m
-BX_KEY_N                                      none       XK_N
-BX_KEY_N                                      none       XK_n
-BX_KEY_O                                      none       XK_O
-BX_KEY_O                                      none       XK_o
-BX_KEY_P                                      none       XK_P
-BX_KEY_P                                      none       XK_p
-BX_KEY_Q                                      none       XK_Q
-BX_KEY_Q                                      none       XK_q
-BX_KEY_R                                      none       XK_R
-BX_KEY_R                                      none       XK_r
-BX_KEY_S                                      none       XK_S
-BX_KEY_S                                      none       XK_s
-BX_KEY_T                                      none       XK_T
-BX_KEY_T                                      none       XK_t
-BX_KEY_U                                      none       XK_U
-BX_KEY_U                                      none       XK_u
-BX_KEY_V                                      none       XK_V
-BX_KEY_V                                      none       XK_v
-BX_KEY_W                                      none       XK_W
-BX_KEY_W                                      none       XK_w
-BX_KEY_X                                      none       XK_X
-BX_KEY_X                                      none       XK_x
-BX_KEY_Y                                      none       XK_Y
-BX_KEY_Y                                      none       XK_y
-BX_KEY_Z                                      none       XK_Z
-BX_KEY_Z                                      none       XK_z
-BX_KEY_F1                                     none       XK_F1
-BX_KEY_F2                                     none       XK_F2
-BX_KEY_F3                                     none       XK_F3
-BX_KEY_F4                                     none       XK_F4
-BX_KEY_F5                                     none       XK_F5
-BX_KEY_F6                                     none       XK_F6
-BX_KEY_F7                                     none       XK_F7
-BX_KEY_F8                                     none       XK_F8
-BX_KEY_F9                                     none       XK_F9
-BX_KEY_F10                                    none       XK_F10
-BX_KEY_F11                                    none       XK_F11
-BX_KEY_F12                                    none       XK_F12
-BX_KEY_ALT_L                                  none       XK_Alt_L
-BX_KEY_ALT_L                                  none       XK_Meta_L
-BX_KEY_ALT_R                                  none       XK_Alt_R
-BX_KEY_ALT_R                                  none       XK_Mode_switch
-BX_KEY_ALT_R                                  none       XK_Multi_key
-BX_KEY_BACKSLASH                              none       XK_Ccedilla
-BX_KEY_BACKSLASH                              none       XK_ccedilla
-BX_KEY_BACKSPACE                              none       XK_BackSpace
-BX_KEY_CAPS_LOCK                              none       XK_Caps_Lock
-BX_KEY_COMMA                                  none       XK_comma
-BX_KEY_COMMA                                  none       XK_semicolon
-BX_KEY_CTRL_L                                 none       XK_Control_L
-BX_KEY_CTRL_R                                 none       XK_Control_R
-BX_KEY_DELETE                                 none       XK_Delete
-BX_KEY_DOWN                                   none       XK_Down
-BX_KEY_END                                    none       XK_End
-BX_KEY_ENTER                                  none       XK_Return
-BX_KEY_EQUALS                                 none       XK_exclamdown
-BX_KEY_EQUALS                                 none       XK_questiondown
-BX_KEY_ESC                                    none       XK_Escape
-BX_KEY_GRAVE                                  none       XK_asciitilde
-BX_KEY_GRAVE                                  none       XK_backslash
-BX_KEY_GRAVE                                  none       XK_grave
-BX_KEY_GRAVE                                  none       XK_masculine
-BX_KEY_GRAVE                                  none       XK_ordfeminine
-BX_KEY_HOME                                   none       XK_Home
-BX_KEY_INSERT                                 none       XK_Insert
-BX_KEY_KP_5                                   none       XK_KP_5
-BX_KEY_KP_5                                   none       XK_KP_Begin
-BX_KEY_KP_ADD                                 none       XK_KP_Add
-BX_KEY_KP_DELETE                              none       XK_KP_Decimal
-BX_KEY_KP_DELETE                              none       XK_KP_Delete
-BX_KEY_KP_DIVIDE                              none       XK_KP_Divide
-BX_KEY_KP_DOWN                                none       XK_KP_2
-BX_KEY_KP_DOWN                                none       XK_KP_Down
-BX_KEY_KP_END                                 none       XK_KP_1
-BX_KEY_KP_END                                 none       XK_KP_End
-BX_KEY_KP_ENTER                               none       XK_KP_Enter
-BX_KEY_KP_HOME                                none       XK_KP_7
-BX_KEY_KP_HOME                                none       XK_KP_Home
-BX_KEY_KP_INSERT                              none       XK_KP_0
-BX_KEY_KP_INSERT                              none       XK_KP_Insert
-BX_KEY_KP_LEFT                                none       XK_KP_4
-BX_KEY_KP_LEFT                                none       XK_KP_Left
-BX_KEY_KP_MULTIPLY                            none       XK_KP_Multiply
-BX_KEY_KP_PAGE_DOWN                           none       XK_KP_3
-BX_KEY_KP_PAGE_DOWN                           none       XK_KP_Page_Down
-BX_KEY_KP_PAGE_UP                             none       XK_KP_9
-BX_KEY_KP_PAGE_UP                             none       XK_KP_Page_Up
-BX_KEY_KP_RIGHT                               none       XK_KP_6
-BX_KEY_KP_RIGHT                               none       XK_KP_Right
-BX_KEY_KP_SUBTRACT                            none       XK_KP_Subtract
-BX_KEY_KP_UP                                  none       XK_KP_8
-BX_KEY_KP_UP                                  none       XK_KP_Up
-BX_KEY_LEFT                                   none       XK_Left
-BX_KEY_LEFT_BACKSLASH                         none       XK_greater
-BX_KEY_LEFT_BACKSLASH                         none       XK_less
-BX_KEY_LEFT_BRACKET                           none       XK_braceleft
-BX_KEY_LEFT_BRACKET                           none       XK_bracketleft
-BX_KEY_LEFT_BRACKET                           none       XK_dead_circumflex
-BX_KEY_LEFT_BRACKET                           none       XK_dead_grave
-BX_KEY_MENU                                   none       XK_Menu
-BX_KEY_MINUS                                  none       XK_apostrophe
-BX_KEY_MINUS                                  none       XK_question
-BX_KEY_NUM_LOCK                               none       XK_Num_Lock
-BX_KEY_PAGE_DOWN                              none       XK_Page_Down
-BX_KEY_PAGE_UP                                none       XK_Page_Up
-BX_KEY_PAUSE                                  none       XK_Break
-BX_KEY_PAUSE                                  none       XK_Pause
-BX_KEY_PERIOD                                 none       XK_colon
-BX_KEY_PERIOD                                 none       XK_period
-BX_KEY_PRINT                                  none       XK_Print
-BX_KEY_PRINT                                  none       XK_Sys_Req
-BX_KEY_RIGHT                                  none       XK_Right
-BX_KEY_RIGHT_BRACKET                          none       XK_asterisk
-BX_KEY_RIGHT_BRACKET                          none       XK_braceright
-BX_KEY_RIGHT_BRACKET                          none       XK_bracketright
-BX_KEY_RIGHT_BRACKET                          none       XK_plus
-BX_KEY_SCRL_LOCK                              none       XK_Scroll_Lock
-BX_KEY_SEMICOLON                              none       XK_Ntilde
-BX_KEY_SEMICOLON                              none       XK_ntilde
-BX_KEY_SHIFT_L                                none       XK_Shift_L
-BX_KEY_SHIFT_R                                none       XK_Shift_R
-BX_KEY_SINGLE_QUOTE                           none       XK_dead_acute
-BX_KEY_SINGLE_QUOTE                           none       XK_dead_diaeresis
-BX_KEY_SLASH                                  none       XK_minus
-BX_KEY_SLASH                                  none       XK_underscore
-BX_KEY_SPACE                                  none       XK_space
-BX_KEY_TAB                                    none       XK_ISO_Left_Tab
-BX_KEY_TAB                                    none       XK_Tab
-BX_KEY_UP                                     none       XK_Up
-BX_KEY_WIN_L                                  none       XK_Super_L
-BX_KEY_WIN_R                                  none       XK_Super_R
diff --git a/tools/ioemu/gui/keymaps/x11-pc-fr.map b/tools/ioemu/gui/keymaps/x11-pc-fr.map
deleted file mode 100644 (file)
index 869b328..0000000
+++ /dev/null
@@ -1,218 +0,0 @@
-# Bochs Keymap file
-# $Id: x11-pc-fr.map,v 1.5 2002/09/25 08:00:24 bdenney Exp $
-# Target: PC(x86) keyboard, FR keymap
-# Author: Christophe Bothamy, Bryce Denney
-#
-# The keymap file describes the layout of a keyboard, and how it translates
-# into Bochs key codes.
-#
-# Format:
-#  BX_Keysym                ASCII_equivalent      Xwin_Keysym
-#
-# Or, for keys that require modifiers:
-#  BX_Keysym+BX_Modifier    ASCII_equivalent    Xwin_Keysym
-#
-# BX_Keysym and BX_Modifier must be present in the bx_key_symbol[] list in
-# gui/keymap.cc.  The BX_Modifier is usually a shift key press, but it
-# could be any key.  Presently a maximum of one modifier is supported, but this
-# could be changed in keymap.h (structure def has only one slot for modifier),
-# keymap.cc (parsing code), and iodev/keyboard.cc (simulate keypresses for >1
-# modifier).
-#
-# The ASCII_equivalent must be either apostrophe + one character + apostrophe,
-# or one of these keywords: space, return, tab, backslash, apostrophe, none.
-# This format is designed to look like a char constant in C, but it's a very
-# simple parser.  There's no concept of backslash being an escape char.  The
-# backslash and apostrophe entries are provided for aesthetic purposes only: no
-# C++ programmer wants to see '\' or '''. The parser doesn't care, but they are
-# ugly.
-#
-# Xwin_Keysym is the X windows equivalent of the key combination.  These
-# codes should match whatever you find in /usr/X11R6/include/X11/keysymdef.h.
-# If you're running X windows, Bochs will take each of these Xwin_Keysyms,
-# pull off the XK_ in front, and use XStringToKeysym() to change them into
-# numerical codes.  If this lookup fails, you will get a panic and you need
-# to edit the keymap file.
-
-BX_KEY_0+BX_KEY_SHIFT_L                       '0'        XK_0
-BX_KEY_0                                      'à'        XK_agrave
-BX_KEY_0+BX_KEY_ALT_R                         '@'        XK_at
-BX_KEY_1+BX_KEY_SHIFT_L                       '1'        XK_1
-BX_KEY_1                                      '&'        XK_ampersand
-BX_KEY_2+BX_KEY_SHIFT_L                       '2'        XK_2
-BX_KEY_2+BX_KEY_ALT_R                         '~'        XK_asciitilde
-BX_KEY_2                                      'é'        XK_eacute
-BX_KEY_3+BX_KEY_SHIFT_L                       '3'        XK_3
-BX_KEY_3+BX_KEY_ALT_R                         '#'        XK_numbersign
-BX_KEY_3                                      '"'        XK_quotedbl
-BX_KEY_4+BX_KEY_SHIFT_L                       '4'        XK_4
-BX_KEY_4                                      apostrophe XK_apostrophe
-BX_KEY_4+BX_KEY_ALT_R                         '{'        XK_braceleft
-BX_KEY_5+BX_KEY_SHIFT_L                       '5'        XK_5
-BX_KEY_5+BX_KEY_ALT_R                         '['        XK_bracketleft
-BX_KEY_5                                      '('        XK_parenleft
-BX_KEY_6+BX_KEY_SHIFT_L                       '6'        XK_6
-BX_KEY_6+BX_KEY_ALT_R                         '|'        XK_bar
-BX_KEY_6                                      '-'        XK_minus
-BX_KEY_7+BX_KEY_SHIFT_L                       '7'        XK_7
-BX_KEY_7                                      'è'        XK_egrave
-BX_KEY_7+BX_KEY_ALT_R                         '`'        XK_grave
-BX_KEY_8+BX_KEY_SHIFT_L                       '8'        XK_8
-BX_KEY_8+BX_KEY_ALT_R                         backslash  XK_backslash
-BX_KEY_8                                      '_'        XK_underscore
-BX_KEY_9+BX_KEY_SHIFT_L                       '9'        XK_9
-BX_KEY_9+BX_KEY_ALT_R                         '^'        XK_asciicircum
-BX_KEY_9                                      'ç'       XK_ccedilla
-BX_KEY_A+BX_KEY_SHIFT_L                       'Q'        XK_Q
-BX_KEY_A                                      'q'        XK_q
-BX_KEY_B+BX_KEY_SHIFT_L                       'B'        XK_B
-BX_KEY_B                                      'b'        XK_b
-BX_KEY_C+BX_KEY_SHIFT_L                       'C'        XK_C
-BX_KEY_C                                      'c'        XK_c
-BX_KEY_D+BX_KEY_SHIFT_L                       'D'        XK_D
-BX_KEY_D                                      'd'        XK_d
-BX_KEY_E+BX_KEY_SHIFT_L                       'E'        XK_E
-BX_KEY_E                                      'e'        XK_e
-BX_KEY_E+BX_KEY_ALT_R                         none       XK_EuroSign
-BX_KEY_F+BX_KEY_SHIFT_L                       'F'        XK_F
-BX_KEY_F                                      'f'        XK_f
-BX_KEY_G+BX_KEY_SHIFT_L                       'G'        XK_G
-BX_KEY_G                                      'g'        XK_g
-BX_KEY_H+BX_KEY_SHIFT_L                       'H'        XK_H
-BX_KEY_H                                      'h'        XK_h
-BX_KEY_I+BX_KEY_SHIFT_L                       'I'        XK_I
-BX_KEY_I                                      'i'        XK_i
-BX_KEY_J+BX_KEY_SHIFT_L                       'J'        XK_J
-BX_KEY_J                                      'j'        XK_j
-BX_KEY_K+BX_KEY_SHIFT_L                       'K'        XK_K
-BX_KEY_K                                      'k'        XK_k
-BX_KEY_L+BX_KEY_SHIFT_L                       'L'        XK_L
-BX_KEY_L                                      'l'        XK_l
-BX_KEY_M+BX_KEY_SHIFT_L                       '?'        XK_question
-BX_KEY_M                                      ','        XK_comma
-BX_KEY_N+BX_KEY_SHIFT_L                       'N'        XK_N
-BX_KEY_N                                      'n'        XK_n
-BX_KEY_O+BX_KEY_SHIFT_L                       'O'        XK_O
-BX_KEY_O                                      'o'        XK_o
-BX_KEY_P+BX_KEY_SHIFT_L                       'P'        XK_P
-BX_KEY_P                                      'p'        XK_p
-BX_KEY_Q+BX_KEY_SHIFT_L                       'A'        XK_A
-BX_KEY_Q                                      'a'        XK_a
-BX_KEY_R+BX_KEY_SHIFT_L                       'R'        XK_R
-BX_KEY_R                                      'r'        XK_r
-BX_KEY_S+BX_KEY_SHIFT_L                       'S'        XK_S
-BX_KEY_S                                      's'        XK_s
-BX_KEY_T+BX_KEY_SHIFT_L                       'T'        XK_T
-BX_KEY_T                                      't'        XK_t
-BX_KEY_U+BX_KEY_SHIFT_L                       'U'        XK_U
-BX_KEY_U                                      'u'        XK_u
-BX_KEY_V+BX_KEY_SHIFT_L                       'V'        XK_V
-BX_KEY_V                                      'v'        XK_v
-BX_KEY_W+BX_KEY_SHIFT_L                       'Z'        XK_Z
-BX_KEY_W                                      'z'        XK_z
-BX_KEY_X+BX_KEY_SHIFT_L                       'X'        XK_X
-BX_KEY_X                                      'x'        XK_x
-BX_KEY_Y+BX_KEY_SHIFT_L                       'Y'        XK_Y
-BX_KEY_Y                                      'y'        XK_y
-BX_KEY_Z+BX_KEY_SHIFT_L                       'W'        XK_W
-BX_KEY_Z                                      'w'        XK_w
-BX_KEY_F1                                     none       XK_F1
-BX_KEY_F2                                     none       XK_F2
-BX_KEY_F3                                     none       XK_F3
-BX_KEY_F4                                     none       XK_F4
-BX_KEY_F5                                     none       XK_F5
-BX_KEY_F6                                     none       XK_F6
-BX_KEY_F7                                     none       XK_F7
-BX_KEY_F8                                     none       XK_F8
-BX_KEY_F9                                     none       XK_F9
-BX_KEY_F10                                    none       XK_F10
-BX_KEY_F11                                    none       XK_F11
-BX_KEY_F12                                    none       XK_F12
-BX_KEY_ALT_L                                  none       XK_Alt_L
-BX_KEY_ALT_L                                  none       XK_Meta_L
-BX_KEY_ALT_R                                  none       XK_Alt_R
-BX_KEY_ALT_R                                  none       XK_Mode_switch
-BX_KEY_ALT_R                                  none       XK_Multi_key
-BX_KEY_BACKSLASH                              '*'        XK_asterisk
-BX_KEY_BACKSLASH+BX_KEY_SHIFT_L               'µ'        XK_mu
-BX_KEY_BACKSPACE                              none       XK_BackSpace
-BX_KEY_CAPS_LOCK                              none       XK_Caps_Lock
-BX_KEY_COMMA+BX_KEY_SHIFT_L                   '.'        XK_period
-BX_KEY_COMMA                                  ';'        XK_semicolon
-BX_KEY_CTRL_L                                 none       XK_Control_L
-BX_KEY_CTRL_R                                 none       XK_Control_R
-BX_KEY_DELETE                                 none       XK_Delete
-BX_KEY_DOWN                                   none       XK_Down
-BX_KEY_END                                    none       XK_End
-BX_KEY_ENTER                                  return     XK_Return
-BX_KEY_EQUALS+BX_KEY_ALT_R                    '}'        XK_braceright
-BX_KEY_EQUALS                                 '='        XK_equal
-BX_KEY_EQUALS+BX_KEY_SHIFT_L                  '+'        XK_plus
-BX_KEY_ESC                                    none       XK_Escape
-BX_KEY_GRAVE                                  '²'        XK_twosuperior
-BX_KEY_HOME                                   none       XK_Home
-BX_KEY_INSERT                                 none       XK_Insert
-BX_KEY_KP_5                                   none       XK_KP_5
-BX_KEY_KP_5                                   none       XK_KP_Begin
-BX_KEY_KP_ADD                                 none       XK_KP_Add
-BX_KEY_KP_DELETE                              none       XK_KP_Decimal
-BX_KEY_KP_DELETE                              none       XK_KP_Delete
-BX_KEY_KP_DIVIDE                              none       XK_KP_Divide
-BX_KEY_KP_DOWN                                none       XK_KP_2
-BX_KEY_KP_DOWN                                none       XK_KP_Down
-BX_KEY_KP_END                                 none       XK_KP_1
-BX_KEY_KP_END                                 none       XK_KP_End
-BX_KEY_KP_ENTER                               none       XK_KP_Enter
-BX_KEY_KP_HOME                                none       XK_KP_7
-BX_KEY_KP_HOME                                none       XK_KP_Home
-BX_KEY_KP_INSERT                              none       XK_KP_0
-BX_KEY_KP_INSERT                              none       XK_KP_Insert
-BX_KEY_KP_LEFT                                none       XK_KP_4
-BX_KEY_KP_LEFT                                none       XK_KP_Left
-BX_KEY_KP_MULTIPLY                            none       XK_KP_Multiply
-BX_KEY_KP_PAGE_DOWN                           none       XK_KP_3
-BX_KEY_KP_PAGE_DOWN                           none       XK_KP_Page_Down
-BX_KEY_KP_PAGE_UP                             none       XK_KP_9
-BX_KEY_KP_PAGE_UP                             none       XK_KP_Page_Up
-BX_KEY_KP_RIGHT                               none       XK_KP_6
-BX_KEY_KP_RIGHT                               none       XK_KP_Right
-BX_KEY_KP_SUBTRACT                            none       XK_KP_Subtract
-BX_KEY_KP_UP                                  none       XK_KP_8
-BX_KEY_KP_UP                                  none       XK_KP_Up
-BX_KEY_LEFT                                   none       XK_Left
-BX_KEY_LEFT_BACKSLASH+BX_KEY_SHIFT_L          '>'        XK_greater
-BX_KEY_LEFT_BACKSLASH                         '<'        XK_less
-BX_KEY_LEFT_BRACKET                           '^'        XK_dead_circumflex
-BX_KEY_LEFT_BRACKET                           none       XK_dead_diaeresis
-BX_KEY_MENU                                   none       XK_Menu
-BX_KEY_MINUS+BX_KEY_ALT_R                     ']'        XK_bracketright
-BX_KEY_MINUS+BX_KEY_SHIFT_L                   '°'        XK_degree
-BX_KEY_MINUS                                  ')'        XK_parenright
-BX_KEY_NUM_LOCK                               none       XK_Num_Lock
-BX_KEY_PAGE_DOWN                              none       XK_Page_Down
-BX_KEY_PAGE_UP                                none       XK_Page_Up
-BX_KEY_PAUSE                                  none       XK_Break
-BX_KEY_PAUSE                                  none       XK_Pause
-BX_KEY_PERIOD                                 ':'        XK_colon
-BX_KEY_PERIOD+BX_KEY_SHIFT_L                  '/'        XK_slash
-BX_KEY_PRINT                                  none       XK_Print
-BX_KEY_PRINT                                  none       XK_Sys_Req
-BX_KEY_RIGHT                                  none       XK_Right
-BX_KEY_RIGHT_BRACKET+BX_KEY_ALT_R             '¤'        XK_currency
-BX_KEY_RIGHT_BRACKET                          '$'        XK_dollar
-BX_KEY_RIGHT_BRACKET+BX_KEY_SHIFT_L           '£'        XK_sterling
-BX_KEY_SCRL_LOCK                              none       XK_Scroll_Lock
-BX_KEY_SEMICOLON+BX_KEY_SHIFT_L               'M'        XK_M
-BX_KEY_SEMICOLON                              'm'        XK_m
-BX_KEY_SHIFT_L                                none       XK_Shift_L
-BX_KEY_SHIFT_R                                none       XK_Shift_R
-BX_KEY_SINGLE_QUOTE+BX_KEY_SHIFT_L            '%'        XK_percent
-BX_KEY_SINGLE_QUOTE                           'ù'        XK_ugrave
-BX_KEY_SLASH                                  '!'        XK_exclam
-BX_KEY_SLASH+BX_KEY_SHIFT_L                   '§'        XK_section
-BX_KEY_SPACE                                  space      XK_space
-BX_KEY_TAB                                    none       XK_ISO_Left_Tab
-BX_KEY_TAB                                    tab        XK_Tab
-BX_KEY_UP                                     none       XK_Up
-BX_KEY_WIN_L                                  none       XK_Super_L
-BX_KEY_WIN_R                                  none       XK_Super_R
diff --git a/tools/ioemu/gui/keymaps/x11-pc-it.map b/tools/ioemu/gui/keymaps/x11-pc-it.map
deleted file mode 100644 (file)
index fac365e..0000000
+++ /dev/null
@@ -1,207 +0,0 @@
-# Bochs Keymap file
-# $Id: x11-pc-it.map,v 1.2 2002/09/25 08:00:25 bdenney Exp $
-# Target: PC(x86) keyboard, IT keymap
-# Author: Emanuele Goldoni
-#
-# The keymap file describes the layout of a keyboard, and how it translates
-# into Bochs key codes.
-#
-# Format:
-#  BX_Keysym                ASCII_equivalent      Xwin_Keysym
-#
-# Or, for keys that require modifiers:
-#  BX_Keysym+BX_Modifier    ASCII_equivalent    Xwin_Keysym
-#
-# BX_Keysym and BX_Modifier must be present in the bx_key_symbol[] list in
-# gui/keymap.cc.  The BX_Modifier is usually a shift key press, but it
-# could be any key.  Presently a maximum of one modifier is supported, but this
-# could be changed in keymap.h (structure def has only one slot for modifier),
-# keymap.cc (parsing code), and iodev/keyboard.cc (simulate keypresses for >1
-# modifier).
-#
-# The ASCII_equivalent must be either apostrophe + one character + apostrophe,
-# or one of these keywords: space, return, tab, backslash, apostrophe, none.
-# This format is designed to look like a char constant in C, but it's a very
-# simple parser.  There's no concept of backslash being an escape char.  The
-# backslash and apostrophe entries are provided for aesthetic purposes only: no
-# C++ programmer wants to see '\' or '''. The parser doesn't care, but they are
-# ugly.
-#
-# Xwin_Keysym is the X windows equivalent of the key combination.  These
-# codes should match whatever you find in /usr/X11R6/include/X11/keysymdef.h.
-# If you're running X windows, Bochs will take each of these Xwin_Keysyms,
-# pull off the XK_ in front, and use XStringToKeysym() to change them into
-# numerical codes.  If this lookup fails, you will get a panic and you need
-# to edit the keymap file.
-#
-
-BX_KEY_0                                      '0'        XK_0
-BX_KEY_0+BX_KEY_SHIFT_L                       '='        XK_equal
-BX_KEY_1                                      '1'        XK_1
-BX_KEY_1+BX_KEY_SHIFT_L                       '!'        XK_exclam
-BX_KEY_2                                      '2'        XK_2
-BX_KEY_2+BX_KEY_SHIFT_L                       '"'        XK_quotedbl
-BX_KEY_3                                      '3'        XK_3
-BX_KEY_3+BX_KEY_SHIFT_L                       '£'        XK_sterling
-BX_KEY_4                                      '4'        XK_4
-BX_KEY_4+BX_KEY_SHIFT_L                       '$'        XK_dollar
-BX_KEY_5                                      '5'        XK_5
-BX_KEY_5+BX_KEY_SHIFT_L                       '%'        XK_percent
-BX_KEY_6                                      '6'        XK_6
-BX_KEY_6+BX_KEY_SHIFT_L                       '&'        XK_ampersand
-BX_KEY_7                                      '7'        XK_7
-BX_KEY_7+BX_KEY_SHIFT_L                       '/'        XK_slash
-BX_KEY_8                                      '8'        XK_8
-BX_KEY_8+BX_KEY_SHIFT_L                       '('        XK_parenleft
-BX_KEY_9                                      '9'        XK_9
-BX_KEY_9+BX_KEY_SHIFT_L                       ')'        XK_parenright
-BX_KEY_A+BX_KEY_SHIFT_L                       'A'        XK_A
-BX_KEY_A                                      'a'        XK_a
-BX_KEY_B+BX_KEY_SHIFT_L                       'B'        XK_B
-BX_KEY_B                                      'b'        XK_b
-BX_KEY_C+BX_KEY_SHIFT_L                       'C'        XK_C
-BX_KEY_C                                      'c'        XK_c
-BX_KEY_D+BX_KEY_SHIFT_L                       'D'        XK_D
-BX_KEY_D                                      'd'        XK_d
-BX_KEY_E+BX_KEY_SHIFT_L                       'E'        XK_E
-BX_KEY_E                                      'e'        XK_e
-BX_KEY_F+BX_KEY_SHIFT_L                       'F'        XK_F
-BX_KEY_F                                      'f'        XK_f
-BX_KEY_G+BX_KEY_SHIFT_L                       'G'        XK_G
-BX_KEY_G                                      'g'        XK_g
-BX_KEY_H+BX_KEY_SHIFT_L                       'H'        XK_H
-BX_KEY_H                                      'h'        XK_h
-BX_KEY_I+BX_KEY_SHIFT_L                       'I'        XK_I
-BX_KEY_I                                      'i'        XK_i
-BX_KEY_J+BX_KEY_SHIFT_L                       'J'        XK_J
-BX_KEY_J                                      'j'        XK_j
-BX_KEY_K+BX_KEY_SHIFT_L                       'K'        XK_K
-BX_KEY_K                                      'k'        XK_k
-BX_KEY_L+BX_KEY_SHIFT_L                       'L'        XK_L
-BX_KEY_L                                      'l'        XK_l
-BX_KEY_M+BX_KEY_SHIFT_L                       'M'        XK_M
-BX_KEY_M                                      'm'        XK_m
-BX_KEY_N+BX_KEY_SHIFT_L                       'N'        XK_N
-BX_KEY_N                                      'n'        XK_n
-BX_KEY_O+BX_KEY_SHIFT_L                       'O'        XK_O
-BX_KEY_O                                      'o'        XK_o
-BX_KEY_P+BX_KEY_SHIFT_L                       'P'        XK_P
-BX_KEY_P                                      'p'        XK_p
-BX_KEY_Q+BX_KEY_SHIFT_L                       'Q'        XK_Q
-BX_KEY_Q                                      'q'        XK_q
-BX_KEY_R+BX_KEY_SHIFT_L                       'R'        XK_R
-BX_KEY_R                                      'r'        XK_r
-BX_KEY_S+BX_KEY_SHIFT_L                       'S'        XK_S
-BX_KEY_S                                      's'        XK_s
-BX_KEY_T+BX_KEY_SHIFT_L                       'T'        XK_T
-BX_KEY_T                                      't'        XK_t
-BX_KEY_U+BX_KEY_SHIFT_L                       'U'        XK_U
-BX_KEY_U                                      'u'        XK_u
-BX_KEY_V+BX_KEY_SHIFT_L                       'V'        XK_V
-BX_KEY_V                                      'v'        XK_v
-BX_KEY_W+BX_KEY_SHIFT_L                       'W'        XK_W
-BX_KEY_W                                      'w'        XK_w
-BX_KEY_X+BX_KEY_SHIFT_L                       'X'        XK_X
-BX_KEY_X                                      'x'        XK_x
-BX_KEY_Y+BX_KEY_SHIFT_L                       'Y'        XK_Y
-BX_KEY_Y                                      'y'        XK_y
-BX_KEY_Z+BX_KEY_SHIFT_L                       'Z'        XK_Z
-BX_KEY_Z                                      'z'        XK_z
-BX_KEY_F1                                     none       XK_F1
-BX_KEY_F2                                     none       XK_F2
-BX_KEY_F3                                     none       XK_F3
-BX_KEY_F4                                     none       XK_F4
-BX_KEY_F5                                     none       XK_F5
-BX_KEY_F6                                     none       XK_F6
-BX_KEY_F7                                     none       XK_F7
-BX_KEY_F8                                     none       XK_F8
-BX_KEY_F9                                     none       XK_F9
-BX_KEY_F10                                    none       XK_F10
-BX_KEY_F11                                    none       XK_F11
-BX_KEY_F12                                    none       XK_F12
-BX_KEY_ALT_L                                  none       XK_Alt_L
-BX_KEY_ALT_L                                  none       XK_Meta_L
-BX_KEY_ALT_R                                  none       XK_Alt_R
-BX_KEY_ALT_R                                  none       XK_Mode_switch
-BX_KEY_ALT_R                                  none       XK_Multi_key
-BX_KEY_BACKSLASH                              'ù'       XK_ugrave
-BX_KEY_BACKSLASH+BX_KEY_SHIFT_L               '§'        XK_section
-BX_KEY_LEFT_BACKSLASH+BX_KEY_SHIFT_L          '>'        XK_greater
-BX_KEY_LEFT_BACKSLASH                         '<'        XK_less
-BX_KEY_BACKSPACE                              none       XK_BackSpace
-BX_KEY_CAPS_LOCK                              none       XK_Caps_Lock
-BX_KEY_COMMA                                  ','        XK_comma
-BX_KEY_COMMA+BX_KEY_SHIFT_L                   ';'        XK_semicolon
-BX_KEY_CTRL_L                                 none       XK_Control_L
-BX_KEY_CTRL_R                                 none       XK_Control_R
-BX_KEY_DELETE                                 none       XK_Delete
-BX_KEY_DOWN                                   none       XK_Down
-BX_KEY_END                                    none       XK_End
-BX_KEY_ENTER                                  return     XK_Return
-BX_KEY_EQUALS                                 'ì'       XK_igrave
-BX_KEY_EQUALS+BX_KEY_SHIFT_L                  '^'        XK_asciicircum
-BX_KEY_ESC                                    none       XK_Escape
-BX_KEY_GRAVE+BX_KEY_SHIFT_L                   '|'        XK_bar
-BX_KEY_GRAVE                                  backslash  XK_backslash
-BX_KEY_HOME                                   none       XK_Home
-BX_KEY_INSERT                                 none       XK_Insert
-BX_KEY_KP_5                                   none       XK_KP_5
-BX_KEY_KP_5                                   none       XK_KP_Begin
-BX_KEY_KP_ADD                                 none       XK_KP_Add
-BX_KEY_KP_DELETE                              none       XK_KP_Decimal
-BX_KEY_KP_DELETE                              none       XK_KP_Delete
-BX_KEY_KP_DIVIDE                              none       XK_KP_Divide
-BX_KEY_KP_DOWN                                none       XK_KP_2
-BX_KEY_KP_DOWN                                none       XK_KP_Down
-BX_KEY_KP_END                                 none       XK_KP_1
-BX_KEY_KP_END                                 none       XK_KP_End
-BX_KEY_KP_ENTER                               none       XK_KP_Enter
-BX_KEY_KP_HOME                                none       XK_KP_7
-BX_KEY_KP_HOME                                none       XK_KP_Home
-BX_KEY_KP_INSERT                              none       XK_KP_0
-BX_KEY_KP_INSERT                              none       XK_KP_Insert
-BX_KEY_KP_LEFT                                none       XK_KP_4
-BX_KEY_KP_LEFT                                none       XK_KP_Left
-BX_KEY_KP_MULTIPLY                            none       XK_KP_Multiply
-BX_KEY_KP_PAGE_DOWN                           none       XK_KP_3
-BX_KEY_KP_PAGE_DOWN                           none       XK_KP_Page_Down
-BX_KEY_KP_PAGE_UP                             none       XK_KP_9
-BX_KEY_KP_PAGE_UP                             none       XK_KP_Page_Up
-BX_KEY_KP_RIGHT                               none       XK_KP_6
-BX_KEY_KP_RIGHT                               none       XK_KP_Right
-BX_KEY_KP_SUBTRACT                            none       XK_KP_Subtract
-BX_KEY_KP_UP                                  none       XK_KP_8
-BX_KEY_KP_UP                                  none       XK_KP_Up
-BX_KEY_LEFT                                   none       XK_Left
-BX_KEY_LEFT_BRACKET+BX_KEY_SHIFT_L            'é'        XK_eacute
-BX_KEY_LEFT_BRACKET                           'è'        XK_egrave
-BX_KEY_MENU                                   none       XK_Menu
-BX_KEY_MINUS                                  apostrophe XK_apostrophe
-BX_KEY_MINUS+BX_KEY_SHIFT_L                   '?'        XK_question
-BX_KEY_NUM_LOCK                               none       XK_Num_Lock
-BX_KEY_PAGE_DOWN                              none       XK_Page_Down
-BX_KEY_PAGE_UP                                none       XK_Page_Up
-BX_KEY_PAUSE                                  none       XK_Break
-BX_KEY_PAUSE                                  none       XK_Pause
-BX_KEY_PERIOD+BX_KEY_SHIFT_L                  ':'        XK_colon
-BX_KEY_PERIOD                                 '.'        XK_period
-BX_KEY_PRINT                                  none       XK_Print
-BX_KEY_PRINT                                  none       XK_Sys_Req
-BX_KEY_RIGHT                                  none       XK_Right
-BX_KEY_RIGHT_BRACKET+BX_KEY_SHIFT_L           '*'        XK_asterisk
-BX_KEY_RIGHT_BRACKET                          '+'        XK_plus
-BX_KEY_SCRL_LOCK                              none       XK_Scroll_Lock
-BX_KEY_SEMICOLON+BX_KEY_SHIFT_L               'ç'        XK_ccedilla
-BX_KEY_SEMICOLON                              'ò'        XK_ograve
-BX_KEY_SHIFT_L                                none       XK_Shift_L
-BX_KEY_SHIFT_R                                none       XK_Shift_R
-BX_KEY_SINGLE_QUOTE                           'à'         XK_agrave 
-BX_KEY_SINGLE_QUOTE+BX_KEY_SHIFT_L            '°'        XK_degree 
-BX_KEY_SLASH+BX_KEY_SHIFT_L                   '_'        XK_underscore
-BX_KEY_SLASH                                  '-'        XK_minus
-BX_KEY_SPACE                                  space      XK_space
-BX_KEY_TAB                                    none       XK_ISO_Left_Tab
-BX_KEY_TAB                                    tab        XK_Tab
-BX_KEY_UP                                     none       XK_Up
-BX_KEY_WIN_L                                  none       XK_Super_L
-BX_KEY_WIN_R                                  none       XK_Super_R
diff --git a/tools/ioemu/gui/keymaps/x11-pc-se.map b/tools/ioemu/gui/keymaps/x11-pc-se.map
deleted file mode 100644 (file)
index c564ca8..0000000
+++ /dev/null
@@ -1,278 +0,0 @@
-# Bochs Keymap file
-# $Id: x11-pc-se.map,v 1.2 2002/09/25 08:00:25 bdenney Exp $
-# Target: PC(x86) keyboard, SE keymap
-# Author: Magnus 'Moggen' Öberg
-#
-# The keymap file describes the layout of a keyboard, and how it translates
-# into Bochs key codes.
-#
-# Format:
-#  BX_Keysym                ASCII_equivalent      Xwin_Keysym
-#
-# Or, for keys that require modifiers:
-#  BX_Keysym+BX_Modifier    ASCII_equivalent    Xwin_Keysym
-#
-# BX_Keysym and BX_Modifier must be present in the bx_key_symbol[] list in
-# gui/keymap.cc.  The BX_Modifier is usually a shift key press, but it
-# could be any key.  Presently a maximum of one modifier is supported, but this
-# could be changed in keymap.h (structure def has only one slot for modifier),
-# keymap.cc (parsing code), and iodev/keyboard.cc (simulate keypresses for >1
-# modifier).
-#
-# The ASCII_equivalent must be either apostrophe + one character + apostrophe,
-# or one of these keywords: space, return, tab, backslash, apostrophe, none.
-# This format is designed to look like a char constant in C, but it's a very
-# simple parser.  There's no concept of backslash being an escape char.  The
-# backslash and apostrophe entries are provided for aesthetic purposes only: no
-# C++ programmer wants to see '\' or '''. The parser doesn't care, but they are
-# ugly.
-#
-# Xwin_Keysym is the X windows equivalent of the key combination.  These
-# codes should match whatever you find in /usr/X11R6/include/X11/keysymdef.h.
-# If you're running X windows, Bochs will take each of these Xwin_Keysyms,
-# pull off the XK_ in front, and use XStringToKeysym() to change them into
-# numerical codes.  If this lookup fails, you will get a panic and you need
-# to edit the keymap file.
-#
-
-# Upper key groups
-BX_KEY_ESC                                    none       XK_Escape
-
-BX_KEY_F1                                     none       XK_F1
-BX_KEY_F2                                     none       XK_F2
-BX_KEY_F3                                     none       XK_F3
-BX_KEY_F4                                     none       XK_F4
-
-BX_KEY_F5                                     none       XK_F5
-BX_KEY_F6                                     none       XK_F6
-BX_KEY_F7                                     none       XK_F7
-BX_KEY_F8                                     none       XK_F8
-
-BX_KEY_F9                                     none       XK_F9
-BX_KEY_F10                                    none       XK_F10
-BX_KEY_F11                                    none       XK_F11
-BX_KEY_F12                                    none       XK_F12
-
-BX_KEY_PRINT                                  none       XK_Print
-BX_KEY_PRINT                                  none       XK_Sys_Req
-BX_KEY_SCRL_LOCK                              none       XK_Scroll_Lock
-BX_KEY_PAUSE                                  none       XK_Break
-BX_KEY_PAUSE                                  none       XK_Pause
-
-# Main key group
-#  Row 1
-BX_KEY_GRAVE                                  '§'        XK_section
-BX_KEY_GRAVE+BX_KEY_SHIFT_L                   '½'        XK_onehalf
-BX_KEY_GRAVE+BX_KEY_ALT_R                     '¶'        XK_paragraph
-BX_KEY_GRAVE+BX_KEY_SHIFT_L+BX_KEY_ALT_R      '¾'        XK_threequarters
-BX_KEY_1                                      '1'        XK_1
-BX_KEY_1+BX_KEY_SHIFT_L                       '!'        XK_exclam
-BX_KEY_1+BX_KEY_ALT_R                         '¡'        XK_exclamdown
-BX_KEY_1+BX_KEY_SHIFT_L+BX_KEY_ALT_R          '¹'        XK_onesuperior
-BX_KEY_2                                      '2'        XK_2
-BX_KEY_2+BX_KEY_SHIFT_L                       '"'        XK_quotedbl
-BX_KEY_2+BX_KEY_ALT_R                         '@'        XK_at
-BX_KEY_2+BX_KEY_SHIFT_L+BX_KEY_ALT_R          '²'        XK_twosuperior
-BX_KEY_3                                      '3'        XK_3
-BX_KEY_3+BX_KEY_SHIFT_L                       '#'        XK_numbersign
-BX_KEY_3+BX_KEY_ALT_R                         '£'        XK_sterling
-BX_KEY_3+BX_KEY_SHIFT_L+BX_KEY_ALT_R          '³'        XK_threesuperior
-BX_KEY_4                                      '4'        XK_4
-BX_KEY_4+BX_KEY_SHIFT_L                       '¤'        XK_currency
-BX_KEY_4+BX_KEY_ALT_R                         '$'        XK_dollar
-BX_KEY_4+BX_KEY_SHIFT_L+BX_KEY_ALT_R          '¼'        XK_onequarter
-BX_KEY_5                                      '5'        XK_5
-BX_KEY_5+BX_KEY_SHIFT_L                       '%'        XK_percent
-BX_KEY_5+BX_KEY_SHIFT_L+BX_KEY_ALT_R          '¢'        XK_cent
-BX_KEY_6                                      '6'        XK_6
-BX_KEY_6+BX_KEY_SHIFT_L                       '&'        XK_ampersand
-BX_KEY_6+BX_KEY_ALT_R                         '¥'        XK_yen
-BX_KEY_7                                      '7'        XK_7
-BX_KEY_7+BX_KEY_SHIFT_L                       '/'        XK_slash
-BX_KEY_7+BX_KEY_ALT_R                         '{'        XK_braceleft
-BX_KEY_7+BX_KEY_SHIFT_L+BX_KEY_ALT_R          '÷'        XK_division
-BX_KEY_8                                      '8'        XK_8
-BX_KEY_8+BX_KEY_SHIFT_L                       '('        XK_parenleft
-BX_KEY_8+BX_KEY_ALT_R                         '['        XK_bracketleft
-BX_KEY_9                                      '9'        XK_9
-BX_KEY_9+BX_KEY_SHIFT_L                       ')'        XK_parenright
-BX_KEY_9+BX_KEY_ALT_R                         ']'        XK_bracketright
-BX_KEY_0                                      '0'        XK_0
-BX_KEY_0+BX_KEY_SHIFT_L                       '='        XK_equal
-BX_KEY_0+BX_KEY_ALT_R                         '}'        XK_braceright
-BX_KEY_0+BX_KEY_SHIFT_L+BX_KEY_ALT_R          '°'        XK_degree
-BX_KEY_MINUS                                  '+'        XK_plus
-BX_KEY_MINUS+BX_KEY_SHIFT_L                   '?'        XK_question
-BX_KEY_MINUS+BX_KEY_ALT_L                     backslash  XK_backslash
-BX_KEY_MINUS+BX_KEY_SHIFT_L+BX_KEY_ALT_R      '¿'        XK_questiondown
-BX_KEY_EQUALS                                 none       XK_dead_acute
-BX_KEY_EQUALS+BX_KEY_SHIFT_L                  none       XK_dead_grave
-BX_KEY_EQUALS+BX_KEY_ALT_L                    '±'        XK_plusminus
-BX_KEY_EQUALS+BX_KEY_ALT_L+BX_KEY_ALT_R       '¬'        XK_notsign
-BX_KEY_BACKSPACE                              none       XK_BackSpace
-
-#  Row 2
-BX_KEY_TAB                                    tab        XK_Tab
-BX_KEY_TAB                                    none       XK_ISO_Left_Tab
-BX_KEY_Q                                      'q'        XK_q
-BX_KEY_Q+BX_KEY_SHIFT_L                       'Q'        XK_Q
-BX_KEY_W                                      'w'        XK_w
-BX_KEY_W+BX_KEY_SHIFT_L                       'W'        XK_W
-BX_KEY_E                                      'e'        XK_e
-BX_KEY_E+BX_KEY_SHIFT_L                       'E'        XK_E
-BX_KEY_E+BX_KEY_SHIFT_L+BX_KEY_ALT_R          none       XK_EuroSign
-BX_KEY_R                                      'r'        XK_r
-BX_KEY_R+BX_KEY_SHIFT_L                       'R'        XK_R
-BX_KEY_R+BX_KEY_ALT_R                         '®'        XK_registered
-BX_KEY_T                                      't'        XK_t
-BX_KEY_T+BX_KEY_SHIFT_L                       'T'        XK_T
-BX_KEY_T+BX_KEY_ALT_R                         'þ'        XK_thorn
-BX_KEY_T+BX_KEY_SHIFT_L+BX_KEY_ALT_R          'Þ'        XK_THORN
-BX_KEY_Y                                      'y'        XK_y
-BX_KEY_Y+BX_KEY_SHIFT_L                       'Y'        XK_Y
-BX_KEY_U                                      'u'        XK_u
-BX_KEY_U+BX_KEY_SHIFT_L                       'U'        XK_U
-BX_KEY_I                                      'i'        XK_i
-BX_KEY_I+BX_KEY_SHIFT_L                       'I'        XK_I
-BX_KEY_O                                      'o'        XK_o
-BX_KEY_O+BX_KEY_SHIFT_L                       'O'        XK_O
-BX_KEY_P                                      'p'        XK_p
-BX_KEY_P+BX_KEY_SHIFT_L                       'P'        XK_P
-BX_KEY_LEFT_BRACKET                           'å'        XK_aring
-BX_KEY_LEFT_BRACKET+BX_KEY_SHIFT_L            'Å'        XK_Aring
-BX_KEY_RIGHT_BRACKET                          none       XK_dead_diaeresis
-BX_KEY_RIGHT_BRACKET+BX_KEY_SHIFT_L           none       XK_dead_circumflex
-BX_KEY_RIGHT_BRACKET+BX_KEY_ALT_R             none       XK_dead_tilde
-BX_KEY_ENTER                                  return     XK_Return
-
-#  Row 3
-BX_KEY_CAPS_LOCK                              none       XK_Caps_Lock
-BX_KEY_A                                      'a'        XK_a
-BX_KEY_A+BX_KEY_SHIFT_L                       'A'        XK_A
-BX_KEY_A+BX_KEY_ALT_R                         'ª'        XK_ordfeminine
-BX_KEY_A+BX_KEY_SHIFT_L+BX_KEY_ALT_R          'º'        XK_masculine
-BX_KEY_S                                      's'        XK_s
-BX_KEY_S+BX_KEY_SHIFT_L                       'S'        XK_S
-BX_KEY_S+BX_KEY_ALT_R                         'ß'        XK_ssharp
-BX_KEY_D                                      'd'        XK_d
-BX_KEY_D+BX_KEY_SHIFT_L                       'D'        XK_D
-BX_KEY_D+BX_KEY_ALT_R                         'ð'        XK_eth
-BX_KEY_D+BX_KEY_SHIFT_L+BX_KEY_ALT_R          'Ð'        XK_ETH
-BX_KEY_F                                      'f'        XK_f
-BX_KEY_F+BX_KEY_SHIFT_L                       'F'        XK_F
-BX_KEY_G                                      'g'        XK_g
-BX_KEY_G+BX_KEY_SHIFT_L                       'G'        XK_G
-BX_KEY_H                                      'h'        XK_h
-BX_KEY_H+BX_KEY_SHIFT_L                       'H'        XK_H
-BX_KEY_J                                      'j'        XK_j
-BX_KEY_J+BX_KEY_SHIFT_L                       'J'        XK_J
-BX_KEY_K                                      'k'        XK_k
-BX_KEY_K+BX_KEY_SHIFT_L                       'K'        XK_K
-BX_KEY_L                                      'l'        XK_l
-BX_KEY_L+BX_KEY_SHIFT_L                       'L'        XK_L
-BX_KEY_SEMICOLON                              'ö'        XK_odiaeresis
-BX_KEY_SEMICOLON+BX_KEY_SHIFT_L               'Ö'        XK_Odiaeresis
-BX_KEY_SEMICOLON+BX_KEY_ALT_R                 'ø'        XK_oslash
-BX_KEY_SEMICOLON+BX_KEY_SHIFT_L+BX_KEY_ALT_R  'Ø'        XK_Ooblique
-BX_KEY_SINGLE_QUOTE                           'ä'        XK_adiaeresis
-BX_KEY_SINGLE_QUOTE+BX_KEY_SHIFT_L            'Ä'        XK_Adiaeresis
-BX_KEY_SINGLE_QUOTE+BX_KEY_ALT_R              'æ'        XK_ae
-BX_KEY_SINGLE_QUOTE+BX_KEY_SHIFT_L+BX_KEY_ALT_R 'Æ'      XK_AE
-BX_KEY_BACKSLASH                              apostrophe XK_apostrophe
-BX_KEY_BACKSLASH+BX_KEY_SHIFT_L               '*'        XK_asterisk
-BX_KEY_BACKSLASH+BX_KEY_ALT_R                 '´'        XK_acute
-BX_KEY_BACKSLASH+BX_KEY_SHIFT_L+BX_KEY_ALT_R  '×'        XK_multiply
-
-#  Row 4
-BX_KEY_SHIFT_L                                none       XK_Shift_L
-BX_KEY_LEFT_BACKSLASH                         '<'        XK_less
-BX_KEY_LEFT_BACKSLASH+BX_KEY_SHIFT_L          '>'        XK_greater
-BX_KEY_LEFT_BACKSLASH+BX_KEY_ALT_R            '|'        XK_bar
-BX_KEY_LEFT_BACKSLASH+BX_KEY_SHIFT_L+BX_KEY_ALT_R '¦'    XK_brokenbar
-BX_KEY_Z                                      'z'        XK_z
-BX_KEY_Z+BX_KEY_SHIFT_L                       'Z'        XK_Z
-BX_KEY_Z+BX_KEY_ALT_R                         '«'        XK_guillemotleft
-BX_KEY_X                                      'x'        XK_x
-BX_KEY_X+BX_KEY_SHIFT_L                       'X'        XK_X
-BX_KEY_X+BX_KEY_ALT_R                         '»'        XK_guillemotright
-BX_KEY_C                                      'c'        XK_c
-BX_KEY_C+BX_KEY_SHIFT_L                       'C'        XK_C
-BX_KEY_C+BX_KEY_ALT_R                         '©'        XK_copyright
-BX_KEY_V                                      'v'        XK_v
-BX_KEY_V+BX_KEY_SHIFT_L                       'V'        XK_V
-BX_KEY_V+BX_KEY_SHIFT_L+BX_KEY_ALT_R          '`'        XK_grave
-BX_KEY_B                                      'b'        XK_b
-BX_KEY_B+BX_KEY_SHIFT_L                       'B'        XK_B
-BX_KEY_N                                      'n'        XK_n
-BX_KEY_N+BX_KEY_SHIFT_L                       'N'        XK_N
-BX_KEY_M                                      'm'        XK_m
-BX_KEY_M+BX_KEY_SHIFT_L                       'M'        XK_M
-BX_KEY_M+BX_KEY_ALT_R                         'µ'        XK_mu
-BX_KEY_COMMA                                  ','        XK_comma
-BX_KEY_COMMA+BX_KEY_SHIFT_L                   ';'        XK_semicolon
-BX_KEY_PERIOD                                 '.'        XK_period
-BX_KEY_PERIOD+BX_KEY_SHIFT_L                  ':'        XK_colon
-BX_KEY_PERIOD+BX_KEY_ALT_R                    '·'        XK_periodcentered
-BX_KEY_SLASH                                  '-'        XK_minus
-BX_KEY_SLASH+BX_KEY_SHIFT                     '_'        XK_underscore
-BX_KEY_SLASH+BX_KEY_ALT_R                     '­'        XK_hyphen
-BX_KEY_SLASH+BX_KEY_SHIFT+BX_KEY_ALT_R        '­'        XK_macron
-BX_KEY_SHIFT_R                                none       XK_Shift_R
-
-#  Row 5
-BX_KEY_CTRL_L                                 none       XK_Control_L
-BX_KEY_WIN_L                                  none       XK_Super_L
-BX_KEY_ALT_L                                  none       XK_Alt_L
-BX_KEY_ALT_L                                  none       XK_Meta_L
-BX_KEY_SPACE                                  space      XK_space
-BX_KEY_SPACE+BX_KEY_ALT_R                     none       XK_nobreakspace
-BX_KEY_ALT_R                                  none       XK_Alt_R
-BX_KEY_ALT_R                                  none       XK_Mode_switch
-BX_KEY_ALT_R                                  none       XK_Multi_key
-BX_KEY_WIN_R                                  none       XK_Super_R
-BX_KEY_MENU                                   none       XK_Menu
-BX_KEY_CTRL_R                                 none       XK_Control_R
-
-# Ins/Del/Home/End/PgUp/PgDn
-BX_KEY_INSERT                                 none       XK_Insert
-BX_KEY_DELETE                                 none       XK_Delete
-BX_KEY_HOME                                   none       XK_Home
-BX_KEY_END                                    none       XK_End
-BX_KEY_PAGE_UP                                none       XK_Page_Up
-BX_KEY_PAGE_DOWN                              none       XK_Page_Down
-
-# Arrow keys
-BX_KEY_LEFT                                   none       XK_Left
-BX_KEY_RIGHT                                  none       XK_Right
-BX_KEY_UP                                     none       XK_Up
-BX_KEY_DOWN                                   none       XK_Down
-
-# Numerical keypad
-BX_KEY_NUM_LOCK                               none       XK_Num_Lock
-BX_KEY_KP_DIVIDE                              none       XK_KP_Divide
-BX_KEY_KP_MULTIPLY                            none       XK_KP_Multiply
-BX_KEY_KP_SUBTRACT                            none       XK_KP_Subtract
-BX_KEY_KP_ADD                                 none       XK_KP_Add
-BX_KEY_KP_ENTER                               none       XK_KP_Enter
-BX_KEY_KP_HOME                                none       XK_KP_7
-BX_KEY_KP_HOME                                none       XK_KP_Home
-BX_KEY_KP_UP                                  none       XK_KP_8
-BX_KEY_KP_UP                                  none       XK_KP_Up
-BX_KEY_KP_PAGE_UP                             none       XK_KP_9
-BX_KEY_KP_PAGE_UP                             none       XK_KP_Page_Up
-BX_KEY_KP_LEFT                                none       XK_KP_4
-BX_KEY_KP_LEFT                                none       XK_KP_Left
-BX_KEY_KP_5                                   none       XK_KP_5
-BX_KEY_KP_5                                   none       XK_KP_Begin
-BX_KEY_KP_RIGHT                               none       XK_KP_6
-BX_KEY_KP_RIGHT                               none       XK_KP_Right
-BX_KEY_KP_END                                 none       XK_KP_1
-BX_KEY_KP_END                                 none       XK_KP_End
-BX_KEY_KP_DOWN                                none       XK_KP_2
-BX_KEY_KP_DOWN                                none       XK_KP_Down
-BX_KEY_KP_PAGE_DOWN                           none       XK_KP_3
-BX_KEY_KP_PAGE_DOWN                           none       XK_KP_Page_Down
-BX_KEY_KP_INSERT                              none       XK_KP_0
-BX_KEY_KP_INSERT                              none       XK_KP_Insert
-BX_KEY_KP_DELETE                              none       XK_KP_Decimal
-BX_KEY_KP_DELETE                              none       XK_KP_Delete
diff --git a/tools/ioemu/gui/keymaps/x11-pc-uk.map b/tools/ioemu/gui/keymaps/x11-pc-uk.map
deleted file mode 100644 (file)
index 05abbe4..0000000
+++ /dev/null
@@ -1,209 +0,0 @@
-# Bochs Keymap file
-# $Id: x11-pc-uk.map,v 1.1 2002/12/11 21:35:50 bdenney Exp $
-# Target: PC(x86) keyboard, UK keymap
-# Author: Denis Lenihan
-#
-# The keymap file describes the layout of a keyboard, and how it translates
-# into Bochs key codes.
-#
-# Format:
-#  BX_Keysym                ASCII_equivalent      Xwin_Keysym
-#
-# Or, for keys that require modifiers:
-#  BX_Keysym+BX_Modifier    ASCII_equivalent    Xwin_Keysym
-#
-# BX_Keysym and BX_Modifier must be present in the bx_key_symbol[] list in
-# gui/keymap.cc.  The BX_Modifier is usually a shift key press, but it
-# could be any key.  Presently a maximum of one modifier is supported, but this
-# could be changed in keymap.h (structure def has only one slot for modifier),
-# keymap.cc (parsing code), and iodev/keyboard.cc (simulate keypresses for >1
-# modifier).
-#
-# The ASCII_equivalent must be either apostrophe + one character + apostrophe,
-# or one of these keywords: space, return, tab, backslash, apostrophe, none.
-# This format is designed to look like a char constant in C, but it's a very
-# simple parser.  There's no concept of backslash being an escape char.  The
-# backslash and apostrophe entries are provided for aesthetic purposes only: no
-# C++ programmer wants to see '\' or '''. The parser doesn't care, but they are
-# ugly.
-#
-# Xwin_Keysym is the X windows equivalent of the key combination.  These
-# codes should match whatever you find in /usr/X11R6/include/X11/keysymdef.h.
-# If you're running X windows, Bochs will take each of these Xwin_Keysyms,
-# pull off the XK_ in front, and use XStringToKeysym() to change them into
-# numerical codes.  If this lookup fails, you will get a panic and you need
-# to edit the keymap file.
-#
-
-BX_KEY_0                                      '0'        XK_0
-BX_KEY_0+BX_KEY_SHIFT_L                       ')'        XK_parenright
-BX_KEY_1                                      '1'        XK_1
-BX_KEY_1+BX_KEY_SHIFT_L                       '!'        XK_exclam
-BX_KEY_2                                      '2'        XK_2
-BX_KEY_2+BX_KEY_SHIFT_L                       '"'        XK_quotedbl
-BX_KEY_3                                      '3'        XK_3
-BX_KEY_3+BX_KEY_SHIFT_L                       '£'        XK_sterling
-BX_KEY_3+BX_KEY_ALT_R                        '|'        XK_EuroSign
-BX_KEY_4                                      '4'        XK_4
-BX_KEY_4+BX_KEY_SHIFT_L                       '$'        XK_dollar
-BX_KEY_5                                      '5'        XK_5
-BX_KEY_5+BX_KEY_SHIFT_L                       '%'        XK_percent
-BX_KEY_6                                      '6'        XK_6
-BX_KEY_6+BX_KEY_SHIFT_L                       '^'        XK_asciicircum
-BX_KEY_7                                      '7'        XK_7
-BX_KEY_7+BX_KEY_SHIFT_L                       '&'        XK_ampersand
-BX_KEY_8                                      '8'        XK_8
-BX_KEY_8+BX_KEY_SHIFT_L                       '*'        XK_asterisk
-BX_KEY_9                                      '9'        XK_9
-BX_KEY_9+BX_KEY_SHIFT_L                       '('        XK_parenleft
-BX_KEY_A+BX_KEY_SHIFT_L                       'A'        XK_A
-BX_KEY_A                                      'a'        XK_a
-BX_KEY_B+BX_KEY_SHIFT_L                       'B'        XK_B
-BX_KEY_B                                      'b'        XK_b
-BX_KEY_C+BX_KEY_SHIFT_L                       'C'        XK_C
-BX_KEY_C                                      'c'        XK_c
-BX_KEY_D+BX_KEY_SHIFT_L                       'D'        XK_D
-BX_KEY_D                                      'd'        XK_d
-BX_KEY_E+BX_KEY_SHIFT_L                       'E'        XK_E
-BX_KEY_E                                      'e'        XK_e
-BX_KEY_F+BX_KEY_SHIFT_L                       'F'        XK_F
-BX_KEY_F                                      'f'        XK_f
-BX_KEY_G+BX_KEY_SHIFT_L                       'G'        XK_G
-BX_KEY_G                                      'g'        XK_g
-BX_KEY_H+BX_KEY_SHIFT_L                       'H'        XK_H
-BX_KEY_H                                      'h'        XK_h
-BX_KEY_I+BX_KEY_SHIFT_L                       'I'        XK_I
-BX_KEY_I                                      'i'        XK_i
-BX_KEY_J+BX_KEY_SHIFT_L                       'J'        XK_J
-BX_KEY_J                                      'j'        XK_j
-BX_KEY_K+BX_KEY_SHIFT_L                       'K'        XK_K
-BX_KEY_K                                      'k'        XK_k
-BX_KEY_L+BX_KEY_SHIFT_L                       'L'        XK_L
-BX_KEY_L                                      'l'        XK_l
-BX_KEY_M+BX_KEY_SHIFT_L                       'M'        XK_M
-BX_KEY_M                                      'm'        XK_m
-BX_KEY_N+BX_KEY_SHIFT_L                       'N'        XK_N
-BX_KEY_N                                      'n'        XK_n
-BX_KEY_O+BX_KEY_SHIFT_L                       'O'        XK_O
-BX_KEY_O                                      'o'        XK_o
-BX_KEY_P+BX_KEY_SHIFT_L                       'P'        XK_P
-BX_KEY_P                                      'p'        XK_p
-BX_KEY_Q+BX_KEY_SHIFT_L                       'Q'        XK_Q
-BX_KEY_Q                                      'q'        XK_q
-BX_KEY_R+BX_KEY_SHIFT_L                       'R'        XK_R
-BX_KEY_R                                      'r'        XK_r
-BX_KEY_S+BX_KEY_SHIFT_L                       'S'        XK_S
-BX_KEY_S                                      's'        XK_s
-BX_KEY_T+BX_KEY_SHIFT_L                       'T'        XK_T
-BX_KEY_T                                      't'        XK_t
-BX_KEY_U+BX_KEY_SHIFT_L                       'U'        XK_U
-BX_KEY_U                                      'u'        XK_u
-BX_KEY_V+BX_KEY_SHIFT_L                       'V'        XK_V
-BX_KEY_V                                      'v'        XK_v
-BX_KEY_W+BX_KEY_SHIFT_L                       'W'        XK_W
-BX_KEY_W                                      'w'        XK_w
-BX_KEY_X+BX_KEY_SHIFT_L                       'X'        XK_X
-BX_KEY_X                                      'x'        XK_x
-BX_KEY_Y+BX_KEY_SHIFT_L                       'Y'        XK_Y
-BX_KEY_Y                                      'y'        XK_y
-BX_KEY_Z+BX_KEY_SHIFT_L                       'Z'        XK_Z
-BX_KEY_Z                                      'z'        XK_z
-BX_KEY_F1                                     none       XK_F1
-BX_KEY_F2                                     none       XK_F2
-BX_KEY_F3                                     none       XK_F3
-BX_KEY_F4                                     none       XK_F4
-BX_KEY_F5                                     none       XK_F5
-BX_KEY_F6                                     none       XK_F6
-BX_KEY_F7                                     none       XK_F7
-BX_KEY_F8                                     none       XK_F8
-BX_KEY_F9                                     none       XK_F9
-BX_KEY_F10                                    none       XK_F10
-BX_KEY_F11                                    none       XK_F11
-BX_KEY_F12                                    none       XK_F12
-BX_KEY_ALT_L                                  none       XK_Alt_L
-BX_KEY_ALT_L                                  none       XK_Meta_L
-BX_KEY_ALT_R                                  none       XK_Alt_R
-BX_KEY_ALT_R                                  none       XK_Mode_switch
-BX_KEY_ALT_R                                  none       XK_Multi_key
-BX_KEY_LEFT_BACKSLASH                         '\'       XK_backslash
-BX_KEY_LEFT_BACKSLASH+BX_KEY_SHIFT_L          '|'        XK_bar
-BX_KEY_BACKSLASH                             '~'        XK_asciitilde
-BX_KEY_BACKSLASH+BX_KEY_SHIFT_L              '#'        XK_numbersign
-BX_KEY_BACKSPACE                              none       XK_BackSpace
-BX_KEY_CAPS_LOCK                              none       XK_Caps_Lock
-BX_KEY_COMMA                                  ','        XK_comma
-BX_KEY_COMMA+BX_KEY_SHIFT_L                   '<'        XK_less
-BX_KEY_CTRL_L                                 none       XK_Control_L
-BX_KEY_CTRL_R                                 none       XK_Control_R
-BX_KEY_DELETE                                 none       XK_Delete
-BX_KEY_DOWN                                   none       XK_Down
-BX_KEY_END                                    none       XK_End
-BX_KEY_ENTER                                  return     XK_Return
-BX_KEY_EQUALS                                 '='        XK_equal
-BX_KEY_EQUALS+BX_KEY_SHIFT_L                  '+'        XK_plus
-BX_KEY_ESC                                    none       XK_Escape
-BX_KEY_GRAVE+BX_KEY_SHIFT_L                   '¬'        XK_notsign
-BX_KEY_GRAVE                                  '`'        XK_grave
-BX_KEY_GRAVE+BX_KEY_ALT_R                     '|'        XK_bar
-BX_KEY_HOME                                   none       XK_Home
-BX_KEY_INSERT                                 none       XK_Insert
-BX_KEY_KP_5                                   none       XK_KP_5
-BX_KEY_KP_5                                   none       XK_KP_Begin
-BX_KEY_KP_ADD                                 none       XK_KP_Add
-BX_KEY_KP_DELETE                              none       XK_KP_Decimal
-BX_KEY_KP_DELETE                              none       XK_KP_Delete
-BX_KEY_KP_DIVIDE                              none       XK_KP_Divide
-BX_KEY_KP_DOWN                                none       XK_KP_2
-BX_KEY_KP_DOWN                                none       XK_KP_Down
-BX_KEY_KP_END                                 none       XK_KP_1
-BX_KEY_KP_END                                 none       XK_KP_End
-BX_KEY_KP_ENTER                               none       XK_KP_Enter
-BX_KEY_KP_HOME                                none       XK_KP_7
-BX_KEY_KP_HOME                                none       XK_KP_Home
-BX_KEY_KP_INSERT                              none       XK_KP_0
-BX_KEY_KP_INSERT                              none       XK_KP_Insert
-BX_KEY_KP_LEFT                                none       XK_KP_4
-BX_KEY_KP_LEFT                                none       XK_KP_Left
-BX_KEY_KP_MULTIPLY                            none       XK_KP_Multiply
-BX_KEY_KP_PAGE_DOWN                           none       XK_KP_3
-BX_KEY_KP_PAGE_DOWN                           none       XK_KP_Page_Down
-BX_KEY_KP_PAGE_UP                             none       XK_KP_9
-BX_KEY_KP_PAGE_UP                             none       XK_KP_Page_Up
-BX_KEY_KP_RIGHT                               none       XK_KP_6
-BX_KEY_KP_RIGHT                               none       XK_KP_Right
-BX_KEY_KP_SUBTRACT                            none       XK_KP_Subtract
-BX_KEY_KP_UP                                  none       XK_KP_8
-BX_KEY_KP_UP                                  none       XK_KP_Up
-BX_KEY_LEFT                                   none       XK_Left
-BX_KEY_LEFT_BRACKET+BX_KEY_SHIFT_L            '{'        XK_braceleft
-BX_KEY_LEFT_BRACKET                           '['        XK_bracketleft
-BX_KEY_MENU                                   none       XK_Menu
-BX_KEY_MINUS                                  '-'        XK_minus
-BX_KEY_MINUS+BX_KEY_SHIFT_L                   '_'        XK_underscore
-BX_KEY_NUM_LOCK                               none       XK_Num_Lock
-BX_KEY_PAGE_DOWN                              none       XK_Page_Down
-BX_KEY_PAGE_UP                                none       XK_Page_Up
-BX_KEY_PAUSE                                  none       XK_Break
-BX_KEY_PAUSE                                  none       XK_Pause
-BX_KEY_PERIOD+BX_KEY_SHIFT_L                  '>'        XK_greater
-BX_KEY_PERIOD                                 '.'        XK_period
-BX_KEY_PRINT                                  none       XK_Print
-BX_KEY_PRINT                                  none       XK_Sys_Req
-BX_KEY_RIGHT                                  none       XK_Right
-BX_KEY_RIGHT_BRACKET+BX_KEY_SHIFT_L           '}'        XK_braceright
-BX_KEY_RIGHT_BRACKET                          ']'        XK_bracketright
-BX_KEY_SCRL_LOCK                              none       XK_Scroll_Lock
-BX_KEY_SEMICOLON+BX_KEY_SHIFT_L               ':'        XK_colon
-BX_KEY_SEMICOLON                              ';'        XK_semicolon
-BX_KEY_SHIFT_L                                none       XK_Shift_L
-BX_KEY_SHIFT_R                                none       XK_Shift_R
-BX_KEY_SINGLE_QUOTE                           apostrophe XK_apostrophe
-BX_KEY_SINGLE_QUOTE+BX_KEY_SHIFT_L            '@'        XK_at
-BX_KEY_SLASH+BX_KEY_SHIFT_L                   '?'        XK_question
-BX_KEY_SLASH                                  '/'        XK_slash
-BX_KEY_SPACE                                  space      XK_space
-BX_KEY_TAB                                    none       XK_ISO_Left_Tab
-BX_KEY_TAB                                    tab        XK_Tab
-BX_KEY_UP                                     none       XK_Up
-BX_KEY_WIN_L                                  none       XK_Super_L
-BX_KEY_WIN_R                                  none       XK_Super_R
diff --git a/tools/ioemu/gui/keymaps/x11-pc-us.map b/tools/ioemu/gui/keymaps/x11-pc-us.map
deleted file mode 100644 (file)
index 8cda7a8..0000000
+++ /dev/null
@@ -1,205 +0,0 @@
-# Bochs Keymap file
-# $Id: x11-pc-us.map,v 1.3 2002/09/25 08:00:25 bdenney Exp $
-# Target: PC(x86) keyboard, US keymap
-# Author: Christophe Bothamy, Bryce Denney
-#
-# The keymap file describes the layout of a keyboard, and how it translates
-# into Bochs key codes.
-#
-# Format:
-#  BX_Keysym                ASCII_equivalent      Xwin_Keysym
-#
-# Or, for keys that require modifiers:
-#  BX_Keysym+BX_Modifier    ASCII_equivalent    Xwin_Keysym
-#
-# BX_Keysym and BX_Modifier must be present in the bx_key_symbol[] list in
-# gui/keymap.cc.  The BX_Modifier is usually a shift key press, but it
-# could be any key.  Presently a maximum of one modifier is supported, but this
-# could be changed in keymap.h (structure def has only one slot for modifier),
-# keymap.cc (parsing code), and iodev/keyboard.cc (simulate keypresses for >1
-# modifier).
-#
-# The ASCII_equivalent must be either apostrophe + one character + apostrophe,
-# or one of these keywords: space, return, tab, backslash, apostrophe, none.
-# This format is designed to look like a char constant in C, but it's a very
-# simple parser.  There's no concept of backslash being an escape char.  The
-# backslash and apostrophe entries are provided for aesthetic purposes only: no
-# C++ programmer wants to see '\' or '''. The parser doesn't care, but they are
-# ugly.
-#
-# Xwin_Keysym is the X windows equivalent of the key combination.  These
-# codes should match whatever you find in /usr/X11R6/include/X11/keysymdef.h.
-# If you're running X windows, Bochs will take each of these Xwin_Keysyms,
-# pull off the XK_ in front, and use XStringToKeysym() to change them into
-# numerical codes.  If this lookup fails, you will get a panic and you need
-# to edit the keymap file.
-#
-
-BX_KEY_0                                      '0'        XK_0
-BX_KEY_0+BX_KEY_SHIFT_L                       ')'        XK_parenright
-BX_KEY_1                                      '1'        XK_1
-BX_KEY_1+BX_KEY_SHIFT_L                       '!'        XK_exclam
-BX_KEY_2                                      '2'        XK_2
-BX_KEY_2+BX_KEY_SHIFT_L                       '@'        XK_at
-BX_KEY_3                                      '3'        XK_3
-BX_KEY_3+BX_KEY_SHIFT_L                       '#'        XK_numbersign
-BX_KEY_4                                      '4'        XK_4
-BX_KEY_4+BX_KEY_SHIFT_L                       '$'        XK_dollar
-BX_KEY_5                                      '5'        XK_5
-BX_KEY_5+BX_KEY_SHIFT_L                       '%'        XK_percent
-BX_KEY_6                                      '6'        XK_6
-BX_KEY_6+BX_KEY_SHIFT_L                       '^'        XK_asciicircum
-BX_KEY_7                                      '7'        XK_7
-BX_KEY_7+BX_KEY_SHIFT_L                       '&'        XK_ampersand
-BX_KEY_8                                      '8'        XK_8
-BX_KEY_8+BX_KEY_SHIFT_L                       '*'        XK_asterisk
-BX_KEY_9                                      '9'        XK_9
-BX_KEY_9+BX_KEY_SHIFT_L                       '('        XK_parenleft
-BX_KEY_A+BX_KEY_SHIFT_L                       'A'        XK_A
-BX_KEY_A                                      'a'        XK_a
-BX_KEY_B+BX_KEY_SHIFT_L                       'B'        XK_B
-BX_KEY_B                                      'b'        XK_b
-BX_KEY_C+BX_KEY_SHIFT_L                       'C'        XK_C
-BX_KEY_C                                      'c'        XK_c
-BX_KEY_D+BX_KEY_SHIFT_L                       'D'        XK_D
-BX_KEY_D                                      'd'        XK_d
-BX_KEY_E+BX_KEY_SHIFT_L                       'E'        XK_E
-BX_KEY_E                                      'e'        XK_e
-BX_KEY_F+BX_KEY_SHIFT_L                       'F'        XK_F
-BX_KEY_F                                      'f'        XK_f
-BX_KEY_G+BX_KEY_SHIFT_L                       'G'        XK_G
-BX_KEY_G                                      'g'        XK_g
-BX_KEY_H+BX_KEY_SHIFT_L                       'H'        XK_H
-BX_KEY_H                                      'h'        XK_h
-BX_KEY_I+BX_KEY_SHIFT_L                       'I'        XK_I
-BX_KEY_I                                      'i'        XK_i
-BX_KEY_J+BX_KEY_SHIFT_L                       'J'        XK_J
-BX_KEY_J                                      'j'        XK_j
-BX_KEY_K+BX_KEY_SHIFT_L                       'K'        XK_K
-BX_KEY_K                                      'k'        XK_k
-BX_KEY_L+BX_KEY_SHIFT_L                       'L'        XK_L
-BX_KEY_L                                      'l'        XK_l
-BX_KEY_M+BX_KEY_SHIFT_L                       'M'        XK_M
-BX_KEY_M                                      'm'        XK_m
-BX_KEY_N+BX_KEY_SHIFT_L                       'N'        XK_N
-BX_KEY_N                                      'n'        XK_n
-BX_KEY_O+BX_KEY_SHIFT_L                       'O'        XK_O
-BX_KEY_O                                      'o'        XK_o
-BX_KEY_P+BX_KEY_SHIFT_L                       'P'        XK_P
-BX_KEY_P                                      'p'        XK_p
-BX_KEY_Q+BX_KEY_SHIFT_L                       'Q'        XK_Q
-BX_KEY_Q                                      'q'        XK_q
-BX_KEY_R+BX_KEY_SHIFT_L                       'R'        XK_R
-BX_KEY_R                                      'r'        XK_r
-BX_KEY_S+BX_KEY_SHIFT_L                       'S'        XK_S
-BX_KEY_S                                      's'        XK_s
-BX_KEY_T+BX_KEY_SHIFT_L                       'T'        XK_T
-BX_KEY_T                                      't'        XK_t
-BX_KEY_U+BX_KEY_SHIFT_L                       'U'        XK_U
-BX_KEY_U                                      'u'        XK_u
-BX_KEY_V+BX_KEY_SHIFT_L                       'V'        XK_V
-BX_KEY_V                                      'v'        XK_v
-BX_KEY_W+BX_KEY_SHIFT_L                       'W'        XK_W
-BX_KEY_W                                      'w'        XK_w
-BX_KEY_X+BX_KEY_SHIFT_L                       'X'        XK_X
-BX_KEY_X                                      'x'        XK_x
-BX_KEY_Y+BX_KEY_SHIFT_L                       'Y'        XK_Y
-BX_KEY_Y                                      'y'        XK_y
-BX_KEY_Z+BX_KEY_SHIFT_L                       'Z'        XK_Z
-BX_KEY_Z                                      'z'        XK_z
-BX_KEY_F1                                     none       XK_F1
-BX_KEY_F2                                     none       XK_F2
-BX_KEY_F3                                     none       XK_F3
-BX_KEY_F4                                     none       XK_F4
-BX_KEY_F5                                     none       XK_F5
-BX_KEY_F6                                     none       XK_F6
-BX_KEY_F7                                     none       XK_F7
-BX_KEY_F8                                     none       XK_F8
-BX_KEY_F9                                     none       XK_F9
-BX_KEY_F10                                    none       XK_F10
-BX_KEY_F11                                    none       XK_F11
-BX_KEY_F12                                    none       XK_F12
-BX_KEY_ALT_L                                  none       XK_Alt_L
-BX_KEY_ALT_L                                  none       XK_Meta_L
-BX_KEY_ALT_R                                  none       XK_Alt_R
-BX_KEY_ALT_R                                  none       XK_Mode_switch
-BX_KEY_ALT_R                                  none       XK_Multi_key
-BX_KEY_BACKSLASH                              backslash  XK_backslash
-BX_KEY_BACKSLASH+BX_KEY_SHIFT_L               '|'        XK_bar
-BX_KEY_BACKSPACE                              none       XK_BackSpace
-BX_KEY_CAPS_LOCK                              none       XK_Caps_Lock
-BX_KEY_COMMA                                  ','        XK_comma
-BX_KEY_COMMA+BX_KEY_SHIFT_L                   '<'        XK_less
-BX_KEY_CTRL_L                                 none       XK_Control_L
-BX_KEY_CTRL_R                                 none       XK_Control_R
-BX_KEY_DELETE                                 none       XK_Delete
-BX_KEY_DOWN                                   none       XK_Down
-BX_KEY_END                                    none       XK_End
-BX_KEY_ENTER                                  return     XK_Return
-BX_KEY_EQUALS                                 '='        XK_equal
-BX_KEY_EQUALS+BX_KEY_SHIFT_L                  '+'        XK_plus
-BX_KEY_ESC                                    none       XK_Escape
-BX_KEY_GRAVE+BX_KEY_SHIFT_L                   '~'        XK_asciitilde
-BX_KEY_GRAVE                                  '`'        XK_grave
-BX_KEY_HOME                                   none       XK_Home
-BX_KEY_INSERT                                 none       XK_Insert
-BX_KEY_KP_5                                   none       XK_KP_5
-BX_KEY_KP_5                                   none       XK_KP_Begin
-BX_KEY_KP_ADD                                 none       XK_KP_Add
-BX_KEY_KP_DELETE                              none       XK_KP_Decimal
-BX_KEY_KP_DELETE                              none       XK_KP_Delete
-BX_KEY_KP_DIVIDE                              none       XK_KP_Divide
-BX_KEY_KP_DOWN                                none       XK_KP_2
-BX_KEY_KP_DOWN                                none       XK_KP_Down
-BX_KEY_KP_END                                 none       XK_KP_1
-BX_KEY_KP_END                                 none       XK_KP_End
-BX_KEY_KP_ENTER                               none       XK_KP_Enter
-BX_KEY_KP_HOME                                none       XK_KP_7
-BX_KEY_KP_HOME                                none       XK_KP_Home
-BX_KEY_KP_INSERT                              none       XK_KP_0
-BX_KEY_KP_INSERT                              none       XK_KP_Insert
-BX_KEY_KP_LEFT                                none       XK_KP_4
-BX_KEY_KP_LEFT                                none       XK_KP_Left
-BX_KEY_KP_MULTIPLY                            none       XK_KP_Multiply
-BX_KEY_KP_PAGE_DOWN                           none       XK_KP_3
-BX_KEY_KP_PAGE_DOWN                           none       XK_KP_Page_Down
-BX_KEY_KP_PAGE_UP                             none       XK_KP_9
-BX_KEY_KP_PAGE_UP                             none       XK_KP_Page_Up
-BX_KEY_KP_RIGHT                               none       XK_KP_6
-BX_KEY_KP_RIGHT                               none       XK_KP_Right
-BX_KEY_KP_SUBTRACT                            none       XK_KP_Subtract
-BX_KEY_KP_UP                                  none       XK_KP_8
-BX_KEY_KP_UP                                  none       XK_KP_Up
-BX_KEY_LEFT                                   none       XK_Left
-BX_KEY_LEFT_BRACKET+BX_KEY_SHIFT_L            '{'        XK_braceleft
-BX_KEY_LEFT_BRACKET                           '['        XK_bracketleft
-BX_KEY_MENU                                   none       XK_Menu
-BX_KEY_MINUS                                  '-'        XK_minus
-BX_KEY_MINUS+BX_KEY_SHIFT_L                   '_'        XK_underscore
-BX_KEY_NUM_LOCK                               none       XK_Num_Lock
-BX_KEY_PAGE_DOWN                              none       XK_Page_Down
-BX_KEY_PAGE_UP                                none       XK_Page_Up
-BX_KEY_PAUSE                                  none       XK_Break
-BX_KEY_PAUSE                                  none       XK_Pause
-BX_KEY_PERIOD+BX_KEY_SHIFT_L                  '>'        XK_greater
-BX_KEY_PERIOD                                 '.'        XK_period
-BX_KEY_PRINT                                  none       XK_Print
-BX_KEY_PRINT                                  none       XK_Sys_Req
-BX_KEY_RIGHT                                  none       XK_Right
-BX_KEY_RIGHT_BRACKET+BX_KEY_SHIFT_L           '}'        XK_braceright
-BX_KEY_RIGHT_BRACKET                          ']'        XK_bracketright
-BX_KEY_SCRL_LOCK                              none       XK_Scroll_Lock
-BX_KEY_SEMICOLON+BX_KEY_SHIFT_L               ':'        XK_colon
-BX_KEY_SEMICOLON                              ';'        XK_semicolon
-BX_KEY_SHIFT_L                                none       XK_Shift_L
-BX_KEY_SHIFT_R                                none       XK_Shift_R
-BX_KEY_SINGLE_QUOTE                           apostrophe XK_apostrophe
-BX_KEY_SINGLE_QUOTE+BX_KEY_SHIFT_L            '"'        XK_quotedbl
-BX_KEY_SLASH+BX_KEY_SHIFT_L                   '?'        XK_question
-BX_KEY_SLASH                                  '/'        XK_slash
-BX_KEY_SPACE                                  space      XK_space
-BX_KEY_TAB                                    none       XK_ISO_Left_Tab
-BX_KEY_TAB                                    tab        XK_Tab
-BX_KEY_UP                                     none       XK_Up
-BX_KEY_WIN_L                                  none       XK_Super_L
-BX_KEY_WIN_R                                  none       XK_Super_R
diff --git a/tools/ioemu/gui/nogui.cc b/tools/ioemu/gui/nogui.cc
deleted file mode 100644 (file)
index dd56d9d..0000000
+++ /dev/null
@@ -1,336 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: nogui.cc,v 1.21 2003/06/28 08:04:31 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2001  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-
-// Define BX_PLUGGABLE in files that can be compiled into plugins.  For
-// platforms that require a special tag on exported symbols, BX_PLUGGABLE 
-// is used to know when we are exporting symbols and when we are importing.
-#define BX_PLUGGABLE
-
-#include "bochs.h"
-#include "icon_bochs.h"
-
-class bx_nogui_gui_c : public bx_gui_c {
-public:
-  bx_nogui_gui_c (void) {}
-  DECLARE_GUI_VIRTUAL_METHODS()
-};
-
-// declare one instance of the gui object and call macro to insert the
-// plugin code
-static bx_nogui_gui_c *theGui = NULL;
-IMPLEMENT_GUI_PLUGIN_CODE(nogui)
-
-#define LOG_THIS theGui->
-
-// This file defines stubs for the GUI interface, which is a
-// place to start if you want to port bochs to a platform, for
-// which there is no support for your native GUI, or if you want to compile
-// bochs without any native GUI support (no output window or
-// keyboard input will be possible).
-// Look in 'x.cc', 'beos.cc', and 'win32.cc' for specific
-// implementations of this interface.  -Kevin
-
-
-
-// ::SPECIFIC_INIT()
-//
-// Called from gui.cc, once upon program startup, to allow for the
-// specific GUI code (X11, BeOS, ...) to be initialized.
-//
-// argc, argv: not used right now, but the intention is to pass native GUI
-//     specific options from the command line.  (X11 options, BeOS options,...)
-//
-// tilewidth, tileheight: for optimization, graphics_tile_update() passes
-//     only updated regions of the screen to the gui code to be redrawn.
-//     These define the dimensions of a region (tile).
-// headerbar_y:  A headerbar (toolbar) is display on the top of the
-//     VGA window, showing floppy status, and other information.  It
-//     always assumes the width of the current VGA mode width, but
-//     it's height is defined by this parameter.
-
-  void
-bx_nogui_gui_c::specific_init(int argc, char **argv, unsigned tilewidth, unsigned tileheight,
-                     unsigned headerbar_y)
-{
-  put("NGUI");
-  UNUSED(argc);
-  UNUSED(argv);
-  UNUSED(tilewidth);
-  UNUSED(tileheight);
-  UNUSED(headerbar_y);
-
-  UNUSED(bochs_icon_bits);  // global variable
-
-  if (bx_options.Oprivate_colormap->get ()) {
-    BX_INFO(("private_colormap option ignored."));
-    }
-}
-
-
-// ::HANDLE_EVENTS()
-//
-// Called periodically (vga_update_interval in .bochsrc) so the
-// the gui code can poll for keyboard, mouse, and other
-// relevant events.
-
-  void
-bx_nogui_gui_c::handle_events(void)
-{
-}
-
-
-// ::FLUSH()
-//
-// Called periodically, requesting that the gui code flush all pending
-// screen update requests.
-
-  void
-bx_nogui_gui_c::flush(void)
-{
-}
-
-
-// ::CLEAR_SCREEN()
-//
-// Called to request that the VGA region is cleared.  Don't
-// clear the area that defines the headerbar.
-
-  void
-bx_nogui_gui_c::clear_screen(void)
-{
-}
-
-
-
-// ::TEXT_UPDATE()
-//
-// Called in a VGA text mode, to update the screen with
-// new content.
-//
-// old_text: array of character/attributes making up the contents
-//           of the screen from the last call.  See below
-// new_text: array of character/attributes making up the current
-//           contents, which should now be displayed.  See below
-//
-// format of old_text & new_text: each is 4000 bytes long.
-//     This represents 80 characters wide by 25 high, with
-//     each character being 2 bytes.  The first by is the
-//     character value, the second is the attribute byte.
-//     I currently don't handle the attribute byte.
-//
-// cursor_x: new x location of cursor
-// cursor_y: new y location of cursor
-
-  void
-bx_nogui_gui_c::text_update(Bit8u *old_text, Bit8u *new_text,
-                      unsigned long cursor_x, unsigned long cursor_y,
-                      bx_vga_tminfo_t tm_info, unsigned nrows)
-{
-  UNUSED(old_text);
-  UNUSED(new_text);
-  UNUSED(cursor_x);
-  UNUSED(cursor_y);
-  UNUSED(tm_info);
-  UNUSED(nrows);
-}
-
-  int
-bx_nogui_gui_c::get_clipboard_text(Bit8u **bytes, Bit32s *nbytes)
-{
-  UNUSED(bytes);
-  UNUSED(nbytes);
-  return 0;
-}
-
-  int
-bx_nogui_gui_c::set_clipboard_text(char *text_snapshot, Bit32u len)
-{
-  UNUSED(text_snapshot);
-  UNUSED(len);
-  return 0;
-}
-
-
-// ::PALETTE_CHANGE()
-//
-// Allocate a color in the native GUI, for this color, and put
-// it in the colormap location 'index'.
-// returns: 0=no screen update needed (color map change has direct effect)
-//          1=screen updated needed (redraw using current colormap)
-
-  bx_bool
-bx_nogui_gui_c::palette_change(unsigned index, unsigned red, unsigned green, unsigned blue)
-{
-  UNUSED(index);
-  UNUSED(red);
-  UNUSED(green);
-  UNUSED(blue);
-  return(0);
-}
-
-
-// ::GRAPHICS_TILE_UPDATE()
-//
-// Called to request that a tile of graphics be drawn to the
-// screen, since info in this region has changed.
-//
-// tile: array of 8bit values representing a block of pixels with
-//       dimension equal to the 'tilewidth' & 'tileheight' parameters to
-//       ::specific_init().  Each value specifies an index into the
-//       array of colors you allocated for ::palette_change()
-// x0: x origin of tile
-// y0: y origin of tile
-//
-// note: origin of tile and of window based on (0,0) being in the upper
-//       left of the window.
-
-  void
-bx_nogui_gui_c::graphics_tile_update(Bit8u *tile, unsigned x0, unsigned y0)
-{
-  UNUSED(tile);
-  UNUSED(x0);
-  UNUSED(y0);
-}
-
-
-
-// ::DIMENSION_UPDATE()
-//
-// Called when the VGA mode changes it's X,Y dimensions.
-// Resize the window to this size, but you need to add on
-// the height of the headerbar to the Y value.
-//
-// x: new VGA x size
-// y: new VGA y size (add headerbar_y parameter from ::specific_init().
-// fheight: new VGA character height in text mode
-// fwidth : new VGA character width in text mode
-// bpp : bits per pixel in graphics mode
-
-  void
-bx_nogui_gui_c::dimension_update(unsigned x, unsigned y, unsigned fheight, unsigned fwidth, unsigned bpp)
-{
-  UNUSED(x);
-  UNUSED(y);
-  UNUSED(fheight);
-  UNUSED(fwidth);
-  UNUSED(bpp);
-}
-
-
-// ::CREATE_BITMAP()
-//
-// Create a monochrome bitmap of size 'xdim' by 'ydim', which will
-// be drawn in the headerbar.  Return an integer ID to the bitmap,
-// with which the bitmap can be referenced later.
-//
-// bmap: packed 8 pixels-per-byte bitmap.  The pixel order is:
-//       bit0 is the left most pixel, bit7 is the right most pixel.
-// xdim: x dimension of bitmap
-// ydim: y dimension of bitmap
-
-  unsigned
-bx_nogui_gui_c::create_bitmap(const unsigned char *bmap, unsigned xdim, unsigned ydim)
-{
-  UNUSED(bmap);
-  UNUSED(xdim);
-  UNUSED(ydim);
-  return(0);
-}
-
-
-// ::HEADERBAR_BITMAP()
-//
-// Called to install a bitmap in the bochs headerbar (toolbar).
-//
-// bmap_id: will correspond to an ID returned from
-//     ::create_bitmap().  'alignment' is either BX_GRAVITY_LEFT
-//     or BX_GRAVITY_RIGHT, meaning install the bitmap in the next
-//     available leftmost or rightmost space.
-// alignment: is either BX_GRAVITY_LEFT or BX_GRAVITY_RIGHT,
-//     meaning install the bitmap in the next
-//     available leftmost or rightmost space.
-// f: a 'C' function pointer to callback when the mouse is clicked in
-//     the boundaries of this bitmap.
-
-  unsigned
-bx_nogui_gui_c::headerbar_bitmap(unsigned bmap_id, unsigned alignment, void (*f)(void))
-{
-  UNUSED(bmap_id);
-  UNUSED(alignment);
-  UNUSED(f);
-  return(0);
-}
-
-
-// ::SHOW_HEADERBAR()
-//
-// Show (redraw) the current headerbar, which is composed of
-// currently installed bitmaps.
-
-  void
-bx_nogui_gui_c::show_headerbar(void)
-{
-}
-
-
-// ::REPLACE_BITMAP()
-//
-// Replace the bitmap installed in the headerbar ID slot 'hbar_id',
-// with the one specified by 'bmap_id'.  'bmap_id' will have
-// been generated by ::create_bitmap().  The old and new bitmap
-// must be of the same size.  This allows the bitmap the user
-// sees to change, when some action occurs.  For example when
-// the user presses on the floppy icon, it then displays
-// the ejected status.
-//
-// hbar_id: headerbar slot ID
-// bmap_id: bitmap ID
-
-  void
-bx_nogui_gui_c::replace_bitmap(unsigned hbar_id, unsigned bmap_id)
-{
-  UNUSED(hbar_id);
-  UNUSED(bmap_id);
-}
-
-
-// ::EXIT()
-//
-// Called before bochs terminates, to allow for a graceful
-// exit from the native GUI mechanism.
-
-  void
-bx_nogui_gui_c::exit(void)
-{
-  BX_INFO(("bx_nogui_gui_c::exit() not implemented yet."));
-}
-
-  void
-bx_nogui_gui_c::mouse_enabled_changed_specific (bx_bool val)
-{
-}
diff --git a/tools/ioemu/gui/rfb.cc b/tools/ioemu/gui/rfb.cc
deleted file mode 100644 (file)
index f67f80e..0000000
+++ /dev/null
@@ -1,1508 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: rfb.cc,v 1.26.2.1 2004/02/02 22:35:30 cbothamy Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2000  Psyon.Org!
-//
-//    Donald Becker
-//    http://www.psyon.org
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-// Define BX_PLUGGABLE in files that can be compiled into plugins.  For
-// platforms that require a special tag on exported symbols, BX_PLUGGABLE 
-// is used to know when we are exporting symbols and when we are importing.
-#define BX_PLUGGABLE
-
-#include "bochs.h"
-#if BX_WITH_RFB
-
-#include "icon_bochs.h"
-#include "font/vga.bitmap.h"
-
-class bx_rfb_gui_c : public bx_gui_c {
-public:
-  bx_rfb_gui_c (void) {}
-  DECLARE_GUI_VIRTUAL_METHODS()
-};
-
-// declare one instance of the gui object and call macro to insert the
-// plugin code
-static bx_rfb_gui_c *theGui = NULL;
-IMPLEMENT_GUI_PLUGIN_CODE(rfb)
-
-#define LOG_THIS theGui->
-
-#ifdef WIN32
-
-#include <winsock.h>
-#include <process.h>
-#include "rfb.h"
-
-#else
-
-#include <sys/socket.h>
-#include <netinet/tcp.h>
-#include <netinet/in.h>
-#include <unistd.h>
-#include <sys/errno.h>
-#include <pthread.h>
-typedef unsigned long CARD32;
-typedef unsigned short CARD16;
-typedef short INT16;
-typedef unsigned char  CARD8;
-typedef int SOCKET;
-
-#endif
-
-#include "rfbproto.h"
-
-static bool keep_alive;
-static bool client_connected;
-
-#define BX_RFB_PORT_MIN 5900
-#define BX_RFB_PORT_MAX 5949
-static unsigned short rfbPort;
-
-// Headerbar stuff
-unsigned rfbBitmapCount = 0;
-struct {
-       char     *bmap;
-       unsigned xdim;
-       unsigned ydim;
-} rfbBitmaps[BX_MAX_PIXMAPS];
-
-unsigned rfbHeaderbarBitmapCount = 0;
-struct {
-       unsigned int index;
-       unsigned int xorigin;
-       unsigned int yorigin;
-       unsigned int alignment;
-       void (*f)(void);
-} rfbHeaderbarBitmaps[BX_MAX_HEADERBAR_ENTRIES];
-
-//Keyboard stuff
-#define KEYBOARD true
-#define MOUSE    false
-#define MAX_KEY_EVENTS 512
-struct {
-       bool type;
-       int  key;
-       int  down;
-       int  x;
-       int  y;
-} rfbKeyboardEvent[MAX_KEY_EVENTS];
-static unsigned long rfbKeyboardEvents = 0;
-static bool          bKeyboardInUse = false;
-
-// Misc Stuff
-struct {
-       unsigned int x;
-       unsigned int y;
-       unsigned int width;
-       unsigned int height;
-       bool updated;
-} rfbUpdateRegion;
-
-static char  *rfbScreen;
-static char  rfbPallet[256];
-
-static long  rfbDimensionX, rfbDimensionY;
-static long  rfbStretchedX, rfbStretchedY;
-static long  rfbHeaderbarY;
-static long  rfbTileX = 0;
-static long  rfbTileY = 0;
-static unsigned long  rfbCursorX = 0;
-static unsigned long  rfbCursorY = 0;
-static unsigned long  rfbOriginLeft  = 0;
-static unsigned long  rfbOriginRight = 0;
-
-static unsigned int text_rows=25, text_cols=80;
-static unsigned int font_height=16, font_width=8;
-
-//static unsigned long ServerThread   = 0;
-//static unsigned long ServerThreadID = 0;
-
-static SOCKET sGlobal;
-
-void ServerThreadInit(void *indata);
-void HandleRfbClient(SOCKET sClient);
-int  ReadExact(int sock, char *buf, int len);
-int  WriteExact(int sock, char *buf, int len);
-void DrawBitmap(int x, int y, int width, int height, char *bmap, char color, bool update_client);
-void DrawChar(int x, int y, int width, int height, int fonty, char *bmap, char color);
-void UpdateScreen(unsigned char *newBits, int x, int y, int width, int height, bool update_client);
-void SendUpdate(int x, int y, int width, int height);
-void StartThread();
-void rfbKeyPressed(Bit32u key, int press_release);
-void rfbMouseMove(int x, int y, int bmask);
-void DrawColorPallet();
-
-static const rfbPixelFormat BGR233Format = {
-    8, 8, 1, 1, 7, 7, 3, 0, 3, 6
-};
-
-// Set this for the endian of your machine. 0 = big, 1 = little 
-static const int rfbEndianTest = 1;
-
-#define Swap16(s) ((((s) & 0xff) << 8) | (((s) >> 8) & 0xff))
-#define Swap32(l) (((l) >> 24) | (((l) & 0x00ff0000) >> 8)  | (((l) & 0x0000ff00) << 8)  | ((l) << 24))
-#define Swap16IfLE(s) (*(const char *)&rfbEndianTest ? Swap16(s) : (s))
-#define Swap32IfLE(l) (*(const char *)&rfbEndianTest ? Swap32(l) : (l))
-#define PF_EQ(x,y) ((x.bitsPerPixel == y.bitsPerPixel) && (x.depth == y.depth) && (x.trueColour == y.trueColour) &&    ((x.bigEndian == y.bigEndian) || (x.bitsPerPixel == 8)) && (!x.trueColour || ((x.redMax == y.redMax) && (x.greenMax == y.greenMax) && (x.blueMax == y.blueMax) && (x.redShift == y.redShift) && (x.greenShift == y.greenShift) && (x.blueShift == y.blueShift))))
-
-// This file defines stubs for the GUI interface, which is a
-// place to start if you want to port bochs to a platform, for
-// which there is no support for your native GUI, or if you want to compile
-// bochs without any native GUI support (no output window or
-// keyboard input will be possible).
-// Look in 'x.cc', 'beos.cc', and 'win32.cc' for specific
-// implementations of this interface.  -Kevin
-
-
-// ::SPECIFIC_INIT()
-//
-// Called from gui.cc, once upon program startup, to allow for the
-// specific GUI code (X11, BeOS, ...) to be initialized.
-//
-// argc, argv: not used right now, but the intention is to pass native GUI
-//     specific options from the command line.  (X11 options, BeOS options,...)
-//
-// tilewidth, tileheight: for optimization, graphics_tile_update() passes
-//     only updated regions of the screen to the gui code to be redrawn.
-//     These define the dimensions of a region (tile).
-// headerbar_y:  A headerbar (toolbar) is display on the top of the
-//     VGA window, showing floppy status, and other information.  It
-//     always assumes the width of the current VGA mode width, but
-//     it's height is defined by this parameter.
-
-void bx_rfb_gui_c::specific_init(int argc, char **argv, unsigned tilewidth, unsigned tileheight, unsigned headerbar_y)
-{
-  unsigned char fc, vc;
-
-  put("RFB");
-  UNUSED(bochs_icon_bits);
-
-  // the ask menu doesn't work on the client side
-  io->set_log_action(LOGLEV_PANIC, ACT_FATAL);
-
-  rfbHeaderbarY = headerbar_y;
-  rfbDimensionX = 640;
-  rfbDimensionY = 480 + rfbHeaderbarY;
-  rfbStretchedX = rfbDimensionX;
-  rfbStretchedY = rfbDimensionY;
-  rfbTileX      = tilewidth;
-  rfbTileY      = tileheight;
-
-  for(int i = 0; i < 256; i++) {
-    for(int j = 0; j < 16; j++) {
-      vc = bx_vgafont[i].data[j];
-      fc = 0;
-      for (int b = 0; b < 8; b++) {
-        fc |= (vc & 0x01) << (7 - b);
-        vc >>= 1;
-      }
-      vga_charmap[i*32+j] = fc;
-    }
-  }
-
-  rfbScreen = (char *)malloc(rfbDimensionX * rfbDimensionY); 
-  memset(&rfbPallet, 0, sizeof(rfbPallet));
-  rfbPallet[63] = (char)0xFF;
-
-  rfbUpdateRegion.x = rfbDimensionX;
-  rfbUpdateRegion.y = rfbDimensionY;
-  rfbUpdateRegion.width  = 0;
-  rfbUpdateRegion.height = 0;
-  rfbUpdateRegion.updated = false;
-
-  keep_alive = true;
-  client_connected = false;
-  StartThread();
-
-#ifdef WIN32
-  Sleep(1000);
-  SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL);
-#endif
-  if (bx_options.Oprivate_colormap->get ()) {
-    BX_ERROR(( "private_colormap option ignored." ));
-  }
-  int counter = 30;
-  while ((!client_connected) && (counter--)) {
-#ifdef WIN32
-    Sleep(1000);
-#else
-    sleep(1);
-#endif
-  }
-  if (counter < 0) BX_PANIC(("timeout! no client present"));
-}
-
-bool InitWinsock()
-{
-#ifdef WIN32
-       WSADATA wsaData;
-       if(WSAStartup(MAKEWORD(1,1), &wsaData) != 0) return false;
-#endif
-       return true;
-}
-
-bool StopWinsock()
-{
-#ifdef WIN32
-       WSACleanup();
-#endif
-       return true;
-}
-
-void ServerThreadInit(void *indata) 
-{
-       SOCKET             sServer;
-       SOCKET             sClient;
-       struct sockaddr_in sai;
-       unsigned int       sai_size;
-       int port_ok = 0;
-
-#ifdef WIN32
-       SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_IDLE);
-#endif
-       if(!InitWinsock()) {
-               BX_PANIC(( "could not initialize winsock."));
-               goto end_of_thread;
-       }
-
-       sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
-       if(sServer == -1) { 
-               BX_PANIC(( "could not create socket." ));
-               goto end_of_thread;
-       }
-       for (rfbPort = BX_RFB_PORT_MIN; rfbPort <= BX_RFB_PORT_MAX; rfbPort++) {
-         sai.sin_addr.s_addr = INADDR_ANY;
-         sai.sin_family      = AF_INET;
-         sai.sin_port        = htons(rfbPort);
-         BX_INFO (("Trying port %d", rfbPort));
-         if(bind(sServer, (struct sockaddr *)&sai, sizeof(sai)) == -1) {
-                 BX_INFO(( "Could not bind socket."));
-                 continue;
-         }
-         if(listen(sServer, SOMAXCONN) == -1) {
-                 BX_INFO(( "Could not listen on socket."));
-                 continue;
-         }
-         // success
-         port_ok = 1;
-         break;
-       }
-       if (!port_ok) {
-         BX_PANIC (("RFB could not bind any port between %d and %d\n", 
-               BX_RFB_PORT_MIN,
-               BX_RFB_PORT_MAX));
-         goto end_of_thread;
-       }
-       BX_INFO (("listening for connections on port %i", rfbPort));
-       fprintf (stderr, "RFB: listening for connections on port %i\n", rfbPort);
-       sai_size = sizeof(sai);
-       while(keep_alive) {
-               sClient = accept(sServer, (struct sockaddr *)&sai, (socklen_t*)&sai_size);
-               if(sClient != -1) {
-                       HandleRfbClient(sClient);
-                       sGlobal = -1;
-                       close(sClient);
-               } else {
-                       close(sClient);
-               }
-       }
-
-end_of_thread:
-       StopWinsock();
-}
-
-void HandleRfbClient(SOCKET sClient) 
-{
-       char rfbName[] = "Bochs-RFB";
-       rfbProtocolVersionMsg pv;
-       int one = 1;
-       CARD32 auth;
-       rfbClientInitMsg cim;
-       rfbServerInitMsg sim;
-
-       client_connected = true;
-       setsockopt(sClient, IPPROTO_TCP, TCP_NODELAY, (const char *)&one, sizeof(one));
-       fprintf(stderr, "# RFB: accepted client connection.\n");
-       sprintf(pv, rfbProtocolVersionFormat, rfbProtocolMajorVersion, rfbProtocolMinorVersion);
-
-       if(WriteExact(sClient, pv, sz_rfbProtocolVersionMsg) < 0) {
-               fprintf(stderr, "# ERROR: RFB: could not send protocol version.\n");
-               return;
-       }
-       if(ReadExact(sClient, pv, sz_rfbProtocolVersionMsg) < 0) {
-               fprintf(stderr, "# ERROR: RFB: could not recieve client protocol version.\n");
-               return;
-       }
-
-       auth = Swap32IfLE(rfbNoAuth);
-       if(WriteExact(sClient, (char *)&auth, sizeof(auth)) < 0) {
-               fprintf(stderr, "# ERROR: RFB: could not send authorization method.\n");
-               return;
-       }
-
-       if(ReadExact(sClient, (char *)&cim, sz_rfbClientInitMsg) < 0) {
-               fprintf(stderr, "# ERROR: RFB: could not recieve client initialization message.\n");
-               return;
-       }
-
-       sim.framebufferWidth  = Swap16IfLE((short)rfbDimensionX);
-       sim.framebufferHeight = Swap16IfLE((short)rfbDimensionY);
-       sim.format            = BGR233Format;
-       sim.format.redMax     = Swap16IfLE(sim.format.redMax);
-       sim.format.greenMax   = Swap16IfLE(sim.format.greenMax);
-       sim.format.blueMax    = Swap16IfLE(sim.format.blueMax);
-       sim.nameLength = strlen(rfbName);
-       sim.nameLength = Swap32IfLE(sim.nameLength);
-       if(WriteExact(sClient, (char *)&sim, sz_rfbServerInitMsg) < 0) {
-               fprintf(stderr, "# ERROR: RFB: could send server initialization message.\n");
-               return;
-       }
-       if(WriteExact(sClient, rfbName, strlen(rfbName)) < 0) {
-               fprintf(stderr, "# ERROR: RFB: could not send server name.\n");
-               return;
-       }
-
-       sGlobal = sClient;
-       while(keep_alive) {
-               CARD8 msgType;
-               int n;
-
-               if((n = recv(sClient, (char *)&msgType, 1, MSG_PEEK)) <= 0) {
-                       if(n == 0) {
-                               fprintf(stderr, "# RFB: client closed connection.\n");
-                       } else {
-                               fprintf(stderr, "# RFB: error recieving data.\n");
-                       }
-                       return;
-               }
-               
-               switch(msgType) {
-               case rfbSetPixelFormat:
-                       {
-                               rfbSetPixelFormatMsg spf;
-                               ReadExact(sClient, (char *)&spf, sizeof(rfbSetPixelFormatMsg));
-
-                               spf.format.bitsPerPixel = spf.format.bitsPerPixel;
-                               spf.format.depth = spf.format.depth;
-                               spf.format.trueColour = (spf.format.trueColour ? 1 : 0);
-                               spf.format.bigEndian = (spf.format.bigEndian ? 1 : 0);
-                               spf.format.redMax = Swap16IfLE(spf.format.redMax);
-                               spf.format.greenMax = Swap16IfLE(spf.format.greenMax);
-                               spf.format.blueMax = Swap16IfLE(spf.format.blueMax);
-                               spf.format.redShift = spf.format.redShift;
-                               spf.format.greenShift = spf.format.greenShift;
-                               spf.format.blueShift = spf.format.blueShift;
-                               
-                               if (!PF_EQ(spf.format, BGR233Format)) {
-                                       fprintf(stderr,"# ERROR: RFB: client has wrong pixel format\n");
-                                       //return;
-                               }
-                               break;
-                       }
-               case rfbFixColourMapEntries:
-                       {
-                               rfbFixColourMapEntriesMsg fcme;
-                               ReadExact(sClient, (char *)&fcme, sizeof(rfbFixColourMapEntriesMsg));
-                               break;
-                       }
-               case rfbSetEncodings:
-                       {
-                               rfbSetEncodingsMsg se;
-                               int                i;
-                               CARD32             enc;
-                               ReadExact(sClient, (char *)&se, sizeof(rfbSetEncodingsMsg));
-                               se.nEncodings = Swap16IfLE(se.nEncodings);
-                               for(i = 0; i < se.nEncodings; i++) {
-                                       if((n = ReadExact(sClient, (char *)&enc, sizeof(CARD32))) <= 0) {
-                                               if(n == 0) {
-                                                       fprintf(stderr, "# RFB: client closed connection.\n");
-                                               } else {
-                                                       fprintf(stderr, "# RFB: error recieving data.\n");
-                                               }
-                                               return;
-                                       }
-                               }
-                               break;
-                       }
-               case rfbFramebufferUpdateRequest:
-                       {
-                               rfbFramebufferUpdateRequestMsg fur;
-
-                               ReadExact(sClient, (char *)&fur, sizeof(rfbFramebufferUpdateRequestMsg));
-                               if(!fur.incremental) {
-                                       rfbUpdateRegion.x = 0;
-                                       rfbUpdateRegion.y = 0;
-                                       rfbUpdateRegion.width  = rfbDimensionX;
-                                       rfbUpdateRegion.height = rfbDimensionY;
-                                       rfbUpdateRegion.updated = true;
-                               } //else {
-                               //      if(fur.x < rfbUpdateRegion.x) rfbUpdateRegion.x = fur.x;
-                               //      if(fur.y < rfbUpdateRegion.x) rfbUpdateRegion.y = fur.y;
-                               //      if(((fur.x + fur.w) - rfbUpdateRegion.x) > rfbUpdateRegion.width) rfbUpdateRegion.width = ((fur.x + fur.w) - rfbUpdateRegion.x);
-                               //      if(((fur.y + fur.h) - rfbUpdateRegion.y) > rfbUpdateRegion.height) rfbUpdateRegion.height = ((fur.y + fur.h) - rfbUpdateRegion.y);
-                               //}
-                               //rfbUpdateRegion.updated = true;
-                               break;
-                       }
-               case rfbKeyEvent:
-                       {
-                               rfbKeyEventMsg ke;
-                               ReadExact(sClient, (char *)&ke, sizeof(rfbKeyEventMsg));
-                               ke.key = Swap32IfLE(ke.key);
-                               while(bKeyboardInUse);
-                               bKeyboardInUse = true;
-                               if (rfbKeyboardEvents >= MAX_KEY_EVENTS) break;
-                               rfbKeyboardEvent[rfbKeyboardEvents].type = KEYBOARD;
-                               rfbKeyboardEvent[rfbKeyboardEvents].key  = ke.key;
-                               rfbKeyboardEvent[rfbKeyboardEvents].down = ke.down;
-                               rfbKeyboardEvents++;
-                               bKeyboardInUse = false;
-                               break;
-                       }
-               case rfbPointerEvent:
-                       {       
-                               rfbPointerEventMsg pe;
-                               ReadExact(sClient, (char *)&pe, sizeof(rfbPointerEventMsg));
-                               while(bKeyboardInUse);
-                               bKeyboardInUse = true;
-                               if (rfbKeyboardEvents >= MAX_KEY_EVENTS) break;
-                               rfbKeyboardEvent[rfbKeyboardEvents].type = MOUSE;
-                               rfbKeyboardEvent[rfbKeyboardEvents].x    = Swap16IfLE(pe.x);
-                               rfbKeyboardEvent[rfbKeyboardEvents].y    = Swap16IfLE(pe.y);
-                               rfbKeyboardEvent[rfbKeyboardEvents].down = pe.buttonMask;
-                               rfbKeyboardEvents++;
-                               bKeyboardInUse = false;
-                               break;
-                       }
-               case rfbClientCutText:
-                       {
-                               rfbClientCutTextMsg cct;
-                               ReadExact(sClient, (char *)&cct, sizeof(rfbClientCutTextMsg));
-                               break;
-                       }
-               }
-       }
-}
-// ::HANDLE_EVENTS()
-//
-// Called periodically (vga_update_interval in .bochsrc) so the
-// the gui code can poll for keyboard, mouse, and other
-// relevant events.
-
-void bx_rfb_gui_c::handle_events(void)
-{
-       unsigned int i = 0;
-       while(bKeyboardInUse);
-       bKeyboardInUse = true;
-       if(rfbKeyboardEvents > 0) {
-               for(i = 0; i < rfbKeyboardEvents; i++) {
-                       if(rfbKeyboardEvent[i].type == KEYBOARD) {
-                               rfbKeyPressed(rfbKeyboardEvent[i].key, rfbKeyboardEvent[i].down);
-                       } else { //type == MOUSE;
-                               rfbMouseMove(rfbKeyboardEvent[i].x, rfbKeyboardEvent[i].y, rfbKeyboardEvent[i].down);
-                       }
-               }
-               rfbKeyboardEvents = 0;
-       }
-       bKeyboardInUse = false;
-
-       if(rfbUpdateRegion.updated) {
-               SendUpdate(rfbUpdateRegion.x, rfbUpdateRegion.y, rfbUpdateRegion.width, rfbUpdateRegion.height);
-               rfbUpdateRegion.x = rfbDimensionX;
-               rfbUpdateRegion.y = rfbDimensionY;
-               rfbUpdateRegion.width  = 0;
-               rfbUpdateRegion.height = 0;
-       }
-       rfbUpdateRegion.updated = false;
-}
-
-
-// ::FLUSH()
-//
-// Called periodically, requesting that the gui code flush all pending
-// screen update requests.
-
-void bx_rfb_gui_c::flush(void)
-{
-}
-
-
-// ::CLEAR_SCREEN()
-//
-// Called to request that the VGA region is cleared.  Don't
-// clear the area that defines the headerbar.
-void bx_rfb_gui_c::clear_screen(void)
-{
-       memset(&rfbScreen[rfbDimensionX * rfbHeaderbarY], 0, rfbDimensionX * (rfbDimensionY - rfbHeaderbarY));
-}
-
-
-
-// ::TEXT_UPDATE()
-//
-// Called in a VGA text mode, to update the screen with
-// new content.
-//
-// old_text: array of character/attributes making up the contents
-//           of the screen from the last call.  See below
-// new_text: array of character/attributes making up the current
-//           contents, which should now be displayed.  See below
-//
-// format of old_text & new_text: each is 4000 bytes long.
-//     This represents 80 characters wide by 25 high, with
-//     each character being 2 bytes.  The first by is the
-//     character value, the second is the attribute byte.
-//     I currently don't handle the attribute byte.
-//
-// cursor_x: new x location of cursor
-// cursor_y: new y location of cursor
-
-void bx_rfb_gui_c::text_update(Bit8u *old_text, Bit8u *new_text, unsigned long cursor_x, unsigned long cursor_y, bx_vga_tminfo_t tm_info, unsigned nrows)
-{
-  unsigned char *old_line, *new_line;
-  unsigned char cAttr, cChar;
-  unsigned int  curs, hchars, offset, rows, x, y, xc, yc;
-  bx_bool force_update=0;
-
-  UNUSED(nrows);
-
-  if(charmap_updated) {
-    force_update = 1;
-    charmap_updated = 0;
-  }
-
-  // first invalidate character at previous and new cursor location
-  if ( (rfbCursorY < text_rows) && (rfbCursorX < text_cols) ) {
-    curs = rfbCursorY * tm_info.line_offset + rfbCursorX * 2;
-    old_text[curs] = ~new_text[curs];
-  }
-  if((tm_info.cs_start <= tm_info.cs_end) && (tm_info.cs_start < font_height) &&
-     (cursor_y < text_rows) && (cursor_x < text_cols)) {
-    curs = cursor_y * tm_info.line_offset + cursor_x * 2;
-    old_text[curs] = ~new_text[curs];
-  } else {
-    curs = 0xffff;
-  }
-
-  rows = text_rows;
-  y = 0;
-  do {
-    hchars = text_cols;
-    new_line = new_text;
-    old_line = old_text;
-    offset = y * tm_info.line_offset;
-    yc = y * font_height + rfbHeaderbarY;
-    x = 0;
-    do {
-      if (force_update || (old_text[0] != new_text[0])
-          || (old_text[1] != new_text[1])) {
-        cChar = new_text[0];
-        cAttr = new_text[1];
-        xc = x * 8;
-        DrawChar(xc, yc, 8, font_height, 0, (char *)&vga_charmap[cChar<<5], cAttr);
-        if(yc < rfbUpdateRegion.y) rfbUpdateRegion.y = yc;
-        if((yc + font_height - rfbUpdateRegion.y) > rfbUpdateRegion.height) rfbUpdateRegion.height = (yc + font_height - rfbUpdateRegion.y);
-        if(xc < rfbUpdateRegion.x) rfbUpdateRegion.x = xc;
-        if((xc + 8 - rfbUpdateRegion.x) > rfbUpdateRegion.width) rfbUpdateRegion.width = (xc + 8 - rfbUpdateRegion.x);
-        rfbUpdateRegion.updated = true;
-       if (offset == curs) {
-          cAttr = ((cAttr >> 4) & 0xF) + ((cAttr & 0xF) << 4);
-          DrawChar(xc, yc + tm_info.cs_start, 8, tm_info.cs_end - tm_info.cs_start + 1,
-                   tm_info.cs_start, (char *)&vga_charmap[cChar<<5], cAttr);
-        }
-      }
-      x++;
-      new_text+=2;
-      old_text+=2;
-      offset+=2;
-    } while (--hchars);
-    y++;
-    new_text = new_line + tm_info.line_offset;
-    old_text = old_line + tm_info.line_offset;
-  } while (--rows);
-
-  rfbCursorX = cursor_x;
-  rfbCursorY = cursor_y;
-}
-
-  int
-bx_rfb_gui_c::get_clipboard_text(Bit8u **bytes, Bit32s *nbytes)
-{
-  return 0;
-}
-
-  int
-bx_rfb_gui_c::set_clipboard_text(char *text_snapshot, Bit32u len)
-{
-  return 0;
-}
-
-
-// ::PALETTE_CHANGE()
-//
-// Allocate a color in the native GUI, for this color, and put
-// it in the colormap location 'index'.
-// returns: 0=no screen update needed (color map change has direct effect)
-//          1=screen updated needed (redraw using current colormap)
-
-bx_bool bx_rfb_gui_c::palette_change(unsigned index, unsigned red, unsigned green, unsigned blue)
-{
-       rfbPallet[index] = (((red * 7 + 127) / 255) << 0) | (((green * 7 + 127) / 255) << 3) | (((blue * 3 + 127) / 255) << 6);
-       return(1);
-}
-
-
-// ::GRAPHICS_TILE_UPDATE()
-//
-// Called to request that a tile of graphics be drawn to the
-// screen, since info in this region has changed.
-//
-// tile: array of 8bit values representing a block of pixels with
-//       dimension equal to the 'tilewidth' & 'tileheight' parameters to
-//       ::specific_init().  Each value specifies an index into the
-//       array of colors you allocated for ::palette_change()
-// x0: x origin of tile
-// y0: y origin of tile
-//
-// note: origin of tile and of window based on (0,0) being in the upper
-//       left of the window.
-void bx_rfb_gui_c::graphics_tile_update(Bit8u *tile, unsigned x0, unsigned y0)
-{
-       UpdateScreen(tile, x0, y0 + rfbHeaderbarY, rfbTileX, rfbTileY, false);
-       if(x0 < rfbUpdateRegion.x) rfbUpdateRegion.x = x0;
-       if((y0 + rfbHeaderbarY) < rfbUpdateRegion.y) rfbUpdateRegion.y = y0 + rfbHeaderbarY;
-       if(((y0 + rfbHeaderbarY + rfbTileY) - rfbUpdateRegion.y) > rfbUpdateRegion.height) rfbUpdateRegion.height =  ((y0 + rfbHeaderbarY + rfbTileY) - rfbUpdateRegion.y);
-       if(((x0 + rfbTileX) - rfbUpdateRegion.x) > rfbUpdateRegion.width) rfbUpdateRegion.width = ((x0 + rfbTileX) - rfbUpdateRegion.x);
-       rfbUpdateRegion.updated = true;
-}
-
-
-
-// ::DIMENSION_UPDATE()
-//
-// Called when the VGA mode changes it's X,Y dimensions.
-// Resize the window to this size, but you need to add on
-// the height of the headerbar to the Y value.
-//
-// x: new VGA x size
-// y: new VGA y size (add headerbar_y parameter from ::specific_init().
-// fheight: new VGA character height in text mode
-// fwidth : new VGA character width in text mode
-// bpp : bits per pixel in graphics mode
-
-  void
-bx_rfb_gui_c::dimension_update(unsigned x, unsigned y, unsigned fheight, unsigned fwidth, unsigned bpp)
-{
-  if (bpp > 8) {
-    BX_PANIC(("%d bpp graphics mode not supported yet", bpp));
-  }
-  if (fheight > 0) {
-    font_height = fheight;
-    font_width = fwidth;
-    text_cols = x / fwidth;
-    text_rows = y / fheight;
-  } else {
-    if ((x > 640) || (y > 480)) {
-      BX_PANIC(("dimension_update(): RFB doesn't support graphics modes > 640x480 (%dx%d)", x, y));
-    }
-  }
-}
-
-
-// ::CREATE_BITMAP()
-//
-// Create a monochrome bitmap of size 'xdim' by 'ydim', which will
-// be drawn in the headerbar.  Return an integer ID to the bitmap,
-// with which the bitmap can be referenced later.
-//
-// bmap: packed 8 pixels-per-byte bitmap.  The pixel order is:
-//       bit0 is the left most pixel, bit7 is the right most pixel.
-// xdim: x dimension of bitmap
-// ydim: y dimension of bitmap
-
-unsigned bx_rfb_gui_c::create_bitmap(const unsigned char *bmap, unsigned xdim, unsigned ydim)
-{
-       if(rfbBitmapCount >= BX_MAX_PIXMAPS) {
-               fprintf(stderr, "# RFB: too many pixmaps.\n");
-               return 0;
-       }
-       rfbBitmaps[rfbBitmapCount].bmap = (char *)malloc((xdim * ydim) / 8);
-       rfbBitmaps[rfbBitmapCount].xdim = xdim;
-       rfbBitmaps[rfbBitmapCount].ydim = ydim;
-       memcpy(rfbBitmaps[rfbBitmapCount].bmap, bmap, (xdim * ydim) / 8);
-       
-       rfbBitmapCount++;
-       return(rfbBitmapCount - 1);
-}
-
-
-// ::HEADERBAR_BITMAP()
-//
-// Called to install a bitmap in the bochs headerbar (toolbar).
-//
-// bmap_id: will correspond to an ID returned from
-//     ::create_bitmap().  'alignment' is either BX_GRAVITY_LEFT
-//     or BX_GRAVITY_RIGHT, meaning install the bitmap in the next
-//     available leftmost or rightmost space.
-// alignment: is either BX_GRAVITY_LEFT or BX_GRAVITY_RIGHT,
-//     meaning install the bitmap in the next
-//     available leftmost or rightmost space.
-// f: a 'C' function pointer to callback when the mouse is clicked in
-//     the boundaries of this bitmap.
-
-unsigned bx_rfb_gui_c::headerbar_bitmap(unsigned bmap_id, unsigned alignment, void (*f)(void))
-{
-       int hb_index;
-
-       if((rfbHeaderbarBitmapCount + 1) > BX_MAX_HEADERBAR_ENTRIES) {
-               return 0;
-       }
-
-       rfbHeaderbarBitmapCount++;
-       hb_index = rfbHeaderbarBitmapCount - 1;
-       rfbHeaderbarBitmaps[hb_index].index     = bmap_id;
-       rfbHeaderbarBitmaps[hb_index].alignment = alignment;
-       rfbHeaderbarBitmaps[hb_index].f = f;
-       if (alignment == BX_GRAVITY_LEFT) {
-               rfbHeaderbarBitmaps[hb_index].xorigin = rfbOriginLeft;
-               rfbHeaderbarBitmaps[hb_index].yorigin = 0;
-               rfbOriginLeft += rfbBitmaps[bmap_id].xdim;
-       } else { // BX_GRAVITY_RIGHT
-               rfbOriginRight += rfbBitmaps[bmap_id].xdim;
-               rfbHeaderbarBitmaps[hb_index].xorigin = rfbOriginRight;
-               rfbHeaderbarBitmaps[hb_index].yorigin = 0;
-       }
-       return hb_index;
-}
-
-
-// ::SHOW_HEADERBAR()
-//
-// Show (redraw) the current headerbar, which is composed of
-// currently installed bitmaps.
-
-void bx_rfb_gui_c::show_headerbar(void)
-{
-  char *newBits;
-  unsigned int i, xorigin;
-
-  newBits = (char *)malloc(rfbDimensionX * rfbHeaderbarY);
-  memset(newBits, 0, (rfbDimensionX * rfbHeaderbarY));
-  DrawBitmap(0, 0, rfbDimensionX, rfbHeaderbarY, newBits, (char)0xf0, false);
-  for(i = 0; i < rfbHeaderbarBitmapCount; i++) {
-    if(rfbHeaderbarBitmaps[i].alignment == BX_GRAVITY_LEFT) {
-      xorigin = rfbHeaderbarBitmaps[i].xorigin;
-    } else {
-      xorigin = rfbDimensionX - rfbHeaderbarBitmaps[i].xorigin;
-    }
-    DrawBitmap(xorigin, 0, rfbBitmaps[rfbHeaderbarBitmaps[i].index].xdim, rfbBitmaps[rfbHeaderbarBitmaps[i].index].ydim, rfbBitmaps[rfbHeaderbarBitmaps[i].index].bmap, (char)0xf0, false);
-  }
-  free(newBits);
-}
-
-
-// ::REPLACE_BITMAP()
-//
-// Replace the bitmap installed in the headerbar ID slot 'hbar_id',
-// with the one specified by 'bmap_id'.  'bmap_id' will have
-// been generated by ::create_bitmap().  The old and new bitmap
-// must be of the same size.  This allows the bitmap the user
-// sees to change, when some action occurs.  For example when
-// the user presses on the floppy icon, it then displays
-// the ejected status.
-//
-// hbar_id: headerbar slot ID
-// bmap_id: bitmap ID
-
-void bx_rfb_gui_c::replace_bitmap(unsigned hbar_id, unsigned bmap_id)
-{
-       rfbHeaderbarBitmaps[hbar_id].index = bmap_id;
-}
-
-
-// ::EXIT()
-//
-// Called before bochs terminates, to allow for a graceful
-// exit from the native GUI mechanism.
-void bx_rfb_gui_c::exit(void)
-{
-       unsigned int i;
-       keep_alive = false;
-       StopWinsock();
-       free(rfbScreen);
-       for(i = 0; i < rfbBitmapCount; i++) {
-               free(rfbBitmaps[i].bmap);
-       }
-       fprintf(stderr, "# RFB: bx_rfb_gui_c::exit()\n");
-}
-
-/*
-* ReadExact reads an exact number of bytes on a TCP socket.  Returns 1 if
-* those bytes have been read, 0 if the other end has closed, or -1 if an error
-* occurred (errno is set to ETIMEDOUT if it timed out).
-*/
-
-int ReadExact(int sock, char *buf, int len)
-{
-    int n;
-    while (len > 0) {
-       n = recv(sock, buf, len, 0);
-       if (n > 0) {
-           buf += n;
-           len -= n;
-        } else {
-            return n;
-       }
-    }
-    return 1;
-}
-
-/*
-* WriteExact writes an exact number of bytes on a TCP socket.  Returns 1 if
-* those bytes have been written, or -1 if an error occurred (errno is set to
-* ETIMEDOUT if it timed out).
-*/
-
-int WriteExact(int sock, char *buf, int len)
-{
-    int n;
-       
-    while (len > 0) {
-       n = send(sock, buf, len,0);
-               
-       if (n > 0) {
-           buf += n;
-           len -= n;
-       } else if (n == 0) {
-           fprintf(stderr,"WriteExact: write returned 0?\n");
-           return n;
-        } else {
-            return n;
-       }
-    }
-    return 1;
-}
-
-void DrawBitmap(int x, int y, int width, int height, char *bmap, char color, bool update_client)
-{
-       int  i;
-       unsigned char *newBits;
-       char fgcolor, bgcolor;
-       char vgaPallet[] = { (char)0x00, //Black 
-                                                (char)0x01, //Dark Blue
-                                                (char)0x02, //Dark Green
-                                                (char)0x03, //Dark Cyan
-                                                (char)0x04, //Dark Red
-                                                (char)0x05, //Dark Magenta
-                                                (char)0x06, //Brown
-                                                (char)0x07, //Light Gray
-                                                (char)0x38, //Dark Gray
-                                                (char)0x09, //Light Blue
-                                                (char)0x12, //Green
-                                                (char)0x1B, //Cyan
-                                                (char)0x24, //Light Red
-                                                (char)0x2D, //Magenta
-                                                (char)0x36, //Yellow
-                                                (char)0x3F  //White
-                                               };
-
-       bgcolor = vgaPallet[(color >> 4) & 0xF];
-       fgcolor = vgaPallet[color & 0xF];
-       newBits = (unsigned char *)malloc(width * height);
-       memset(newBits, 0, (width * height));
-       for(i = 0; i < (width * height) / 8; i++) {
-               newBits[i * 8 + 0] = (bmap[i] & 0x01) ? fgcolor : bgcolor;
-               newBits[i * 8 + 1] = (bmap[i] & 0x02) ? fgcolor : bgcolor;
-               newBits[i * 8 + 2] = (bmap[i] & 0x04) ? fgcolor : bgcolor;
-               newBits[i * 8 + 3] = (bmap[i] & 0x08) ? fgcolor : bgcolor;
-               newBits[i * 8 + 4] = (bmap[i] & 0x10) ? fgcolor : bgcolor;
-               newBits[i * 8 + 5] = (bmap[i] & 0x20) ? fgcolor : bgcolor;
-               newBits[i * 8 + 6] = (bmap[i] & 0x40) ? fgcolor : bgcolor;
-               newBits[i * 8 + 7] = (bmap[i] & 0x80) ? fgcolor : bgcolor;
-       }
-       UpdateScreen(newBits, x, y, width, height, update_client);
-       //DrawColorPallet();
-       free(newBits);
-}
-
-void DrawChar(int x, int y, int width, int height, int fonty, char *bmap, char color)
-{
-  static unsigned char newBits[8 * 32];
-  unsigned char mask;
-  int bytes = width * height;
-  char fgcolor, bgcolor;
-  char vgaPallet[] = { (char)0x00, //Black
-                       (char)0x01, //Dark Blue
-                       (char)0x02, //Dark Green
-                       (char)0x03, //Dark Cyan
-                       (char)0x04, //Dark Red
-                       (char)0x05, //Dark Magenta
-                       (char)0x06, //Brown
-                       (char)0x07, //Light Gray
-                       (char)0x38, //Dark Gray
-                       (char)0x09, //Light Blue
-                       (char)0x12, //Green
-                       (char)0x1B, //Cyan
-                       (char)0x24, //Light Red
-                       (char)0x2D, //Magenta
-                       (char)0x36, //Yellow
-                       (char)0x3F  //White
-                     };
-
-  bgcolor = vgaPallet[(color >> 4) & 0xF];
-  fgcolor = vgaPallet[color & 0xF];
-
-  for(int i = 0; i < bytes; i+=width) {
-    mask = 0x80;
-    for(int j = 0; j < width; j++) {
-      newBits[i + j] = (bmap[fonty] & mask) ? fgcolor : bgcolor;
-      mask >>= 1;
-    }
-    fonty++;
-  }
-  UpdateScreen(newBits, x, y, width, height, false);
-  //DrawColorPallet();
-}
-
-void DrawColorPallet()
-{
-       unsigned char bits[100];
-       int x = 0, y = 0, c;
-       for(c = 0; c < 256; c++) {
-               memset(&bits, rfbPallet[c], 100);
-               UpdateScreen(bits, x, y, 10, 10, false);
-               x += 10;
-               if(x > 70) {
-                       y += 10;
-                       x = 0;
-               }
-       }
-}
-
-void UpdateScreen(unsigned char *newBits, int x, int y, int width, int height, bool update_client)
-{
-       int i, c;
-       for(i = 0; i < height; i++) {
-               for(c = 0; c < width; c++) {
-                       newBits[(i * width) + c] = rfbPallet[newBits[(i * width) + c]];
-               }
-               memcpy(&rfbScreen[y * rfbDimensionX + x], &newBits[i * width], width);
-               y++;
-       }
-       if(update_client) {
-               if(sGlobal == -1) return;
-               rfbFramebufferUpdateMsg fum;
-               rfbFramebufferUpdateRectHeader furh;
-               fum.type = rfbFramebufferUpdate;
-               fum.nRects = Swap16IfLE(1);
-               WriteExact(sGlobal, (char *)&fum, sz_rfbFramebufferUpdateMsg);
-               furh.r.x = Swap16IfLE(x);
-               furh.r.y = Swap16IfLE((y - i));
-               furh.r.w = Swap16IfLE((short)width);
-               furh.r.h = Swap16IfLE((short)height);
-               furh.encoding = Swap32IfLE(rfbEncodingRaw);
-               WriteExact(sGlobal, (char *)&furh, sz_rfbFramebufferUpdateRectHeader);
-               WriteExact(sGlobal, (char *)newBits, width * height);
-       }
-}
-
-void SendUpdate(int x, int y, int width, int height)
-{
-       char *newBits;
-       int  i;
-
-       if(x < 0 || y < 0 || (x + width) > rfbDimensionX || (y + height) > rfbDimensionY) {
-               fprintf(stderr, "# RFB: Dimensions out of bounds.  x=%i y=%i w=%i h=%i\n", x, y, width, height);
-       }
-       if(sGlobal != -1) {
-               rfbFramebufferUpdateMsg fum;
-               rfbFramebufferUpdateRectHeader furh;
-
-               fum.type = rfbFramebufferUpdate;
-               fum.nRects = Swap16IfLE(1);
-
-               furh.r.x = Swap16IfLE(x);
-               furh.r.y = Swap16IfLE(y);
-               furh.r.w = Swap16IfLE((short)width);
-               furh.r.h = Swap16IfLE((short)height);
-               furh.encoding = Swap32IfLE(rfbEncodingRaw);
-
-               newBits = (char *)malloc(width * height);
-               for(i = 0; i < height; i++) {
-                       memcpy(&newBits[i * width], &rfbScreen[y * rfbDimensionX + x], width);
-                       y++;
-               }
-
-               WriteExact(sGlobal, (char *)&fum, sz_rfbFramebufferUpdateMsg);
-               WriteExact(sGlobal, (char *)&furh, sz_rfbFramebufferUpdateRectHeader);
-               WriteExact(sGlobal, (char *)newBits, width * height);
-
-               free(newBits);
-       }
-}
-
-void StartThread()
-{
-#ifdef WIN32
-       _beginthread(ServerThreadInit, 0, NULL);
-#else
-       pthread_t      thread;
-       pthread_create(&thread, NULL, (void *(*)(void *))&ServerThreadInit, NULL);
-#endif
-}
-
-/***********************/
-/* Keyboard Definitons */
-/*        And          */
-/*     Functions       */
-/***********************/
-
-#define XK_space            0x020
-#define XK_asciitilde       0x07e
-
-#define XK_dead_grave       0xFE50
-#define XK_dead_acute       0xFE51
-#define XK_dead_circumflex  0xFE52
-#define XK_dead_tilde       0xFE53
-
-#define XK_BackSpace           0xFF08  
-#define XK_Tab                     0xFF09
-#define XK_Linefeed                0xFF0A
-#define XK_Clear                   0xFF0B
-#define XK_Return                  0xFF0D
-#define XK_Pause                   0xFF13      
-#define XK_Scroll_Lock         0xFF14
-#define XK_Sys_Req                 0xFF15
-#define XK_Escape                  0xFF1B
-
-#define XK_Delete                  0xFFFF
-
-#define XK_Home                        0xFF50
-#define XK_Left                        0xFF51  
-#define XK_Up                  0xFF52  
-#define XK_Right               0xFF53
-#define XK_Down                        0xFF54
-#define XK_Page_Up             0xFF55
-#define XK_Page_Down   0xFF56
-#define XK_End                 0xFF57  
-#define XK_Begin               0xFF58  
-
-#define XK_Select              0xFF60  
-#define XK_Print               0xFF61
-#define XK_Execute             0xFF62  
-#define XK_Insert              0xFF63  
-
-#define XK_Cancel              0xFF69  
-#define XK_Help                        0xFF6A
-#define XK_Break               0xFF6B
-#define XK_Num_Lock            0xFF7F
-
-#define XK_KP_Space            0xFF80
-#define XK_KP_Tab              0xFF89
-#define XK_KP_Enter            0xFF8D  
-
-#define XK_KP_Home             0xFF95
-#define XK_KP_Left             0xFF96
-#define XK_KP_Up               0xFF97
-#define XK_KP_Right            0xFF98
-#define XK_KP_Down             0xFF99
-#define XK_KP_Prior            0xFF9A
-#define XK_KP_Page_Up  0xFF9A
-#define XK_KP_Next             0xFF9B
-#define XK_KP_Page_Down        0xFF9B
-#define XK_KP_End              0xFF9C
-#define XK_KP_Begin            0xFF9D
-#define XK_KP_Insert   0xFF9E
-#define XK_KP_Delete   0xFF9F
-#define XK_KP_Equal            0xFFBD
-#define XK_KP_Multiply 0xFFAA
-#define XK_KP_Add              0xFFAB
-#define XK_KP_Separator        0xFFAC  
-#define XK_KP_Subtract 0xFFAD
-#define XK_KP_Decimal  0xFFAE
-#define XK_KP_Divide   0xFFAF
-
-#define XK_KP_F1               0xFF91
-#define XK_KP_F2               0xFF92
-#define XK_KP_F3               0xFF93
-#define XK_KP_F4               0xFF94
-
-#define XK_KP_0                        0xFFB0
-#define XK_KP_1                        0xFFB1
-#define XK_KP_2                        0xFFB2
-#define XK_KP_3                        0xFFB3
-#define XK_KP_4                        0xFFB4
-#define XK_KP_5                        0xFFB5
-#define XK_KP_6                        0xFFB6
-#define XK_KP_7                        0xFFB7
-#define XK_KP_8                        0xFFB8
-#define XK_KP_9                        0xFFB9
-
-#define XK_F1                  0xFFBE
-#define XK_F2                  0xFFBF
-#define XK_F3                  0xFFC0
-#define XK_F4                  0xFFC1
-#define XK_F5                  0xFFC2
-#define XK_F6                  0xFFC3
-#define XK_F7                  0xFFC4
-#define XK_F8                  0xFFC5
-#define XK_F9                  0xFFC6
-#define XK_F10                 0xFFC7
-#define XK_F11                 0xFFC8
-#define XK_F12                 0xFFC9
-#define XK_F13                 0xFFCA
-#define XK_F14                 0xFFCB
-#define XK_F15                 0xFFCC
-#define XK_F16                 0xFFCD
-#define XK_F17                 0xFFCE
-#define XK_F18                 0xFFCF
-#define XK_F19                 0xFFD0
-#define XK_F20                 0xFFD1
-#define XK_F21                 0xFFD2
-#define XK_F22                 0xFFD3
-#define XK_F23                 0xFFD4
-#define XK_F24                 0xFFD5
-
-
-#define XK_Shift_L             0xFFE1  
-#define XK_Shift_R             0xFFE2  
-#define XK_Control_L   0xFFE3  
-#define XK_Control_R   0xFFE4  
-#define XK_Caps_Lock   0xFFE5  
-#define XK_Shift_Lock  0xFFE6  
-#define XK_Meta_L              0xFFE7  
-#define XK_Meta_R              0xFFE8
-#define XK_Alt_L               0xFFE9
-#define XK_Alt_R               0xFFEA
-
-Bit32u rfb_ascii_to_key_event[0x5f] = {
-  //  !"#$%&'
-  BX_KEY_SPACE,
-  BX_KEY_1,
-  BX_KEY_SINGLE_QUOTE,
-  BX_KEY_3,
-  BX_KEY_4,
-  BX_KEY_5,
-  BX_KEY_7,
-  BX_KEY_SINGLE_QUOTE,
-
-  // ()*+,-./
-  BX_KEY_9,
-  BX_KEY_0,
-  BX_KEY_8,
-  BX_KEY_EQUALS,
-  BX_KEY_COMMA,
-  BX_KEY_MINUS,
-  BX_KEY_PERIOD,
-  BX_KEY_SLASH,
-
-  // 01234567
-  BX_KEY_0,
-  BX_KEY_1,
-  BX_KEY_2,
-  BX_KEY_3,
-  BX_KEY_4,
-  BX_KEY_5,
-  BX_KEY_6,
-  BX_KEY_7,
-
-  // 89:;<=>?
-  BX_KEY_8,
-  BX_KEY_9,
-  BX_KEY_SEMICOLON,
-  BX_KEY_SEMICOLON,
-  BX_KEY_COMMA,
-  BX_KEY_EQUALS,
-  BX_KEY_PERIOD,
-  BX_KEY_SLASH,
-
-  // @ABCDEFG
-  BX_KEY_2,
-  BX_KEY_A,
-  BX_KEY_B,
-  BX_KEY_C,
-  BX_KEY_D,
-  BX_KEY_E,
-  BX_KEY_F,
-  BX_KEY_G,
-
-
-  // HIJKLMNO
-  BX_KEY_H,
-  BX_KEY_I,
-  BX_KEY_J,
-  BX_KEY_K,
-  BX_KEY_L,
-  BX_KEY_M,
-  BX_KEY_N,
-  BX_KEY_O,
-
-
-  // PQRSTUVW
-  BX_KEY_P,
-  BX_KEY_Q,
-  BX_KEY_R,
-  BX_KEY_S,
-  BX_KEY_T,
-  BX_KEY_U,
-  BX_KEY_V,
-  BX_KEY_W,
-
-  // XYZ[\]^_
-  BX_KEY_X,
-  BX_KEY_Y,
-  BX_KEY_Z,
-  BX_KEY_LEFT_BRACKET,
-  BX_KEY_BACKSLASH,
-  BX_KEY_RIGHT_BRACKET,
-  BX_KEY_6,
-  BX_KEY_MINUS,
-
-  // `abcdefg
-  BX_KEY_GRAVE,
-  BX_KEY_A,
-  BX_KEY_B,
-  BX_KEY_C,
-  BX_KEY_D,
-  BX_KEY_E,
-  BX_KEY_F,
-  BX_KEY_G,
-
-  // hijklmno
-  BX_KEY_H,
-  BX_KEY_I,
-  BX_KEY_J,
-  BX_KEY_K,
-  BX_KEY_L,
-  BX_KEY_M,
-  BX_KEY_N,
-  BX_KEY_O,
-
-  // pqrstuvw
-  BX_KEY_P,
-  BX_KEY_Q,
-  BX_KEY_R,
-  BX_KEY_S,
-  BX_KEY_T,
-  BX_KEY_U,
-  BX_KEY_V,
-  BX_KEY_W,
-
-  // xyz{|}~
-  BX_KEY_X,
-  BX_KEY_Y,
-  BX_KEY_Z,
-  BX_KEY_LEFT_BRACKET,
-  BX_KEY_BACKSLASH,
-  BX_KEY_RIGHT_BRACKET,
-  BX_KEY_GRAVE
-  };
-
-void rfbKeyPressed(Bit32u key, int press_release)
-{
-  Bit32u key_event;
-
-  if((key >= XK_space) && (key <= XK_asciitilde)) {
-    key_event = rfb_ascii_to_key_event[key - XK_space];
-  } else {
-    switch (key) {
-      case XK_KP_1:
-#ifdef XK_KP_End
-      case XK_KP_End:
-#endif
-        key_event = BX_KEY_KP_END; break;
-
-      case XK_KP_2:
-#ifdef XK_KP_Down
-      case XK_KP_Down:
-#endif
-        key_event = BX_KEY_KP_DOWN; break;
-
-      case XK_KP_3:
-#ifdef XK_KP_Page_Down
-      case XK_KP_Page_Down:
-#endif
-        key_event = BX_KEY_KP_PAGE_DOWN; break;
-
-      case XK_KP_4:
-#ifdef XK_KP_Left
-      case XK_KP_Left:
-#endif
-        key_event = BX_KEY_KP_LEFT; break;
-
-      case XK_KP_5:
-#ifdef XK_KP_Begin
-      case XK_KP_Begin:
-#endif
-        key_event = BX_KEY_KP_5; break;
-
-      case XK_KP_6:
-#ifdef XK_KP_Right
-      case XK_KP_Right:
-#endif
-        key_event = BX_KEY_KP_RIGHT; break;
-
-      case XK_KP_7:
-#ifdef XK_KP_Home
-      case XK_KP_Home:
-#endif
-        key_event = BX_KEY_KP_HOME; break;
-
-      case XK_KP_8:
-#ifdef XK_KP_Up
-      case XK_KP_Up:
-#endif
-        key_event = BX_KEY_KP_UP; break;
-
-      case XK_KP_9:
-#ifdef XK_KP_Page_Up
-      case XK_KP_Page_Up:
-#endif
-        key_event = BX_KEY_KP_PAGE_UP; break;
-
-      case XK_KP_0:
-#ifdef XK_KP_Insert
-      case XK_KP_Insert:
-#endif
-        key_event = BX_KEY_KP_INSERT; break;
-
-      case XK_KP_Decimal:
-#ifdef XK_KP_Delete
-      case XK_KP_Delete:
-#endif
-        key_event = BX_KEY_KP_DELETE; break;
-
-#ifdef XK_KP_Enter
-      case XK_KP_Enter:    key_event = BX_KEY_KP_ENTER; break;
-#endif
-
-      case XK_KP_Subtract: key_event = BX_KEY_KP_SUBTRACT; break;
-      case XK_KP_Add:      key_event = BX_KEY_KP_ADD; break;
-
-      case XK_KP_Multiply: key_event = BX_KEY_KP_MULTIPLY; break;
-      case XK_KP_Divide:   key_event = BX_KEY_KP_DIVIDE; break;
-
-
-      case XK_Up:          key_event = BX_KEY_UP; break;
-      case XK_Down:        key_event = BX_KEY_DOWN; break;
-      case XK_Left:        key_event = BX_KEY_LEFT; break;
-      case XK_Right:       key_event = BX_KEY_RIGHT; break;
-
-
-      case XK_Delete:      key_event = BX_KEY_DELETE; break;
-      case XK_BackSpace:   key_event = BX_KEY_BACKSPACE; break;
-      case XK_Tab:         key_event = BX_KEY_TAB; break;
-#ifdef XK_ISO_Left_Tab
-      case XK_ISO_Left_Tab: key_event = BX_KEY_TAB; break;
-#endif
-      case XK_Return:      key_event = BX_KEY_ENTER; break;
-      case XK_Escape:      key_event = BX_KEY_ESC; break;
-      case XK_F1:          key_event = BX_KEY_F1; break;
-      case XK_F2:          key_event = BX_KEY_F2; break;
-      case XK_F3:          key_event = BX_KEY_F3; break;
-      case XK_F4:          key_event = BX_KEY_F4; break;
-      case XK_F5:          key_event = BX_KEY_F5; break;
-      case XK_F6:          key_event = BX_KEY_F6; break;
-      case XK_F7:          key_event = BX_KEY_F7; break;
-      case XK_F8:          key_event = BX_KEY_F8; break;
-      case XK_F9:          key_event = BX_KEY_F9; break;
-      case XK_F10:         key_event = BX_KEY_F10; break;
-      case XK_F11:         key_event = BX_KEY_F11; break;
-      case XK_F12:         key_event = BX_KEY_F12; break;
-      case XK_Control_L:   key_event = BX_KEY_CTRL_L; break;
-#ifdef XK_Control_R
-      case XK_Control_R:   key_event = BX_KEY_CTRL_R; break;
-#endif
-      case XK_Shift_L:     key_event = BX_KEY_SHIFT_L; break;
-      case XK_Shift_R:     key_event = BX_KEY_SHIFT_R; break;
-      case XK_Alt_L:       key_event = BX_KEY_ALT_L; break;
-#ifdef XK_Alt_R
-      case XK_Alt_R:       key_event = BX_KEY_ALT_R; break;
-#endif
-      case XK_Caps_Lock:   key_event = BX_KEY_CAPS_LOCK; break;
-      case XK_Num_Lock:    key_event = BX_KEY_NUM_LOCK; break;
-#ifdef XK_Scroll_Lock
-      case XK_Scroll_Lock: key_event = BX_KEY_SCRL_LOCK; break;
-#endif
-#ifdef XK_Print
-      case XK_Print:       key_event = BX_KEY_PRINT; break;
-#endif
-#ifdef XK_Pause
-      case XK_Pause:       key_event = BX_KEY_PAUSE; break;
-#endif
-
-      case XK_Insert:      key_event = BX_KEY_INSERT; break;
-      case XK_Home:        key_event = BX_KEY_HOME; break;
-      case XK_End:         key_event = BX_KEY_END; break;
-      case XK_Page_Up:     key_event = BX_KEY_PAGE_UP; break;
-      case XK_Page_Down:   key_event = BX_KEY_PAGE_DOWN; break;
-
-      default:
-        BX_ERROR(("rfbKeyPress(): key %04x unhandled!", key));
-        fprintf(stderr, "RFB: rfbKeyPress(): key %04x unhandled!\n", key);
-        return;
-        break;
-    }
-  }
-
-  if (press_release) key_event |= BX_KEY_RELEASED;
-  DEV_kbd_gen_scancode(key_event);
-}
-
-void rfbMouseMove(int x, int y, int bmask)
-{
-  static int oldx = -1;
-  static int oldy = -1;
-  int xorigin;
-
-  if (oldx == oldy == -1) {
-    oldx = x;
-    oldy = y;
-    return;
-  }
-  if(y > rfbHeaderbarY) {
-    //DEV_mouse_motion(x, y - rfbHeaderbarY, buttons);
-    DEV_mouse_motion(x - oldx, oldy - y, bmask);
-    oldx = x;
-    oldy = y;
-  } else {
-    if (bmask == 1) {
-      for (unsigned i=0; i<rfbHeaderbarBitmapCount; i++) {
-        if (rfbHeaderbarBitmaps[i].alignment == BX_GRAVITY_LEFT)
-          xorigin = rfbHeaderbarBitmaps[i].xorigin;
-        else
-          xorigin = rfbDimensionX - rfbHeaderbarBitmaps[i].xorigin;
-        if ( (x>=xorigin) && (x<(xorigin+int(rfbBitmaps[rfbHeaderbarBitmaps[i].index].xdim))) ) {
-          rfbHeaderbarBitmaps[i].f();
-          return;
-        }
-      }
-    }
-  }
-}
-
-  void
-bx_rfb_gui_c::mouse_enabled_changed_specific (bx_bool val)
-{
-}
-
-#endif /* if BX_WITH_RFB */
diff --git a/tools/ioemu/gui/rfb.h b/tools/ioemu/gui/rfb.h
deleted file mode 100644 (file)
index 948ac82..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: rfb.h,v 1.2 2001/10/03 13:10:37 bdenney Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-// rfb.h
-// This includes the rfb spec header, the port numbers,
-// the CARD type definitions and various useful macros.
-//
-
-#ifndef RFB_H__
-#define RFB_H__
-
-// Define the CARD* types as used in X11/Xmd.h
-
-typedef unsigned long CARD32;
-typedef unsigned short CARD16;
-typedef short INT16;
-typedef unsigned char  CARD8;
-
-// Define the port number offsets
-#define FLASH_PORT_OFFSET 5400
-#define INCOMING_PORT_OFFSET 5500
-#define HTTP_PORT_OFFSET 5800  // we don't use this in Venice
-#define RFB_PORT_OFFSET 5900
-
-#define _SIZEOF(x) sz_##x
-#define SIZEOF(x) _SIZEOF(x)
-
-#define PORT_TO_DISPLAY(p) ( (p) - RFB_PORT_OFFSET )
-#define DISPLAY_TO_PORT(d) ( (d) + RFB_PORT_OFFSET )
-
-#define EWOULDBLOCK WSAEWOULDBLOCK
-#define ETIMEDOUT WSAETIMEDOUT
-
-#endif
diff --git a/tools/ioemu/gui/rfbproto.h b/tools/ioemu/gui/rfbproto.h
deleted file mode 100644 (file)
index a2be5f8..0000000
+++ /dev/null
@@ -1,675 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: rfbproto.h,v 1.2 2001/10/03 13:10:37 bdenney Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-/*
- *  Copyright (C) 1997, 1998 Olivetti & Oracle Research Laboratory
- *
- *  This is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This software is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this software; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
- *  USA.
- */
-
-/*
- * rfbproto.h - header file for the RFB protocol version 3.3
- *
- * Uses types CARD<n> for an n-bit unsigned integer, INT<n> for an n-bit signed
- * integer (for n = 8, 16 and 32).
- *
- * All multiple byte integers are in big endian (network) order (most
- * significant byte first).  Unless noted otherwise there is no special
- * alignment of protocol structures.
- *
- *
- * Once the initial handshaking is done, all messages start with a type byte,
- * (usually) followed by message-specific data.  The order of definitions in
- * this file is as follows:
- *
- *  (1) Structures used in several types of message.
- *  (2) Structures used in the initial handshaking.
- *  (3) Message types.
- *  (4) Encoding types.
- *  (5) For each message type, the form of the data following the type byte.
- *      Sometimes this is defined by a single structure but the more complex
- *      messages have to be explained by comments.
- */
-
-
-/*****************************************************************************
- *
- * Structures used in several messages
- *
- *****************************************************************************/
-
-/*-----------------------------------------------------------------------------
- * Structure used to specify a rectangle.  This structure is a multiple of 4
- * bytes so that it can be interspersed with 32-bit pixel data without
- * affecting alignment.
- */
-
-typedef struct {
-    CARD16 x;
-    CARD16 y;
-    CARD16 w;
-    CARD16 h;
-} rfbRectangle;
-
-#define sz_rfbRectangle 8
-
-
-/*-----------------------------------------------------------------------------
- * Structure used to specify pixel format.
- */
-
-typedef struct {
-
-    CARD8 bitsPerPixel;                /* 8,16,32 only */
-
-    CARD8 depth;               /* 8 to 32 */
-
-    CARD8 bigEndian;           /* True if multi-byte pixels are interpreted
-                                  as big endian, or if single-bit-per-pixel
-                                  has most significant bit of the byte
-                                  corresponding to first (leftmost) pixel. Of
-                                  course this is meaningless for 8 bits/pix */
-
-    CARD8 trueColour;          /* If false then we need a "colour map" to
-                                  convert pixels to RGB.  If true, xxxMax and
-                                  xxxShift specify bits used for red, green
-                                  and blue */
-
-    /* the following fields are only meaningful if trueColour is true */
-
-    CARD16 redMax;             /* maximum red value (= 2^n - 1 where n is the
-                                  number of bits used for red). Note this
-                                  value is always in big endian order. */
-
-    CARD16 greenMax;           /* similar for green */
-
-    CARD16 blueMax;            /* and blue */
-
-    CARD8 redShift;            /* number of shifts needed to get the red
-                                  value in a pixel to the least significant
-                                  bit. To find the red value from a given
-                                  pixel, do the following:
-                                  1) Swap pixel value according to bigEndian
-                                     (e.g. if bigEndian is false and host byte
-                                     order is big endian, then swap).
-                                  2) Shift right by redShift.
-                                  3) AND with redMax (in host byte order).
-                                  4) You now have the red value between 0 and
-                                     redMax. */
-
-    CARD8 greenShift;          /* similar for green */
-
-    CARD8 blueShift;           /* and blue */
-
-    CARD8 pad1;
-    CARD16 pad2;
-
-} rfbPixelFormat;
-
-#define sz_rfbPixelFormat 16
-
-
-
-/*****************************************************************************
- *
- * Initial handshaking messages
- *
- *****************************************************************************/
-
-/*-----------------------------------------------------------------------------
- * Protocol Version
- *
- * The server always sends 12 bytes to start which identifies the latest RFB
- * protocol version number which it supports.  These bytes are interpreted
- * as a string of 12 ASCII characters in the format "RFB xxx.yyy\n" where
- * xxx and yyy are the major and minor version numbers (for version 3.3
- * this is "RFB 003.003\n").
- *
- * The client then replies with a similar 12-byte message giving the version
- * number of the protocol which should actually be used (which may be different
- * to that quoted by the server).
- *
- * It is intended that both clients and servers may provide some level of
- * backwards compatibility by this mechanism.  Servers in particular should
- * attempt to provide backwards compatibility, and even forwards compatibility
- * to some extent.  For example if a client demands version 3.1 of the
- * protocol, a 3.0 server can probably assume that by ignoring requests for
- * encoding types it doesn't understand, everything will still work OK.  This
- * will probably not be the case for changes in the major version number.
- *
- * The format string below can be used in sprintf or sscanf to generate or
- * decode the version string respectively.
- */
-
-#define rfbProtocolVersionFormat "RFB %03d.%03d\n"
-#define rfbProtocolMajorVersion 3
-#define rfbProtocolMinorVersion 3
-
-typedef char rfbProtocolVersionMsg[13];        /* allow extra byte for null */
-
-#define sz_rfbProtocolVersionMsg 12
-
-
-/*-----------------------------------------------------------------------------
- * Authentication
- *
- * Once the protocol version has been decided, the server then sends a 32-bit
- * word indicating whether any authentication is needed on the connection.
- * The value of this word determines the authentication scheme in use.  For
- * version 3.0 of the protocol this may have one of the following values:
- */
-
-#define rfbConnFailed 0
-#define rfbNoAuth 1
-#define rfbVncAuth 2
-
-/*
- * rfbConnFailed:      For some reason the connection failed (e.g. the server
- *                     cannot support the desired protocol version).  This is
- *                     followed by a string describing the reason (where a
- *                     string is specified as a 32-bit length followed by that
- *                     many ASCII characters).
- *
- * rfbNoAuth:          No authentication is needed.
- *
- * rfbVncAuth:         The VNC authentication scheme is to be used.  A 16-byte
- *                     challenge follows, which the client encrypts as
- *                     appropriate using the password and sends the resulting
- *                     16-byte response.  If the response is correct, the
- *                     server sends the 32-bit word rfbVncAuthOK.  If a simple
- *                     failure happens, the server sends rfbVncAuthFailed and
- *                     closes the connection. If the server decides that too
- *                     many failures have occurred, it sends rfbVncAuthTooMany
- *                     and closes the connection.  In the latter case, the
- *                     server should not allow an immediate reconnection by
- *                     the client.
- */
-
-#define rfbVncAuthOK 0
-#define rfbVncAuthFailed 1
-#define rfbVncAuthTooMany 2
-
-
-/*-----------------------------------------------------------------------------
- * Client Initialisation Message
- *
- * Once the client and server are sure that they're happy to talk to one
- * another, the client sends an initialisation message.  At present this
- * message only consists of a boolean indicating whether the server should try
- * to share the desktop by leaving other clients connected, or give exclusive
- * access to this client by disconnecting all other clients.
- */
-
-typedef struct {
-    CARD8 shared;
-} rfbClientInitMsg;
-
-#define sz_rfbClientInitMsg 1
-
-
-/*-----------------------------------------------------------------------------
- * Server Initialisation Message
- *
- * After the client initialisation message, the server sends one of its own.
- * This tells the client the width and height of the server's framebuffer,
- * its pixel format and the name associated with the desktop.
- */
-
-typedef struct {
-    CARD16 framebufferWidth;
-    CARD16 framebufferHeight;
-    rfbPixelFormat format;     /* the server's preferred pixel format */
-    CARD32 nameLength;
-    /* followed by char name[nameLength] */
-} rfbServerInitMsg;
-
-#define sz_rfbServerInitMsg (8 + sz_rfbPixelFormat)
-
-
-/*
- * Following the server initialisation message it's up to the client to send
- * whichever protocol messages it wants.  Typically it will send a
- * SetPixelFormat message and a SetEncodings message, followed by a
- * FramebufferUpdateRequest.  From then on the server will send
- * FramebufferUpdate messages in response to the client's
- * FramebufferUpdateRequest messages.  The client should send
- * FramebufferUpdateRequest messages with incremental set to true when it has
- * finished processing one FramebufferUpdate and is ready to process another.
- * With a fast client, the rate at which FramebufferUpdateRequests are sent
- * should be regulated to avoid hogging the network.
- */
-
-
-
-/*****************************************************************************
- *
- * Message types
- *
- *****************************************************************************/
-
-/* server -> client */
-
-#define rfbFramebufferUpdate 0
-#define rfbSetColourMapEntries 1
-#define rfbBell 2
-#define rfbServerCutText 3
-
-
-/* client -> server */
-
-#define rfbSetPixelFormat 0
-#define rfbFixColourMapEntries 1       /* not currently supported */
-#define rfbSetEncodings 2
-#define rfbFramebufferUpdateRequest 3
-#define rfbKeyEvent 4
-#define rfbPointerEvent 5
-#define rfbClientCutText 6
-
-
-
-
-/*****************************************************************************
- *
- * Encoding types
- *
- *****************************************************************************/
-
-#define rfbEncodingRaw 0
-#define rfbEncodingCopyRect 1
-#define rfbEncodingRRE 2
-#define rfbEncodingCoRRE 4
-#define rfbEncodingHextile 5
-
-
-
-/*****************************************************************************
- *
- * Server -> client message definitions
- *
- *****************************************************************************/
-
-
-/*-----------------------------------------------------------------------------
- * FramebufferUpdate - a block of rectangles to be copied to the framebuffer.
- *
- * This message consists of a header giving the number of rectangles of pixel
- * data followed by the rectangles themselves.  The header is padded so that
- * together with the type byte it is an exact multiple of 4 bytes (to help
- * with alignment of 32-bit pixels):
- */
-
-typedef struct {
-    CARD8 type;                        /* always rfbFramebufferUpdate */
-    CARD8 pad;
-    CARD16 nRects;
-    /* followed by nRects rectangles */
-} rfbFramebufferUpdateMsg;
-
-#define sz_rfbFramebufferUpdateMsg 4
-
-/*
- * Each rectangle of pixel data consists of a header describing the position
- * and size of the rectangle and a type word describing the encoding of the
- * pixel data, followed finally by the pixel data.  Note that if the client has
- * not sent a SetEncodings message then it will only receive raw pixel data.
- * Also note again that this structure is a multiple of 4 bytes.
- */
-
-typedef struct {
-    rfbRectangle r;
-    CARD32 encoding;   /* one of the encoding types rfbEncoding... */
-} rfbFramebufferUpdateRectHeader;
-
-#define sz_rfbFramebufferUpdateRectHeader (sz_rfbRectangle + 4)
-
-
-/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * Raw Encoding.  Pixels are sent in top-to-bottom scanline order,
- * left-to-right within a scanline with no padding in between.
- */
-
-
-/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * CopyRect Encoding.  The pixels are specified simply by the x and y position
- * of the source rectangle.
- */
-
-typedef struct {
-    CARD16 srcX;
-    CARD16 srcY;
-} rfbCopyRect;
-
-#define sz_rfbCopyRect 4
-
-
-/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * RRE - Rise-and-Run-length Encoding.  We have an rfbRREHeader structure
- * giving the number of subrectangles following.  Finally the data follows in
- * the form [<bgpixel><subrect><subrect>...] where each <subrect> is
- * [<pixel><rfbRectangle>].
- */
-
-typedef struct {
-    CARD32 nSubrects;
-} rfbRREHeader;
-
-#define sz_rfbRREHeader 4
-
-
-/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * CoRRE - Compact RRE Encoding.  We have an rfbRREHeader structure giving
- * the number of subrectangles following.  Finally the data follows in the form
- * [<bgpixel><subrect><subrect>...] where each <subrect> is
- * [<pixel><rfbCoRRERectangle>].  This means that
- * the whole rectangle must be at most 255x255 pixels.
- */
-
-typedef struct {
-    CARD8 x;
-    CARD8 y;
-    CARD8 w;
-    CARD8 h;
-} rfbCoRRERectangle;
-
-#define sz_rfbCoRRERectangle 4
-
-
-/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * Hextile Encoding.  The rectangle is divided up into "tiles" of 16x16 pixels,
- * starting at the top left going in left-to-right, top-to-bottom order.  If
- * the width of the rectangle is not an exact multiple of 16 then the width of
- * the last tile in each row will be correspondingly smaller.  Similarly if the
- * height is not an exact multiple of 16 then the height of each tile in the
- * final row will also be smaller.  Each tile begins with a "subencoding" type
- * byte, which is a mask made up of a number of bits.  If the Raw bit is set
- * then the other bits are irrelevant; w*h pixel values follow (where w and h
- * are the width and height of the tile).  Otherwise the tile is encoded in a
- * similar way to RRE, except that the position and size of each subrectangle
- * can be specified in just two bytes.  The other bits in the mask are as
- * follows:
- *
- * BackgroundSpecified - if set, a pixel value follows which specifies
- *    the background colour for this tile.  The first non-raw tile in a
- *    rectangle must have this bit set.  If this bit isn't set then the
- *    background is the same as the last tile.
- *
- * ForegroundSpecified - if set, a pixel value follows which specifies
- *    the foreground colour to be used for all subrectangles in this tile.
- *    If this bit is set then the SubrectsColoured bit must be zero.
- *
- * AnySubrects - if set, a single byte follows giving the number of
- *    subrectangles following.  If not set, there are no subrectangles (i.e.
- *    the whole tile is just solid background colour).
- *
- * SubrectsColoured - if set then each subrectangle is preceded by a pixel
- *    value giving the colour of that subrectangle.  If not set, all
- *    subrectangles are the same colour, the foreground colour;  if the
- *    ForegroundSpecified bit wasn't set then the foreground is the same as
- *    the last tile.
- *
- * The position and size of each subrectangle is specified in two bytes.  The
- * Pack macros below can be used to generate the two bytes from x, y, w, h,
- * and the Extract macros can be used to extract the x, y, w, h values from
- * the two bytes.
- */
-
-#define rfbHextileRaw                  (1 << 0)
-#define rfbHextileBackgroundSpecified  (1 << 1)
-#define rfbHextileForegroundSpecified  (1 << 2)
-#define rfbHextileAnySubrects          (1 << 3)
-#define rfbHextileSubrectsColoured     (1 << 4)
-
-#define rfbHextilePackXY(x,y) (((x) << 4) | (y))
-#define rfbHextilePackWH(w,h) ((((w)-1) << 4) | ((h)-1))
-#define rfbHextileExtractX(byte) ((byte) >> 4)
-#define rfbHextileExtractY(byte) ((byte) & 0xf)
-#define rfbHextileExtractW(byte) (((byte) >> 4) + 1)
-#define rfbHextileExtractH(byte) (((byte) & 0xf) + 1)
-
-
-/*-----------------------------------------------------------------------------
- * SetColourMapEntries - these messages are only sent if the pixel
- * format uses a "colour map" (i.e. trueColour false) and the client has not
- * fixed the entire colour map using FixColourMapEntries.  In addition they
- * will only start being sent after the client has sent its first
- * FramebufferUpdateRequest.  So if the client always tells the server to use
- * trueColour then it never needs to process this type of message.
- */
-
-typedef struct {
-    CARD8 type;                        /* always rfbSetColourMapEntries */
-    CARD8 pad;
-    CARD16 firstColour;
-    CARD16 nColours;
-
-    /* Followed by nColours * 3 * CARD16
-       r1, g1, b1, r2, g2, b2, r3, g3, b3, ..., rn, bn, gn */
-
-} rfbSetColourMapEntriesMsg;
-
-#define sz_rfbSetColourMapEntriesMsg 6
-
-
-
-/*-----------------------------------------------------------------------------
- * Bell - ring a bell on the client if it has one.
- */
-
-typedef struct {
-    CARD8 type;                        /* always rfbBell */
-} rfbBellMsg;
-
-#define sz_rfbBellMsg 1
-
-
-
-/*-----------------------------------------------------------------------------
- * ServerCutText - the server has new text in its cut buffer.
- */
-
-typedef struct {
-    CARD8 type;                        /* always rfbServerCutText */
-    CARD8 pad1;
-    CARD16 pad2;
-    CARD32 length;
-    /* followed by char text[length] */
-} rfbServerCutTextMsg;
-
-#define sz_rfbServerCutTextMsg 8
-
-
-/*-----------------------------------------------------------------------------
- * Union of all server->client messages.
- */
-
-typedef union {
-    CARD8 type;
-    rfbFramebufferUpdateMsg fu;
-    rfbSetColourMapEntriesMsg scme;
-    rfbBellMsg b;
-    rfbServerCutTextMsg sct;
-} rfbServerToClientMsg;
-
-
-
-/*****************************************************************************
- *
- * Message definitions (client -> server)
- *
- *****************************************************************************/
-
-
-/*-----------------------------------------------------------------------------
- * SetPixelFormat - tell the RFB server the format in which the client wants
- * pixels sent.
- */
-
-typedef struct {
-    CARD8 type;                        /* always rfbSetPixelFormat */
-    CARD8 pad1;
-    CARD16 pad2;
-    rfbPixelFormat format;
-} rfbSetPixelFormatMsg;
-
-#define sz_rfbSetPixelFormatMsg (sz_rfbPixelFormat + 4)
-
-
-/*-----------------------------------------------------------------------------
- * FixColourMapEntries - when the pixel format uses a "colour map", fix
- * read-only colour map entries.
- *
- *    ***************** NOT CURRENTLY SUPPORTED *****************
- */
-
-typedef struct {
-    CARD8 type;                        /* always rfbFixColourMapEntries */
-    CARD8 pad;
-    CARD16 firstColour;
-    CARD16 nColours;
-
-    /* Followed by nColours * 3 * CARD16
-       r1, g1, b1, r2, g2, b2, r3, g3, b3, ..., rn, bn, gn */
-
-} rfbFixColourMapEntriesMsg;
-
-#define sz_rfbFixColourMapEntriesMsg 6
-
-
-/*-----------------------------------------------------------------------------
- * SetEncodings - tell the RFB server which encoding types we accept.  Put them
- * in order of preference, if we have any.  We may always receive raw
- * encoding, even if we don't specify it here.
- */
-
-typedef struct {
-    CARD8 type;                        /* always rfbSetEncodings */
-    CARD8 pad;
-    CARD16 nEncodings;
-    /* followed by nEncodings * CARD32 encoding types */
-} rfbSetEncodingsMsg;
-
-#define sz_rfbSetEncodingsMsg 4
-
-
-/*-----------------------------------------------------------------------------
- * FramebufferUpdateRequest - request for a framebuffer update.  If incremental
- * is true then the client just wants the changes since the last update.  If
- * false then it wants the whole of the specified rectangle.
- */
-
-typedef struct {
-    CARD8 type;                        /* always rfbFramebufferUpdateRequest */
-    CARD8 incremental;
-    CARD16 x;
-    CARD16 y;
-    CARD16 w;
-    CARD16 h;
-} rfbFramebufferUpdateRequestMsg;
-
-#define sz_rfbFramebufferUpdateRequestMsg 10
-
-
-/*-----------------------------------------------------------------------------
- * KeyEvent - key press or release
- *
- * Keys are specified using the "keysym" values defined by the X Window System.
- * For most ordinary keys, the keysym is the same as the corresponding ASCII
- * value.  Other common keys are:
- *
- * BackSpace           0xff08
- * Tab                 0xff09
- * Return or Enter     0xff0d
- * Escape              0xff1b
- * Insert              0xff63
- * Delete              0xffff
- * Home                        0xff50
- * End                 0xff57
- * Page Up             0xff55
- * Page Down           0xff56
- * Left                        0xff51
- * Up                  0xff52
- * Right               0xff53
- * Down                        0xff54
- * F1                  0xffbe
- * F2                  0xffbf
- * ...                 ...
- * F12                 0xffc9
- * Shift               0xffe1
- * Control             0xffe3
- * Meta                        0xffe7
- * Alt                 0xffe9
- */
-
-typedef struct {
-    CARD8 type;                        /* always rfbKeyEvent */
-    CARD8 down;                        /* true if down (press), false if up */
-    CARD16 pad;
-    CARD32 key;                        /* key is specified as an X keysym */
-} rfbKeyEventMsg;
-
-#define sz_rfbKeyEventMsg 8
-
-
-/*-----------------------------------------------------------------------------
- * PointerEvent - mouse/pen move and/or button press.
- */
-
-typedef struct {
-    CARD8 type;                        /* always rfbPointerEvent */
-    CARD8 buttonMask;          /* bits 0-7 are buttons 1-8, 0=up, 1=down */
-    CARD16 x;
-    CARD16 y;
-} rfbPointerEventMsg;
-
-#define rfbButton1Mask 1
-#define rfbButton2Mask 2
-#define rfbButton3Mask 4
-
-#define sz_rfbPointerEventMsg 6
-
-
-
-/*-----------------------------------------------------------------------------
- * ClientCutText - the client has new text in its cut buffer.
- */
-
-typedef struct {
-    CARD8 type;                        /* always rfbClientCutText */
-    CARD8 pad1;
-    CARD16 pad2;
-    CARD32 length;
-    /* followed by char text[length] */
-} rfbClientCutTextMsg;
-
-#define sz_rfbClientCutTextMsg 8
-
-
-
-/*-----------------------------------------------------------------------------
- * Union of all client->server messages.
- */
-
-typedef union {
-    CARD8 type;
-    rfbSetPixelFormatMsg spf;
-    rfbFixColourMapEntriesMsg fcme;
-    rfbSetEncodingsMsg se;
-    rfbFramebufferUpdateRequestMsg fur;
-    rfbKeyEventMsg ke;
-    rfbPointerEventMsg pe;
-    rfbClientCutTextMsg cct;
-} rfbClientToServerMsg;
diff --git a/tools/ioemu/gui/sdl.h b/tools/ioemu/gui/sdl.h
deleted file mode 100644 (file)
index c8df029..0000000
+++ /dev/null
@@ -1,1038 +0,0 @@
-#define BX_HEADERBAR_FG_RED    0x10
-#define BX_HEADERBAR_FG_GREEN  0x10
-#define BX_HEADERBAR_FG_BLUE   0x10
-#define BX_HEADERBAR_BG_RED    0xD0
-#define BX_HEADERBAR_BG_GREEN  0xD0
-#define BX_HEADERBAR_BG_BLUE   0xD0
-
-unsigned char sdl_font8x16[256][16] = {
-  {   0,   0,   0,   0,   0,   0,   0,   0,    // 0
-      0,   0,   0,   0,   0,   0,   0,   0 },
-  {   0,   0, 126, 129, 165, 129, 129, 189,    // 1
-    153, 129, 129, 126,   0,   0,   0,   0 },
-  {   0,   0, 126, 255, 219, 255, 255, 195,    // 2
-    231, 255, 255, 126,   0,   0,   0,   0 },
-  {   0,   0,   0,   0, 108, 254, 254, 254,    // 3
-    254, 124,  56,  16,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,  16,  56, 124, 254,    // 4
-    124,  56,  16,   0,   0,   0,   0,   0 },
-  {   0,   0,   0,  24,  60,  60, 231, 231,    // 5
-    231,  24,  24,  60,   0,   0,   0,   0 },
-  {   0,   0,   0,  24,  60, 126, 255, 255,    // 6
-    126,  24,  24,  60,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0,   0,  24,  60,    // 7
-     60,  24,   0,   0,   0,   0,   0,   0 },
-  { 255, 255, 255, 255, 255, 255, 231, 195,    // 8
-    195, 231, 255, 255, 255, 255, 255, 255 },
-  {   0,   0,   0,   0,   0,  60, 102,  66,    // 9
-     66, 102,  60,   0,   0,   0,   0,   0 },
-  { 255, 255, 255, 255, 255, 195, 153, 189,    // 10
-    189, 153, 195, 255, 255, 255, 255, 255 },
-  {   0,   0,  30,  14,  26,  50, 120, 204,    // 11
-    204, 204, 204, 120,   0,   0,   0,   0 },
-  {   0,   0,  60, 102, 102, 102, 102,  60,    // 12
-     24, 126,  24,  24,   0,   0,   0,   0 },
-  {   0,   0,  63,  51,  63,  48,  48,  48,    // 13
-     48, 112, 240, 224,   0,   0,   0,   0 },
-  {   0,   0, 127,  99, 127,  99,  99,  99,    // 14
-     99, 103, 231, 230, 192,   0,   0,   0 },
-  {   0,   0,   0,  24,  24, 219,  60, 231,    // 15
-     60, 219,  24,  24,   0,   0,   0,   0 },
-  {   0, 128, 192, 224, 240, 248, 254, 248,    // 16
-    240, 224, 192, 128,   0,   0,   0,   0 },
-  {   0,   2,   6,  14,  30,  62, 254,  62,    // 17
-     30,  14,   6,   2,   0,   0,   0,   0 },
-  {   0,   0,  24,  60, 126,  24,  24,  24,    // 18
-    126,  60,  24,   0,   0,   0,   0,   0 },
-  {   0,   0, 102, 102, 102, 102, 102, 102,    // 19
-    102,   0, 102, 102,   0,   0,   0,   0 },
-  {   0,   0, 127, 219, 219, 219, 123,  27,    // 20
-     27,  27,  27,  27,   0,   0,   0,   0 },
-  {   0, 124, 198,  96,  56, 108, 198, 198,    // 21
-    108,  56,  12, 198, 124,   0,   0,   0 },
-  {   0,   0,   0,   0,   0,   0,   0,   0,    // 22
-    254, 254, 254, 254,   0,   0,   0,   0 },
-  {   0,   0,  24,  60, 126,  24,  24,  24,    // 23
-    126,  60,  24, 126,   0,   0,   0,   0 },
-  {   0,   0,  24,  60, 126,  24,  24,  24,    // 24
-     24,  24,  24,  24,   0,   0,   0,   0 },
-  {   0,   0,  24,  24,  24,  24,  24,  24,    // 25
-     24, 126,  60,  24,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0,  24,  12, 254,    // 26
-     12,  24,   0,   0,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0,  48,  96, 254,    // 27
-     96,  48,   0,   0,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0,   0, 192, 192,    // 28
-    192, 254,   0,   0,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0,  40, 108, 254,    // 29
-    108,  40,   0,   0,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,  16,  56,  56, 124,    // 30
-    124, 254, 254,   0,   0,   0,   0,   0 },
-  {   0,   0,   0,   0, 254, 254, 124, 124,    // 31
-     56,  56,  16,   0,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0,   0,   0,   0,    // 32
-      0,   0,   0,   0,   0,   0,   0,   0 },
-  {   0,   0,  24,  60,  60,  60,  24,  24,    // 33
-     24,   0,  24,  24,   0,   0,   0,   0 },
-  {   0, 102, 102, 102,  36,   0,   0,   0,    // 34
-      0,   0,   0,   0,   0,   0,   0,   0 },
-  {   0,   0,   0, 108, 108, 254, 108, 108,    // 35
-    108, 254, 108, 108,   0,   0,   0,   0 },
-  {  24,  24, 124, 198, 194, 192, 124,   6,    // 36
-      6, 134, 198, 124,  24,  24,   0,   0 },
-  {   0,   0,   0,   0, 194, 198,  12,  24,    // 37
-     48,  96, 198, 134,   0,   0,   0,   0 },
-  {   0,   0,  56, 108, 108,  56, 118, 220,    // 38
-    204, 204, 204, 118,   0,   0,   0,   0 },
-  {   0,  48,  48,  48,  96,   0,   0,   0,    // 39
-      0,   0,   0,   0,   0,   0,   0,   0 },
-  {   0,   0,  12,  24,  48,  48,  48,  48,    // 40
-     48,  48,  24,  12,   0,   0,   0,   0 },
-  {   0,   0,  48,  24,  12,  12,  12,  12,    // 41
-     12,  12,  24,  48,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0, 102,  60, 255,    // 42
-     60, 102,   0,   0,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0,  24,  24, 126,    // 43
-     24,  24,   0,   0,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0,   0,   0,   0,    // 44
-      0,  24,  24,  24,  48,   0,   0,   0 },
-  {   0,   0,   0,   0,   0,   0,   0, 254,    // 45
-      0,   0,   0,   0,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0,   0,   0,   0,    // 46
-      0,   0,  24,  24,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   2,   6,  12,  24,    // 47
-     48,  96, 192, 128,   0,   0,   0,   0 },
-  {   0,   0,  56, 108, 198, 198, 214, 214,    // 48
-    198, 198, 108,  56,   0,   0,   0,   0 },
-  {   0,   0,  24,  56, 120,  24,  24,  24,    // 49
-     24,  24,  24, 126,   0,   0,   0,   0 },
-  {   0,   0, 124, 198,   6,  12,  24,  48,    // 50
-     96, 192, 198, 254,   0,   0,   0,   0 },
-  {   0,   0, 124, 198,   6,   6,  60,   6,    // 51
-      6,   6, 198, 124,   0,   0,   0,   0 },
-  {   0,   0,  12,  28,  60, 108, 204, 254,    // 52
-     12,  12,  12,  30,   0,   0,   0,   0 },
-  {   0,   0, 254, 192, 192, 192, 252,   6,    // 53
-      6,   6, 198, 124,   0,   0,   0,   0 },
-  {   0,   0,  56,  96, 192, 192, 252, 198,    // 54
-    198, 198, 198, 124,   0,   0,   0,   0 },
-  {   0,   0, 254, 198,   6,   6,  12,  24,    // 55
-     48,  48,  48,  48,   0,   0,   0,   0 },
-  {   0,   0, 124, 198, 198, 198, 124, 198,    // 56
-    198, 198, 198, 124,   0,   0,   0,   0 },
-  {   0,   0, 124, 198, 198, 198, 126,   6,    // 57
-      6,   6,  12, 120,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,  24,  24,   0,   0,    // 58
-      0,  24,  24,   0,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,  24,  24,   0,   0,    // 59
-      0,  24,  24,  48,   0,   0,   0,   0 },
-  {   0,   0,   0,   6,  12,  24,  48,  96,    // 60
-     48,  24,  12,   6,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0, 126,   0,   0,    // 61
-    126,   0,   0,   0,   0,   0,   0,   0 },
-  {   0,   0,   0,  96,  48,  24,  12,   6,    // 62
-     12,  24,  48,  96,   0,   0,   0,   0 },
-  {   0,   0, 124, 198, 198,  12,  24,  24,    // 63
-     24,   0,  24,  24,   0,   0,   0,   0 },
-  {   0,   0,   0, 124, 198, 198, 222, 222,    // 64
-    222, 220, 192, 124,   0,   0,   0,   0 },
-  {   0,   0,  16,  56, 108, 198, 198, 254,    // 65
-    198, 198, 198, 198,   0,   0,   0,   0 },
-  {   0,   0, 252, 102, 102, 102, 124, 102,    // 66
-    102, 102, 102, 252,   0,   0,   0,   0 },
-  {   0,   0,  60, 102, 194, 192, 192, 192,    // 67
-    192, 194, 102,  60,   0,   0,   0,   0 },
-  {   0,   0, 248, 108, 102, 102, 102, 102,    // 68
-    102, 102, 108, 248,   0,   0,   0,   0 },
-  {   0,   0, 254, 102,  98, 104, 120, 104,    // 69
-     96,  98, 102, 254,   0,   0,   0,   0 },
-  {   0,   0, 254, 102,  98, 104, 120, 104,    // 70
-     96,  96,  96, 240,   0,   0,   0,   0 },
-  {   0,   0,  60, 102, 194, 192, 192, 222,    // 71
-    198, 198, 102,  58,   0,   0,   0,   0 },
-  {   0,   0, 198, 198, 198, 198, 254, 198,    // 72
-    198, 198, 198, 198,   0,   0,   0,   0 },
-  {   0,   0,  60,  24,  24,  24,  24,  24,    // 73
-     24,  24,  24,  60,   0,   0,   0,   0 },
-  {   0,   0,  30,  12,  12,  12,  12,  12,    // 74
-    204, 204, 204, 120,   0,   0,   0,   0 },
-  {   0,   0, 230, 102, 102, 108, 120, 120,    // 75
-    108, 102, 102, 230,   0,   0,   0,   0 },
-  {   0,   0, 240,  96,  96,  96,  96,  96,    // 76
-     96,  98, 102, 254,   0,   0,   0,   0 },
-  {   0,   0, 198, 238, 254, 254, 214, 198,    // 77
-    198, 198, 198, 198,   0,   0,   0,   0 },
-  {   0,   0, 198, 230, 246, 254, 222, 206,    // 78
-    198, 198, 198, 198,   0,   0,   0,   0 },
-  {   0,   0, 124, 198, 198, 198, 198, 198,    // 79
-    198, 198, 198, 124,   0,   0,   0,   0 },
-  {   0,   0, 252, 102, 102, 102, 124,  96,    // 80
-     96,  96,  96, 240,   0,   0,   0,   0 },
-  {   0,   0, 124, 198, 198, 198, 198, 198,    // 81
-    198, 214, 222, 124,  12,  14,   0,   0 },
-  {   0,   0, 252, 102, 102, 102, 124, 108,    // 82
-    102, 102, 102, 230,   0,   0,   0,   0 },
-  {   0,   0, 124, 198, 198,  96,  56,  12,    // 83
-      6, 198, 198, 124,   0,   0,   0,   0 },
-  {   0,   0, 126, 126,  90,  24,  24,  24,    // 84
-     24,  24,  24,  60,   0,   0,   0,   0 },
-  {   0,   0, 198, 198, 198, 198, 198, 198,    // 85
-    198, 198, 198, 124,   0,   0,   0,   0 },
-  {   0,   0, 198, 198, 198, 198, 198, 198,    // 86
-    198, 108,  56,  16,   0,   0,   0,   0 },
-  {   0,   0, 198, 198, 198, 198, 214, 214,    // 87
-    214, 254, 238, 108,   0,   0,   0,   0 },
-  {   0,   0, 198, 198, 108, 124,  56,  56,    // 88
-    124, 108, 198, 198,   0,   0,   0,   0 },
-  {   0,   0, 102, 102, 102, 102,  60,  24,    // 89
-     24,  24,  24,  60,   0,   0,   0,   0 },
-  {   0,   0, 254, 198, 134,  12,  24,  48,    // 90
-     96, 194, 198, 254,   0,   0,   0,   0 },
-  {   0,   0,  60,  48,  48,  48,  48,  48,    // 91
-     48,  48,  48,  60,   0,   0,   0,   0 },
-  {   0,   0,   0, 128, 192, 224, 112,  56,    // 92
-     28,  14,   6,   2,   0,   0,   0,   0 },
-  {   0,   0,  60,  12,  12,  12,  12,  12,    // 93
-     12,  12,  12,  60,   0,   0,   0,   0 },
-  {  16,  56, 108, 198,   0,   0,   0,   0,    // 94
-      0,   0,   0,   0,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0,   0,   0,   0,    // 95
-      0,   0,   0,   0,   0, 255,   0,   0 },
-  {   0,  48,  24,  12,   0,   0,   0,   0,    // 96
-      0,   0,   0,   0,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0, 120,  12, 124,    // 97
-    204, 204, 204, 118,   0,   0,   0,   0 },
-  {   0,   0, 224,  96,  96, 120, 108, 102,    // 98
-    102, 102, 102, 124,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0, 124, 198, 192,    // 99
-    192, 192, 198, 124,   0,   0,   0,   0 },
-  {   0,   0,  28,  12,  12,  60, 108, 204,    // 100
-    204, 204, 204, 118,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0, 124, 198, 254,    // 101
-    192, 192, 198, 124,   0,   0,   0,   0 },
-  {   0,   0,  28,  54,  50,  48, 120,  48,    // 102
-     48,  48,  48, 120,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0, 118, 204, 204,    // 103
-    204, 204, 204, 124,  12, 204, 120,   0 },
-  {   0,   0, 224,  96,  96, 108, 118, 102,    // 104
-    102, 102, 102, 230,   0,   0,   0,   0 },
-  {   0,   0,  24,  24,   0,  56,  24,  24,    // 105
-     24,  24,  24,  60,   0,   0,   0,   0 },
-  {   0,   0,   6,   6,   0,  14,   6,   6,    // 106
-      6,   6,   6,   6, 102, 102,  60,   0 },
-  {   0,   0, 224,  96,  96, 102, 108, 120,    // 107
-    120, 108, 102, 230,   0,   0,   0,   0 },
-  {   0,   0,  56,  24,  24,  24,  24,  24,    // 108
-     24,  24,  24,  60,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0, 236, 254, 214,    // 109
-    214, 214, 214, 198,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0, 220, 102, 102,    // 110
-    102, 102, 102, 102,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0, 124, 198, 198,    // 111
-    198, 198, 198, 124,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0, 220, 102, 102,    // 112
-    102, 102, 102, 124,  96,  96, 240,   0 },
-  {   0,   0,   0,   0,   0, 118, 204, 204,    // 113
-    204, 204, 204, 124,  12,  12,  30,   0 },
-  {   0,   0,   0,   0,   0, 220, 118, 102,    // 114
-     96,  96,  96, 240,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0, 124, 198,  96,    // 115
-     56,  12, 198, 124,   0,   0,   0,   0 },
-  {   0,   0,  16,  48,  48, 252,  48,  48,    // 116
-     48,  48,  54,  28,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0, 204, 204, 204,    // 117
-    204, 204, 204, 118,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0, 198, 198, 198,    // 118
-    198, 198, 108,  56,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0, 198, 198, 214,    // 119
-    214, 214, 254, 108,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0, 198, 108,  56,    // 120
-     56,  56, 108, 198,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0, 198, 198, 198,    // 121
-    198, 198, 198, 126,   6,  12, 248,   0 },
-  {   0,   0,   0,   0,   0, 254, 204,  24,    // 122
-     48,  96, 198, 254,   0,   0,   0,   0 },
-  {   0,   0,  14,  24,  24,  24, 112,  24,    // 123
-     24,  24,  24,  14,   0,   0,   0,   0 },
-  {   0,   0,  24,  24,  24,  24,  24,  24,    // 124
-     24,  24,  24,  24,   0,   0,   0,   0 },
-  {   0,   0, 112,  24,  24,  24,  14,  24,    // 125
-     24,  24,  24, 112,   0,   0,   0,   0 },
-  {   0, 118, 220,   0,   0,   0,   0,   0,    // 126
-      0,   0,   0,   0,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,  16,  56, 108, 198,    // 127
-    198, 198, 254,   0,   0,   0,   0,   0 },
-  {   0,   0,  60, 102, 194, 192, 192, 192,    // 128
-    192, 194, 102,  60,  24, 112,   0,   0 },
-  {   0,   0, 204,   0,   0, 204, 204, 204,    // 129
-    204, 204, 204, 118,   0,   0,   0,   0 },
-  {   0,  12,  24,  48,   0, 124, 198, 254,    // 130
-    192, 192, 198, 124,   0,   0,   0,   0 },
-  {   0,  16,  56, 108,   0, 120,  12, 124,    // 131
-    204, 204, 204, 118,   0,   0,   0,   0 },
-  {   0,   0, 204,   0,   0, 120,  12, 124,    // 132
-    204, 204, 204, 118,   0,   0,   0,   0 },
-  {   0,  96,  48,  24,   0, 120,  12, 124,    // 133
-    204, 204, 204, 118,   0,   0,   0,   0 },
-  {   0,  56, 108,  56,   0, 120,  12, 124,    // 134
-    204, 204, 204, 118,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0, 124, 198, 192,    // 135
-    192, 192, 198, 124,  24, 112,   0,   0 },
-  {   0,  16,  56, 108,   0, 124, 198, 254,    // 136
-    192, 192, 198, 124,   0,   0,   0,   0 },
-  {   0,   0, 198,   0,   0, 124, 198, 254,    // 137
-    192, 192, 198, 124,   0,   0,   0,   0 },
-  {   0,  96,  48,  24,   0, 124, 198, 254,    // 138
-    192, 192, 198, 124,   0,   0,   0,   0 },
-  {   0,   0, 102,   0,   0,  56,  24,  24,    // 139
-     24,  24,  24,  60,   0,   0,   0,   0 },
-  {   0,  24,  60, 102,   0,  56,  24,  24,    // 140
-     24,  24,  24,  60,   0,   0,   0,   0 },
-  {   0,  96,  48,  24,   0,  56,  24,  24,    // 141
-     24,  24,  24,  60,   0,   0,   0,   0 },
-  {   0, 198,   0,  16,  56, 108, 198, 198,    // 142
-    254, 198, 198, 198,   0,   0,   0,   0 },
-  {  56, 108,  56,  16,  56, 108, 198, 198,    // 143
-    254, 198, 198, 198,   0,   0,   0,   0 },
-  {  12,  24,   0, 254, 102,  98, 104, 120,    // 144
-    104,  98, 102, 254,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0, 236,  54,  54,    // 145
-    126, 216, 216, 110,   0,   0,   0,   0 },
-  {   0,   0,  62, 108, 204, 204, 254, 204,    // 146
-    204, 204, 204, 206,   0,   0,   0,   0 },
-  {   0,  16,  56, 108,   0, 124, 198, 198,    // 147
-    198, 198, 198, 124,   0,   0,   0,   0 },
-  {   0,   0, 198,   0,   0, 124, 198, 198,    // 148
-    198, 198, 198, 124,   0,   0,   0,   0 },
-  {   0,  96,  48,  24,   0, 124, 198, 198,    // 149
-    198, 198, 198, 124,   0,   0,   0,   0 },
-  {   0,  48, 120, 204,   0, 204, 204, 204,    // 150
-    204, 204, 204, 118,   0,   0,   0,   0 },
-  {   0,  96,  48,  24,   0, 204, 204, 204,    // 151
-    204, 204, 204, 118,   0,   0,   0,   0 },
-  {   0,   0, 198,   0,   0, 198, 198, 198,    // 152
-    198, 198, 198, 126,   6,  12, 120,   0 },
-  {   0, 198,   0, 124, 198, 198, 198, 198,    // 153
-    198, 198, 198, 124,   0,   0,   0,   0 },
-  {   0, 198,   0, 198, 198, 198, 198, 198,    // 154
-    198, 198, 198, 124,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0, 124, 206, 222,    // 155
-    246, 230, 198, 124,   0,   0,   0,   0 },
-  {   0,  56, 108, 100,  96, 240,  96,  96,    // 156
-     96,  96, 230, 252,   0,   0,   0,   0 },
-  {   0,   4, 124, 206, 206, 214, 214, 214,    // 157
-    214, 230, 230, 124,  64,   0,   0,   0 },
-  {   0,   0,   0,   0,   0, 198, 108,  56,    // 158
-     56, 108, 198,   0,   0,   0,   0,   0 },
-  {   0,  14,  27,  24,  24,  24, 126,  24,    // 159
-     24,  24, 216, 112,   0,   0,   0,   0 },
-  {   0,  24,  48,  96,   0, 120,  12, 124,    // 160
-    204, 204, 204, 118,   0,   0,   0,   0 },
-  {   0,  12,  24,  48,   0,  56,  24,  24,    // 161
-     24,  24,  24,  60,   0,   0,   0,   0 },
-  {   0,  24,  48,  96,   0, 124, 198, 198,    // 162
-    198, 198, 198, 124,   0,   0,   0,   0 },
-  {   0,  24,  48,  96,   0, 204, 204, 204,    // 163
-    204, 204, 204, 118,   0,   0,   0,   0 },
-  {   0,   0, 118, 220,   0, 220, 102, 102,    // 164
-    102, 102, 102, 102,   0,   0,   0,   0 },
-  { 118, 220,   0, 198, 230, 246, 254, 222,    // 165
-    206, 198, 198, 198,   0,   0,   0,   0 },
-  {   0,   0,  60, 108, 108,  62,   0, 126,    // 166
-      0,   0,   0,   0,   0,   0,   0,   0 },
-  {   0,   0,  56, 108, 108,  56,   0, 124,    // 167
-      0,   0,   0,   0,   0,   0,   0,   0 },
-  {   0,   0,  48,  48,   0,  48,  48,  96,    // 168
-    192, 198, 198, 124,   0,   0,   0,   0 },
-  {   0,   0, 124, 130, 178, 170, 178, 170,    // 169
-    170, 130, 124,   0,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0,   0, 254,   6,    // 170
-      6,   6,   6,   0,   0,   0,   0,   0 },
-  {   0,  96, 224,  98, 102, 108,  24,  48,    // 171
-     96, 220, 134,  12,  24,  62,   0,   0 },
-  {   0,  96, 224,  98, 102, 108,  24,  48,    // 172
-    102, 206, 154,  63,   6,   6,   0,   0 },
-  {   0,   0,  24,  24,   0,  24,  24,  24,    // 173
-     60,  60,  60,  24,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0,  54, 108, 216,    // 174
-    108,  54,   0,   0,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0, 216, 108,  54,    // 175
-    108, 216,   0,   0,   0,   0,   0,   0 },
-  {  17,  68,  17,  68,  17,  68,  17,  68,    // 176
-     17,  68,  17,  68,  17,  68,  17,  68 },
-  {  85, 170,  85, 170,  85, 170,  85, 170,    // 177
-     85, 170,  85, 170,  85, 170,  85, 170 },
-  { 221, 119, 221, 119, 221, 119, 221, 119,    // 178
-    221, 119, 221, 119, 221, 119, 221, 119 },
-  {  24,  24,  24,  24,  24,  24,  24,  24,    // 179
-     24,  24,  24,  24,  24,  24,  24,  24 },
-  {  24,  24,  24,  24,  24,  24,  24, 248,    // 180
-     24,  24,  24,  24,  24,  24,  24,  24 },
-  {  96, 192,  16,  56, 108, 198, 198, 254,    // 181
-    198, 198, 198, 198,   0,   0,   0,   0 },
-  { 124, 198,  16,  56, 108, 198, 198, 254,    // 182
-    198, 198, 198, 198,   0,   0,   0,   0 },
-  {  12,   6,  16,  56, 108, 198, 198, 254,    // 183
-    198, 198, 198, 198,   0,   0,   0,   0 },
-  {   0,   0, 124, 130, 154, 162, 162, 162,    // 184
-    154, 130, 124,   0,   0,   0,   0,   0 },
-  {  54,  54,  54,  54,  54, 246,   6, 246,    // 185
-     54,  54,  54,  54,  54,  54,  54,  54 },
-  {  54,  54,  54,  54,  54,  54,  54,  54,    // 186
-     54,  54,  54,  54,  54,  54,  54,  54 },
-  {   0,   0,   0,   0,   0, 254,   6, 246,    // 187
-     54,  54,  54,  54,  54,  54,  54,  54 },
-  {  54,  54,  54,  54,  54, 246,   6, 254,    // 188
-      0,   0,   0,   0,   0,   0,   0,   0 },
-  {   0,   0,  24,  24, 124, 198, 192, 192,    // 189
-    198, 124,  24,  24,   0,   0,   0,   0 },
-  {   0,   0,   0, 102, 102,  60,  24, 126,    // 190
-     24, 126,  24,  24,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0,   0,   0, 248,    // 191
-     24,  24,  24,  24,  24,  24,  24,  24 },
-  {  24,  24,  24,  24,  24,  24,  24,  31,    // 192
-      0,   0,   0,   0,   0,   0,   0,   0 },
-  {  24,  24,  24,  24,  24,  24,  24, 255,    // 193
-      0,   0,   0,   0,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0,   0,   0, 255,    // 194
-     24,  24,  24,  24,  24,  24,  24,  24 },
-  {  24,  24,  24,  24,  24,  24,  24,  31,    // 195
-     24,  24,  24,  24,  24,  24,  24,  24 },
-  {   0,   0,   0,   0,   0,   0,   0, 255,    // 196
-      0,   0,   0,   0,   0,   0,   0,   0 },
-  {  24,  24,  24,  24,  24,  24,  24, 255,    // 197
-     24,  24,  24,  24,  24,  24,  24,  24 },
-  {   0,   0, 118, 220,   0, 120,  12, 124,    // 198
-    204, 204, 204, 118,   0,   0,   0,   0 },
-  { 118, 220,   0,  56, 108, 198, 198, 254,    // 199
-    198, 198, 198, 198,   0,   0,   0,   0 },
-  {  54,  54,  54,  54,  54,  55,  48,  63,    // 200
-      0,   0,   0,   0,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0,  63,  48,  55,    // 201
-     54,  54,  54,  54,  54,  54,  54,  54 },
-  {  54,  54,  54,  54,  54, 247,   0, 255,    // 202
-      0,   0,   0,   0,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0, 255,   0, 247,    // 203
-     54,  54,  54,  54,  54,  54,  54,  54 },
-  {  54,  54,  54,  54,  54,  55,  48,  55,    // 204
-     54,  54,  54,  54,  54,  54,  54,  54 },
-  {   0,   0,   0,   0,   0, 255,   0, 255,    // 205
-      0,   0,   0,   0,   0,   0,   0,   0 },
-  {  54,  54,  54,  54,  54, 247,   0, 247,    // 206
-     54,  54,  54,  54,  54,  54,  54,  54 },
-  {   0,   0,   0,   0, 198, 124, 198, 198,    // 207
-    198, 198, 124, 198,   0,   0,   0,   0 },
-  {   0,   0,  52,  24,  44,   6,  62, 102,    // 208
-    102, 102, 102,  60,   0,   0,   0,   0 },
-  {   0,   0, 248, 108, 102, 102, 246, 102,    // 209
-    102, 102, 108, 248,   0,   0,   0,   0 },
-  {  56, 108,   0, 254, 102,  98, 104, 120,    // 210
-    104,  98, 102, 254,   0,   0,   0,   0 },
-  {   0, 198,   0, 254, 102,  98, 104, 120,    // 211
-    104,  98, 102, 254,   0,   0,   0,   0 },
-  {  48,  24,   0, 254, 102,  98, 104, 120,    // 212
-    104,  98, 102, 254,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0,  56,  24,  24,    // 213
-     24,  24,  24,  60,   0,   0,   0,   0 },
-  {  12,  24,   0,  60,  24,  24,  24,  24,    // 214
-     24,  24,  24,  60,   0,   0,   0,   0 },
-  {  60, 102,   0,  60,  24,  24,  24,  24,    // 215
-     24,  24,  24,  60,   0,   0,   0,   0 },
-  {   0, 102,   0,  60,  24,  24,  24,  24,    // 216
-     24,  24,  24,  60,   0,   0,   0,   0 },
-  {  24,  24,  24,  24,  24,  24,  24, 248,    // 217
-      0,   0,   0,   0,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0,   0,   0,  31,    // 218
-     24,  24,  24,  24,  24,  24,  24,  24 },
-  { 255, 255, 255, 255, 255, 255, 255, 255,    // 219
-    255, 255, 255, 255, 255, 255, 255, 255 },
-  {   0,   0,   0,   0,   0,   0,   0, 255,    // 220
-    255, 255, 255, 255, 255, 255, 255, 255 },
-  {   0,  24,  24,  24,  24,  24,   0,   0,    // 221
-     24,  24,  24,  24,  24,   0,   0,   0 },
-  {  48,  24,   0,  60,  24,  24,  24,  24,    // 222
-     24,  24,  24,  60,   0,   0,   0,   0 },
-  { 255, 255, 255, 255, 255, 255, 255,   0,    // 223
-      0,   0,   0,   0,   0,   0,   0,   0 },
-  {  24,  48,   0, 124, 198, 198, 198, 198,    // 224
-    198, 198, 198, 124,   0,   0,   0,   0 },
-  {   0,   0, 120, 204, 204, 204, 216, 204,    // 225
-    198, 198, 198, 204,   0,   0,   0,   0 },
-  {  56, 108,   0, 124, 198, 198, 198, 198,    // 226
-    198, 198, 198, 124,   0,   0,   0,   0 },
-  {  48,  24,   0, 124, 198, 198, 198, 198,    // 227
-    198, 198, 198, 124,   0,   0,   0,   0 },
-  {   0,   0, 118, 220,   0, 124, 198, 198,    // 228
-    198, 198, 198, 124,   0,   0,   0,   0 },
-  { 118, 220,   0, 124, 198, 198, 198, 198,    // 229
-    198, 198, 198, 124,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0, 102, 102, 102,    // 230
-    102, 102, 102, 124,  96,  96, 192,   0 },
-  {   0,   0, 224,  96,  96, 124, 102, 102,    // 231
-    102, 102, 102, 124,  96,  96, 240,   0 },
-  {   0,   0, 240,  96, 124, 102, 102, 102,    // 232
-    102, 124,  96, 240,   0,   0,   0,   0 },
-  {  24,  48,   0, 198, 198, 198, 198, 198,    // 233
-    198, 198, 198, 124,   0,   0,   0,   0 },
-  {  56, 108,   0, 198, 198, 198, 198, 198,    // 234
-    198, 198, 198, 124,   0,   0,   0,   0 },
-  {  48,  24,   0, 198, 198, 198, 198, 198,    // 235
-    198, 198, 198, 124,   0,   0,   0,   0 },
-  {   0,  12,  24,  48,   0, 198, 198, 198,    // 236
-    198, 198, 198, 126,   6,  12, 248,   0 },
-  {  12,  24,   0, 102, 102, 102, 102,  60,    // 237
-     24,  24,  24,  60,   0,   0,   0,   0 },
-  {   0, 255,   0,   0,   0,   0,   0,   0,    // 238
-      0,   0,   0,   0,   0,   0,   0,   0 },
-  {   0,  12,  24,  48,   0,   0,   0,   0,    // 239
-      0,   0,   0,   0,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0,   0,   0, 254,    // 240
-      0,   0,   0,   0,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,  24,  24, 126,  24,    // 241
-     24,   0,   0, 126,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0,   0,   0,   0,    // 242
-      0,   0,   0,   0, 255,   0, 255,   0 },
-  {   0, 224,  48,  98,  54, 236,  24,  48,    // 243
-    102, 206, 154,  63,   6,   6,   0,   0 },
-  {   0,   0, 127, 219, 219, 219, 123,  27,    // 244
-     27,  27,  27,  27,   0,   0,   0,   0 },
-  {   0, 124, 198,  96,  56, 108, 198, 198,    // 245
-    108,  56,  12, 198, 124,   0,   0,   0 },
-  {   0,   0,   0,   0,   0,  24,   0, 126,    // 246
-      0,  24,   0,   0,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0,   0,   0,   0,    // 247
-      0,   0,   0,  24,  12, 120,   0,   0 },
-  {   0,  56, 108, 108,  56,   0,   0,   0,    // 248
-      0,   0,   0,   0,   0,   0,   0,   0 },
-  {   0, 198,   0,   0,   0,   0,   0,   0,    // 249
-      0,   0,   0,   0,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0,   0,   0,  24,    // 250
-      0,   0,   0,   0,   0,   0,   0,   0 },
-  {   0,  24,  56,  24,  24,  24,  60,   0,    // 251
-      0,   0,   0,   0,   0,   0,   0,   0 },
-  {   0, 124,   6,  60,   6,   6, 124,   0,    // 252
-      0,   0,   0,   0,   0,   0,   0,   0 },
-  {   0,  60, 102,  12,  24,  50, 126,   0,    // 253
-      0,   0,   0,   0,   0,   0,   0,   0 },
-  {   0,   0,   0,   0, 126, 126, 126, 126,    // 254
-    126, 126, 126,   0,   0,   0,   0,   0 },
-  {   0,   0,   0,   0,   0,   0,   0,   0,    // 255
-      0,   0,   0,   0,   0,   0,   0,   0 }};
-
-unsigned char sdl_font8x8[256][8] = {
-  {   0,   0,   0,   0,   0,   0,   0,   0 },  // 0
-  { 126, 129, 165, 129, 189, 153, 129, 126 },  // 1
-  { 126, 255, 219, 255, 195, 231, 255, 126 },  // 2
-  { 108, 254, 254, 254, 124,  56,  16,   0 },  // 3
-  {  16,  56, 124, 254, 124,  56,  16,   0 },  // 4
-  {  56, 124,  56, 254, 254, 214,  16,  56 },  // 5
-  {  16,  56, 124, 254, 254, 124,  16,  56 },  // 6
-  {   0,   0,  24,  60,  60,  24,   0,   0 },  // 7
-  { 255, 255, 231, 195, 195, 231, 255, 255 },  // 8
-  {   0,  60, 102,  66,  66, 102,  60,   0 },  // 9
-  { 255, 195, 153, 189, 189, 153, 195, 255 },  // 10
-  {  15,   7,  15, 125, 204, 204, 204, 120 },  // 11
-  {  60, 102, 102, 102,  60,  24, 126,  24 },  // 12
-  {  63,  51,  63,  48,  48, 112, 240, 224 },  // 13
-  { 127,  99, 127,  99,  99, 103, 230, 192 },  // 14
-  {  24, 219,  60, 231, 231,  60, 219,  24 },  // 15
-  { 128, 224, 248, 254, 248, 224, 128,   0 },  // 16
-  {   2,  14,  62, 254,  62,  14,   2,   0 },  // 17
-  {  24,  60, 126,  24,  24, 126,  60,  24 },  // 18
-  { 102, 102, 102, 102, 102,   0, 102,   0 },  // 19
-  { 127, 219, 219, 123,  27,  27,  27,   0 },  // 20
-  {  62,  97,  60, 102, 102,  60, 134, 124 },  // 21
-  {   0,   0,   0,   0, 126, 126, 126,   0 },  // 22
-  {  24,  60, 126,  24, 126,  60,  24, 255 },  // 23
-  {  24,  60, 126,  24,  24,  24,  24,   0 },  // 24
-  {  24,  24,  24,  24, 126,  60,  24,   0 },  // 25
-  {   0,  24,  12, 254,  12,  24,   0,   0 },  // 26
-  {   0,  48,  96, 254,  96,  48,   0,   0 },  // 27
-  {   0,   0, 192, 192, 192, 254,   0,   0 },  // 28
-  {   0,  36, 102, 255, 102,  36,   0,   0 },  // 29
-  {   0,  24,  60, 126, 255, 255,   0,   0 },  // 30
-  {   0, 255, 255, 126,  60,  24,   0,   0 },  // 31
-  {   0,   0,   0,   0,   0,   0,   0,   0 },  // 32
-  {  24,  60,  60,  24,  24,   0,  24,   0 },  // 33
-  { 102, 102,  36,   0,   0,   0,   0,   0 },  // 34
-  { 108, 108, 254, 108, 254, 108, 108,   0 },  // 35
-  {  24,  62,  96,  60,   6, 124,  24,   0 },  // 36
-  {   0, 198, 204,  24,  48, 102, 198,   0 },  // 37
-  {  56, 108,  56, 118, 220, 204, 118,   0 },  // 38
-  {  24,  24,  48,   0,   0,   0,   0,   0 },  // 39
-  {  12,  24,  48,  48,  48,  24,  12,   0 },  // 40
-  {  48,  24,  12,  12,  12,  24,  48,   0 },  // 41
-  {   0, 102,  60, 231,  60, 102,   0,   0 },  // 42
-  {   0,  24,  24, 126,  24,  24,   0,   0 },  // 43
-  {   0,   0,   0,   0,   0,  24,  24,  48 },  // 44
-  {   0,   0,   0, 126,   0,   0,   0,   0 },  // 45
-  {   0,   0,   0,   0,   0,  24,  24,   0 },  // 46
-  {   6,  12,  24,  48,  96, 192, 128,   0 },  // 47
-  { 124, 198, 206, 222, 246, 230, 124,   0 },  // 48
-  {  24,  56,  24,  24,  24,  24, 126,   0 },  // 49
-  { 124, 198,   6,  28,  48, 102, 254,   0 },  // 50
-  { 124, 198,   6,  60,   6, 198, 124,   0 },  // 51
-  {  28,  60, 108, 204, 254,  12,  30,   0 },  // 52
-  { 254, 192, 192, 252,   6, 198, 124,   0 },  // 53
-  {  56,  96, 192, 252, 198, 198, 124,   0 },  // 54
-  { 254, 198,  12,  24,  48,  48,  48,   0 },  // 55
-  { 124, 198, 198, 124, 198, 198, 124,   0 },  // 56
-  { 124, 198, 198, 126,   6,  12, 120,   0 },  // 57
-  {   0,  24,  24,   0,   0,  24,  24,   0 },  // 58
-  {   0,  24,  24,   0,   0,  24,  24,  48 },  // 59
-  {   6,  12,  24,  48,  24,  12,   6,   0 },  // 60
-  {   0,   0, 126,   0,   0, 126,   0,   0 },  // 61
-  {  96,  48,  24,  12,  24,  48,  96,   0 },  // 62
-  { 124, 198,  12,  24,  24,   0,  24,   0 },  // 63
-  { 124, 198, 222, 222, 222, 192, 120,   0 },  // 64
-  {  56, 108, 198, 254, 198, 198, 198,   0 },  // 65
-  { 252, 102, 102, 124, 102, 102, 252,   0 },  // 66
-  {  60, 102, 192, 192, 192, 102,  60,   0 },  // 67
-  { 248, 108, 102, 102, 102, 108, 248,   0 },  // 68
-  { 254,  98, 104, 120, 104,  98, 254,   0 },  // 69
-  { 254,  98, 104, 120, 104,  96, 240,   0 },  // 70
-  {  60, 102, 192, 192, 206, 102,  58,   0 },  // 71
-  { 198, 198, 198, 254, 198, 198, 198,   0 },  // 72
-  {  60,  24,  24,  24,  24,  24,  60,   0 },  // 73
-  {  30,  12,  12,  12, 204, 204, 120,   0 },  // 74
-  { 230, 102, 108, 120, 108, 102, 230,   0 },  // 75
-  { 240,  96,  96,  96,  98, 102, 254,   0 },  // 76
-  { 198, 238, 254, 254, 214, 198, 198,   0 },  // 77
-  { 198, 230, 246, 222, 206, 198, 198,   0 },  // 78
-  { 124, 198, 198, 198, 198, 198, 124,   0 },  // 79
-  { 252, 102, 102, 124,  96,  96, 240,   0 },  // 80
-  { 124, 198, 198, 198, 198, 206, 124,  14 },  // 81
-  { 252, 102, 102, 124, 108, 102, 230,   0 },  // 82
-  {  60, 102,  48,  24,  12, 102,  60,   0 },  // 83
-  { 126, 126,  90,  24,  24,  24,  60,   0 },  // 84
-  { 198, 198, 198, 198, 198, 198, 124,   0 },  // 85
-  { 198, 198, 198, 198, 198, 108,  56,   0 },  // 86
-  { 198, 198, 198, 214, 214, 254, 108,   0 },  // 87
-  { 198, 198, 108,  56, 108, 198, 198,   0 },  // 88
-  { 102, 102, 102,  60,  24,  24,  60,   0 },  // 89
-  { 254, 198, 140,  24,  50, 102, 254,   0 },  // 90
-  {  60,  48,  48,  48,  48,  48,  60,   0 },  // 91
-  { 192,  96,  48,  24,  12,   6,   2,   0 },  // 92
-  {  60,  12,  12,  12,  12,  12,  60,   0 },  // 93
-  {  16,  56, 108, 198,   0,   0,   0,   0 },  // 94
-  {   0,   0,   0,   0,   0,   0,   0, 255 },  // 95
-  {  48,  24,  12,   0,   0,   0,   0,   0 },  // 96
-  {   0,   0, 120,  12, 124, 204, 118,   0 },  // 97
-  { 224,  96, 124, 102, 102, 102, 220,   0 },  // 98
-  {   0,   0, 124, 198, 192, 198, 124,   0 },  // 99
-  {  28,  12, 124, 204, 204, 204, 118,   0 },  // 100
-  {   0,   0, 124, 198, 254, 192, 124,   0 },  // 101
-  {  60, 102,  96, 248,  96,  96, 240,   0 },  // 102
-  {   0,   0, 118, 204, 204, 124,  12, 248 },  // 103
-  { 224,  96, 108, 118, 102, 102, 230,   0 },  // 104
-  {  24,   0,  56,  24,  24,  24,  60,   0 },  // 105
-  {   6,   0,   6,   6,   6, 102, 102,  60 },  // 106
-  { 224,  96, 102, 108, 120, 108, 230,   0 },  // 107
-  {  56,  24,  24,  24,  24,  24,  60,   0 },  // 108
-  {   0,   0, 236, 254, 214, 214, 214,   0 },  // 109
-  {   0,   0, 220, 102, 102, 102, 102,   0 },  // 110
-  {   0,   0, 124, 198, 198, 198, 124,   0 },  // 111
-  {   0,   0, 220, 102, 102, 124,  96, 240 },  // 112
-  {   0,   0, 118, 204, 204, 124,  12,  30 },  // 113
-  {   0,   0, 220, 118,  96,  96, 240,   0 },  // 114
-  {   0,   0, 126, 192, 124,   6, 252,   0 },  // 115
-  {  48,  48, 252,  48,  48,  54,  28,   0 },  // 116
-  {   0,   0, 204, 204, 204, 204, 118,   0 },  // 117
-  {   0,   0, 198, 198, 198, 108,  56,   0 },  // 118
-  {   0,   0, 198, 214, 214, 254, 108,   0 },  // 119
-  {   0,   0, 198, 108,  56, 108, 198,   0 },  // 120
-  {   0,   0, 198, 198, 198, 126,   6, 252 },  // 121
-  {   0,   0, 126,  76,  24,  50, 126,   0 },  // 122
-  {  14,  24,  24, 112,  24,  24,  14,   0 },  // 123
-  {  24,  24,  24,  24,  24,  24,  24,   0 },  // 124
-  { 112,  24,  24,  14,  24,  24, 112,   0 },  // 125
-  { 118, 220,   0,   0,   0,   0,   0,   0 },  // 126
-  {   0,  16,  56, 108, 198, 198, 254,   0 },  // 127
-  { 124, 198, 192, 192, 198, 124,  12, 120 },  // 128
-  { 204,   0, 204, 204, 204, 204, 118,   0 },  // 129
-  {  12,  24, 124, 198, 254, 192, 124,   0 },  // 130
-  { 124, 130, 120,  12, 124, 204, 118,   0 },  // 131
-  { 198,   0, 120,  12, 124, 204, 118,   0 },  // 132
-  {  48,  24, 120,  12, 124, 204, 118,   0 },  // 133
-  {  48,  48, 120,  12, 124, 204, 118,   0 },  // 134
-  {   0,   0, 126, 192, 192, 126,  12,  56 },  // 135
-  { 124, 130, 124, 198, 254, 192, 124,   0 },  // 136
-  { 198,   0, 124, 198, 254, 192, 124,   0 },  // 137
-  {  48,  24, 124, 198, 254, 192, 124,   0 },  // 138
-  { 102,   0,  56,  24,  24,  24,  60,   0 },  // 139
-  { 124, 130,  56,  24,  24,  24,  60,   0 },  // 140
-  {  48,  24,   0,  56,  24,  24,  60,   0 },  // 141
-  { 198,  56, 108, 198, 254, 198, 198,   0 },  // 142
-  {  56, 108, 124, 198, 254, 198, 198,   0 },  // 143
-  {  24,  48, 254, 192, 248, 192, 254,   0 },  // 144
-  {   0,   0, 126,  18, 254, 144, 254,   0 },  // 145
-  {  62, 108, 204, 254, 204, 204, 206,   0 },  // 146
-  { 124, 130, 124, 198, 198, 198, 124,   0 },  // 147
-  { 198,   0, 124, 198, 198, 198, 124,   0 },  // 148
-  {  48,  24, 124, 198, 198, 198, 124,   0 },  // 149
-  { 120, 132,   0, 204, 204, 204, 118,   0 },  // 150
-  {  96,  48, 204, 204, 204, 204, 118,   0 },  // 151
-  { 198,   0, 198, 198, 198, 126,   6, 252 },  // 152
-  { 198,  56, 108, 198, 198, 108,  56,   0 },  // 153
-  { 198,   0, 198, 198, 198, 198, 124,   0 },  // 154
-  {   0,   2, 124, 206, 214, 230, 124, 128 },  // 155
-  {  56, 108, 100, 240,  96, 102, 252,   0 },  // 156
-  {  58, 108, 206, 214, 230, 108, 184,   0 },  // 157
-  {   0, 198, 108,  56, 108, 198,   0,   0 },  // 158
-  {  14,  27,  24,  60,  24, 216, 112,   0 },  // 159
-  {  24,  48, 120,  12, 124, 204, 118,   0 },  // 160
-  {  12,  24,   0,  56,  24,  24,  60,   0 },  // 161
-  {  12,  24, 124, 198, 198, 198, 124,   0 },  // 162
-  {  24,  48, 204, 204, 204, 204, 118,   0 },  // 163
-  { 118, 220,   0, 220, 102, 102, 102,   0 },  // 164
-  { 118, 220,   0, 230, 246, 222, 206,   0 },  // 165
-  {  60, 108, 108,  62,   0, 126,   0,   0 },  // 166
-  {  56, 108, 108,  56,   0, 124,   0,   0 },  // 167
-  {  24,   0,  24,  24,  48,  99,  62,   0 },  // 168
-  { 126, 129, 185, 165, 185, 165, 129, 126 },  // 169
-  {   0,   0,   0, 254,   6,   6,   0,   0 },  // 170
-  {  99, 230, 108, 126,  51, 102, 204,  15 },  // 171
-  {  99, 230, 108, 122,  54, 106, 223,   6 },  // 172
-  {  24,   0,  24,  24,  60,  60,  24,   0 },  // 173
-  {   0,  51, 102, 204, 102,  51,   0,   0 },  // 174
-  {   0, 204, 102,  51, 102, 204,   0,   0 },  // 175
-  {  34, 136,  34, 136,  34, 136,  34, 136 },  // 176
-  {  85, 170,  85, 170,  85, 170,  85, 170 },  // 177
-  { 119, 221, 119, 221, 119, 221, 119, 221 },  // 178
-  {  24,  24,  24,  24,  24,  24,  24,  24 },  // 179
-  {  24,  24,  56, 248,  56,  24,  24,  24 },  // 180
-  {  48,  96,  56, 108, 198, 254, 198,   0 },  // 181
-  { 124, 130,  56, 108, 198, 254, 198,   0 },  // 182
-  {  24,  12,  56, 108, 198, 254, 198,   0 },  // 183
-  { 126, 129, 157, 161, 161, 157, 129, 126 },  // 184
-  {  54,  54, 246,   6, 246,  54,  54,  54 },  // 185
-  {  54,  54,  54,  54,  54,  54,  54,  54 },  // 186
-  {   0,   0, 254,   6, 246,  54,  54,  54 },  // 187
-  {  54,  54, 246,   6, 254,   0,   0,   0 },  // 188
-  {  24,  24, 126, 192, 192, 126,  24,  24 },  // 189
-  { 102, 102,  60, 126,  24, 126,  24,  24 },  // 190
-  {   0,   0,   0, 240,  56,  24,  24,  24 },  // 191
-  {  24,  24,  28,  15,   0,   0,   0,   0 },  // 192
-  {  24,  24,  60, 255,   0,   0,   0,   0 },  // 193
-  {   0,   0,   0, 255,  60,  24,  24,  24 },  // 194
-  {  48,  48,  56,  63,  56,  48,  48,  48 },  // 195
-  {   0,   0,   0, 255,   0,   0,   0,   0 },  // 196
-  {  24,  24,  24,  60, 231,  60,  24,  24 },  // 197
-  { 240, 120, 120, 120,  60,  60,  60,  28 },  // 198
-  {  30,  60,  60,  60, 120, 120, 120, 112 },  // 199
-  {  15,  63,  63, 120, 120,   0,   1,   3 },  // 200
-  { 192, 224, 240, 240, 240, 240, 240, 224 },  // 201
-  {   0,   0,   0,   0,   0,   0,   0,   0 },  // 202
-  {   0,   0,   0,   0,   0,   0,   0,   0 },  // 203
-  {  30,  30,  14,  15,  15,   7,   7,   0 },  // 204
-  { 240, 240, 224, 224, 192, 192, 192,   0 },  // 205
-  {   6,  13,  27,  55,  47, 127, 126,  30 },  // 206
-  {   0, 252, 255, 255, 143, 119, 243,   3 },  // 207
-  {   0,   1,   7, 143, 143, 207, 207, 199 },  // 208
-  {   0, 248, 254, 254,  31,  15, 192, 248 },  // 209
-  {   0,   0,   0,   0,   0,   0,   0,   0 },  // 210
-  {   0,   0,   0,   0,   0,   0,   0,   0 },  // 211
-  {  30,  30,  30,  31,  15,   7,   7,   1 },  // 212
-  {   3,   3,   3,   7, 143, 255, 254, 252 },  // 213
-  { 195, 192, 192, 207, 143,   7,   7,   1 },  // 214
-  { 254, 255,  31,  15, 143, 254, 254, 248 },  // 215
-  { 102,   0,  60,  24,  24,  24,  60,   0 },  // 216
-  {  24,  24,  56, 240,   0,   0,   0,   0 },  // 217
-  {   0,   0,   0,  15,  28,  24,  24,  24 },  // 218
-  { 255, 255, 255, 255, 255, 255, 255, 255 },  // 219
-  {   0,   0,   0,   0, 255, 255, 255, 255 },  // 220
-  {  24,  24,  24,   0,   0,  24,  24,  24 },  // 221
-  {  48,  24,  60,  24,  24,  24,  60,   0 },  // 222
-  { 255, 255, 255, 255,   0,   0,   0,   0 },  // 223
-  {   0,   0,   0,   0,   0,   0,   0, 255 },  // 224
-  {   0,   0,   0,   0,   0, 255,   0, 255 },  // 225
-  {   0,   0,   0, 255,   0, 255,   0, 255 },  // 226
-  {   0, 255,   0, 255,   0, 255,   0, 255 },  // 227
-  {   0, 255,   0, 255,   0, 255,   0,   0 },  // 228
-  {   0, 255,   0, 255,   0,   0,   0,   0 },  // 229
-  {   0, 255,   0,   0,   0,   0,   0,   0 },  // 230
-  { 224, 128,   0,   0,   0,   0, 128, 224 },  // 231
-  { 248, 254, 255, 255, 255, 255, 254, 248 },  // 232
-  {  24,  48, 198, 198, 198, 198, 124,   0 },  // 233
-  { 124, 130,   0, 198, 198, 198, 124,   0 },  // 234
-  {  96,  48, 198, 198, 198, 198, 124,   0 },  // 235
-  {  24,  48, 198, 198, 198, 126,   6, 252 },  // 236
-  {  12,  24, 102, 102,  60,  24,  60,   0 },  // 237
-  { 255,   0,   0,   0,   0,   0,   0,   0 },  // 238
-  {  12,  24,  48,   0,   0,   0,   0,   0 },  // 239
-  {   0,   0,   0, 126,   0,   0,   0,   0 },  // 240
-  {  24,  24, 126,  24,  24,   0, 126,   0 },  // 241
-  {   0,   0,   0,   0,   0, 255,   0, 255 },  // 242
-  { 225,  50, 228,  58, 246,  42,  95, 134 },  // 243
-  { 127, 219, 219, 123,  27,  27,  27,   0 },  // 244
-  {  62,  97,  60, 102, 102,  60, 134, 124 },  // 245
-  {   0,  24,   0, 126,   0,  24,   0,   0 },  // 246
-  {   0,   0,   0,   0,   0,  24,  12,  56 },  // 247
-  {  56, 108, 108,  56,   0,   0,   0,   0 },  // 248
-  {   0, 198,   0,   0,   0,   0,   0,   0 },  // 249
-  {   0,   0,   0,  24,   0,   0,   0,   0 },  // 250
-  {  24,  56,  24,  24,  60,   0,   0,   0 },  // 251
-  { 120,  12,  56,  12, 120,   0,   0,   0 },  // 252
-  { 120,  12,  24,  48, 124,   0,   0,   0 },  // 253
-  {   0,   0,  60,  60,  60,  60,   0,   0 },  // 254
-  {   0,   0,   0,   0,   0,   0,   0,   0 }}; // 255
-
-/*
-unsigned char sdl_palette[256][3] = {
-  {   0,   0,   0 },  // 0
-  {   0,   0, 168 },  // 1
-  {   0, 168,   0 },  // 2
-  {   0, 168, 168 },  // 3
-  { 168,   0,   0 },  // 4
-  { 168,   0, 168 },  // 5
-  { 168,  84,   0 },  // 6
-  { 168, 168, 168 },  // 7
-  {  84,  84,  84 },  // 8
-  {  84,  84, 252 },  // 9
-  {  84, 252,  84 },  // 10
-  {  84, 252, 252 },  // 11
-  { 252,  84,  84 },  // 12
-  { 252,  84, 252 },  // 13
-  { 252, 252,  84 },  // 14
-  { 252, 252, 252 },  // 15
-  {   0,   0,   0 },  // 16
-  {  20,  20,  20 },  // 17
-  {  32,  32,  32 },  // 18
-  {  44,  44,  44 },  // 19
-  {  56,  56,  56 },  // 20
-  {  68,  68,  68 },  // 21
-  {  80,  80,  80 },  // 22
-  {  96,  96,  96 },  // 23
-  { 112, 112, 112 },  // 24
-  { 128, 128, 128 },  // 25
-  { 144, 144, 144 },  // 26
-  { 160, 160, 160 },  // 27
-  { 180, 180, 180 },  // 28
-  { 200, 200, 200 },  // 29
-  { 224, 224, 224 },  // 30
-  { 252, 252, 252 },  // 31
-  {   0,   0, 252 },  // 32
-  {  64,   0, 252 },  // 33
-  { 124,   0, 252 },  // 34
-  { 188,   0, 252 },  // 35
-  { 252,   0, 252 },  // 36
-  { 252,   0, 188 },  // 37
-  { 252,   0, 124 },  // 38
-  { 252,   0,  64 },  // 39
-  { 252,   0,   0 },  // 40
-  { 252,  64,   0 },  // 41
-  { 252, 124,   0 },  // 42
-  { 252, 188,   0 },  // 43
-  { 252, 252,   0 },  // 44
-  { 188, 252,   0 },  // 45
-  { 124, 252,   0 },  // 46
-  {  64, 252,   0 },  // 47
-  {   0, 252,   0 },  // 48
-  {   0, 252,  64 },  // 49
-  {   0, 252, 124 },  // 50
-  {   0, 252, 188 },  // 51
-  {   0, 252, 252 },  // 52
-  {   0, 188, 252 },  // 53
-  {   0, 124, 252 },  // 54
-  {   0,  64, 252 },  // 55
-  { 124, 124, 252 },  // 56
-  { 156, 124, 252 },  // 57
-  { 188, 124, 252 },  // 58
-  { 220, 124, 252 },  // 59
-  { 252, 124, 252 },  // 60
-  { 252, 124, 220 },  // 61
-  { 252, 124, 188 },  // 62
-  { 252, 124, 156 },  // 63
-  { 252, 124, 124 },  // 64
-  { 252, 156, 124 },  // 65
-  { 252, 188, 124 },  // 66
-  { 252, 220, 124 },  // 67
-  { 252, 252, 124 },  // 68
-  { 220, 252, 124 },  // 69
-  { 188, 252, 124 },  // 70
-  { 156, 252, 124 },  // 71
-  { 124, 252, 124 },  // 72
-  { 124, 252, 156 },  // 73
-  { 124, 252, 188 },  // 74
-  { 124, 252, 220 },  // 75
-  { 124, 252, 252 },  // 76
-  { 124, 220, 252 },  // 77
-  { 124, 188, 252 },  // 78
-  { 124, 156, 252 },  // 79
-  { 180, 180, 252 },  // 80
-  { 196, 180, 252 },  // 81
-  { 216, 180, 252 },  // 82
-  { 232, 180, 252 },  // 83
-  { 252, 180, 252 },  // 84
-  { 252, 180, 232 },  // 85
-  { 252, 180, 216 },  // 86
-  { 252, 180, 196 },  // 87
-  { 252, 180, 180 },  // 88
-  { 252, 196, 180 },  // 89
-  { 252, 216, 180 },  // 90
-  { 252, 232, 180 },  // 91
-  { 252, 252, 180 },  // 92
-  { 232, 252, 180 },  // 93
-  { 216, 252, 180 },  // 94
-  { 196, 252, 180 },  // 95
-  { 180, 252, 180 },  // 96
-  { 180, 252, 196 },  // 97
-  { 180, 252, 216 },  // 98
-  { 180, 252, 232 },  // 99
-  { 180, 252, 252 },  // 100
-  { 180, 232, 252 },  // 101
-  { 180, 216, 252 },  // 102
-  { 180, 196, 252 },  // 103
-  {   0,   0, 112 },  // 104
-  {  28,   0, 112 },  // 105
-  {  56,   0, 112 },  // 106
-  {  84,   0, 112 },  // 107
-  { 112,   0, 112 },  // 108
-  { 112,   0,  84 },  // 109
-  { 112,   0,  56 },  // 110
-  { 112,   0,  28 },  // 111
-  { 112,   0,   0 },  // 112
-  { 112,  28,   0 },  // 113
-  { 112,  56,   0 },  // 114
-  { 112,  84,   0 },  // 115
-  { 112, 112,   0 },  // 116
-  {  84, 112,   0 },  // 117
-  {  56, 112,   0 },  // 118
-  {  28, 112,   0 },  // 119
-  {   0, 112,   0 },  // 120
-  {   0, 112,  28 },  // 121
-  {   0, 112,  56 },  // 122
-  {   0, 112,  84 },  // 123
-  {   0, 112, 112 },  // 124
-  {   0,  84, 112 },  // 125
-  {   0,  56, 112 },  // 126
-  {   0,  28, 112 },  // 127
-  {  56,  56, 112 },  // 128
-  {  68,  56, 112 },  // 129
-  {  84,  56, 112 },  // 130
-  {  96,  56, 112 },  // 131
-  { 112,  56, 112 },  // 132
-  { 112,  56,  96 },  // 133
-  { 112,  56,  84 },  // 134
-  { 112,  56,  68 },  // 135
-  { 112,  56,  56 },  // 136
-  { 112,  68,  56 },  // 137
-  { 112,  84,  56 },  // 138
-  { 112,  96,  56 },  // 139
-  { 112, 112,  56 },  // 140
-  {  96, 112,  56 },  // 141
-  {  84, 112,  56 },  // 142
-  {  68, 112,  56 },  // 143
-  {  56, 112,  56 },  // 144
-  {  56, 112,  68 },  // 145
-  {  56, 112,  84 },  // 146
-  {  56, 112,  96 },  // 147
-  {  56, 112, 112 },  // 148
-  {  56,  96, 112 },  // 149
-  {  56,  84, 112 },  // 150
-  {  56,  68, 112 },  // 151
-  {  80,  80, 112 },  // 152
-  {  88,  80, 112 },  // 153
-  {  96,  80, 112 },  // 154
-  { 104,  80, 112 },  // 155
-  { 112,  80, 112 },  // 156
-  { 112,  80, 104 },  // 157
-  { 112,  80,  96 },  // 158
-  { 112,  80,  88 },  // 159
-  { 112,  80,  80 },  // 160
-  { 112,  88,  80 },  // 161
-  { 112,  96,  80 },  // 162
-  { 112, 104,  80 },  // 163
-  { 112, 112,  80 },  // 164
-  { 104, 112,  80 },  // 165
-  {  96, 112,  80 },  // 166
-  {  88, 112,  80 },  // 167
-  {  80, 112,  80 },  // 168
-  {  80, 112,  88 },  // 169
-  {  80, 112,  96 },  // 170
-  {  80, 112, 104 },  // 171
-  {  80, 112, 112 },  // 172
-  {  80, 104, 112 },  // 173
-  {  80,  96, 112 },  // 174
-  {  80,  88, 112 },  // 175
-  {   0,   0,  64 },  // 176
-  {  16,   0,  64 },  // 177
-  {  32,   0,  64 },  // 178
-  {  48,   0,  64 },  // 179
-  {  64,   0,  64 },  // 180
-  {  64,   0,  48 },  // 181
-  {  64,   0,  32 },  // 182
-  {  64,   0,  16 },  // 183
-  {  64,   0,   0 },  // 184
-  {  64,  16,   0 },  // 185
-  {  64,  32,   0 },  // 186
-  {  64,  48,   0 },  // 187
-  {  64,  64,   0 },  // 188
-  {  48,  64,   0 },  // 189
-  {  32,  64,   0 },  // 190
-  {  16,  64,   0 },  // 191
-  {   0,  64,   0 },  // 192
-  {   0,  64,  16 },  // 193
-  {   0,  64,  32 },  // 194
-  {   0,  64,  48 },  // 195
-  {   0,  64,  64 },  // 196
-  {   0,  48,  64 },  // 197
-  {   0,  32,  64 },  // 198
-  {   0,  16,  64 },  // 199
-  {  32,  32,  64 },  // 200
-  {  40,  32,  64 },  // 201
-  {  48,  32,  64 },  // 202
-  {  56,  32,  64 },  // 203
-  {  64,  32,  64 },  // 204
-  {  64,  32,  56 },  // 205
-  {  64,  32,  48 },  // 206
-  {  64,  32,  40 },  // 207
-  {  64,  32,  32 },  // 208
-  {  64,  40,  32 },  // 209
-  {  64,  48,  32 },  // 210
-  {  64,  56,  32 },  // 211
-  {  64,  64,  32 },  // 212
-  {  56,  64,  32 },  // 213
-  {  48,  64,  32 },  // 214
-  {  40,  64,  32 },  // 215
-  {  32,  64,  32 },  // 216
-  {  32,  64,  40 },  // 217
-  {  32,  64,  48 },  // 218
-  {  32,  64,  56 },  // 219
-  {  32,  64,  64 },  // 220
-  {  32,  56,  64 },  // 221
-  {  32,  48,  64 },  // 222
-  {  32,  40,  64 },  // 223
-  {  44,  44,  64 },  // 224
-  {  48,  44,  64 },  // 225
-  {  52,  44,  64 },  // 226
-  {  60,  44,  64 },  // 227
-  {  64,  44,  64 },  // 228
-  {  64,  44,  60 },  // 229
-  {  64,  44,  52 },  // 230
-  {  64,  44,  48 },  // 231
-  {  64,  44,  44 },  // 232
-  {  64,  48,  44 },  // 233
-  {  64,  52,  44 },  // 234
-  {  64,  60,  44 },  // 235
-  {  64,  64,  44 },  // 236
-  {  60,  64,  44 },  // 237
-  {  52,  64,  44 },  // 238
-  {  48,  64,  44 },  // 239
-  {  44,  64,  44 },  // 240
-  {  44,  64,  48 },  // 241
-  {  44,  64,  52 },  // 242
-  {  44,  64,  60 },  // 243
-  {  44,  64,  64 },  // 244
-  {  44,  60,  64 },  // 245
-  {  44,  52,  64 },  // 246
-  {  44,  48,  64 },  // 247
-  {   0,   0,   0 },  // 248
-  {   0,   0,   0 },  // 249
-  {   0,   0,   0 },  // 250
-  {   0,   0,   0 },  // 251
-  {   0,   0,   0 },  // 252
-  {   0,   0,   0 },  // 253
-  {   0,   0,   0 },  // 254
-  { 112,  97, 108 }}; // 255
-*/
diff --git a/tools/ioemu/gui/sdlkeys.h b/tools/ioemu/gui/sdlkeys.h
deleted file mode 100644 (file)
index fd1197a..0000000
+++ /dev/null
@@ -1,257 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: sdlkeys.h,v 1.2 2002/10/24 21:06:32 bdenney Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-// This file is simply a list of SDL key symbols taken from <SDL/SDL_keysym.h>.
-// The order in this file is not important.  In sdl.cc, DEF_SDL_KEY() is
-// defined as a macro and then it includes this file to fill in all the data in
-// its key mapping table.
-// 
-// The symbols, such as SDLK_RETURN, are used for two purposes.  They
-// are converted into a string (by the # operator in processor), which is 
-// compared to the host key name in the keymap file.  Also, the value of
-// the symbol is inserted into the key mapping table.  Then the value is
-// compared with the keysym field of each key up/down event as it arrives.
-// 
-// If you get undefined symbol errors in this file, it must mean that
-// your SDL library version doesn't define those same SDLK_* symbols in
-// <SDL/SDL_keysym.h>.  You can't fix it with #ifdef SDLK_SYM because
-// they are enums, so you'll just have to comment out the offending line.
-// The list was generated using symbols from SDL 1.2.3.
-
-DEF_SDL_KEY( SDLK_UNKNOWN )
-DEF_SDL_KEY( SDLK_FIRST )
-DEF_SDL_KEY( SDLK_BACKSPACE )
-DEF_SDL_KEY( SDLK_TAB )
-DEF_SDL_KEY( SDLK_CLEAR )
-DEF_SDL_KEY( SDLK_RETURN )
-DEF_SDL_KEY( SDLK_PAUSE )
-DEF_SDL_KEY( SDLK_ESCAPE )
-DEF_SDL_KEY( SDLK_SPACE )
-DEF_SDL_KEY( SDLK_EXCLAIM )
-DEF_SDL_KEY( SDLK_QUOTEDBL )
-DEF_SDL_KEY( SDLK_HASH )
-DEF_SDL_KEY( SDLK_DOLLAR )
-DEF_SDL_KEY( SDLK_AMPERSAND )
-DEF_SDL_KEY( SDLK_QUOTE )
-DEF_SDL_KEY( SDLK_LEFTPAREN )
-DEF_SDL_KEY( SDLK_RIGHTPAREN )
-DEF_SDL_KEY( SDLK_ASTERISK )
-DEF_SDL_KEY( SDLK_PLUS )
-DEF_SDL_KEY( SDLK_COMMA )
-DEF_SDL_KEY( SDLK_MINUS )
-DEF_SDL_KEY( SDLK_PERIOD )
-DEF_SDL_KEY( SDLK_SLASH )
-DEF_SDL_KEY( SDLK_0 )
-DEF_SDL_KEY( SDLK_1 )
-DEF_SDL_KEY( SDLK_2 )
-DEF_SDL_KEY( SDLK_3 )
-DEF_SDL_KEY( SDLK_4 )
-DEF_SDL_KEY( SDLK_5 )
-DEF_SDL_KEY( SDLK_6 )
-DEF_SDL_KEY( SDLK_7 )
-DEF_SDL_KEY( SDLK_8 )
-DEF_SDL_KEY( SDLK_9 )
-DEF_SDL_KEY( SDLK_COLON )
-DEF_SDL_KEY( SDLK_SEMICOLON )
-DEF_SDL_KEY( SDLK_LESS )
-DEF_SDL_KEY( SDLK_EQUALS )
-DEF_SDL_KEY( SDLK_GREATER )
-DEF_SDL_KEY( SDLK_QUESTION )
-DEF_SDL_KEY( SDLK_AT )
-DEF_SDL_KEY( /*  )
-DEF_SDL_KEY( Skip uppercase letters )
-DEF_SDL_KEY( */ )
-DEF_SDL_KEY( SDLK_LEFTBRACKET )
-DEF_SDL_KEY( SDLK_BACKSLASH )
-DEF_SDL_KEY( SDLK_RIGHTBRACKET )
-DEF_SDL_KEY( SDLK_CARET )
-DEF_SDL_KEY( SDLK_UNDERSCORE )
-DEF_SDL_KEY( SDLK_BACKQUOTE )
-DEF_SDL_KEY( SDLK_a )
-DEF_SDL_KEY( SDLK_b )
-DEF_SDL_KEY( SDLK_c )
-DEF_SDL_KEY( SDLK_d )
-DEF_SDL_KEY( SDLK_e )
-DEF_SDL_KEY( SDLK_f )
-DEF_SDL_KEY( SDLK_g )
-DEF_SDL_KEY( SDLK_h )
-DEF_SDL_KEY( SDLK_i )
-DEF_SDL_KEY( SDLK_j )
-DEF_SDL_KEY( SDLK_k )
-DEF_SDL_KEY( SDLK_l )
-DEF_SDL_KEY( SDLK_m )
-DEF_SDL_KEY( SDLK_n )
-DEF_SDL_KEY( SDLK_o )
-DEF_SDL_KEY( SDLK_p )
-DEF_SDL_KEY( SDLK_q )
-DEF_SDL_KEY( SDLK_r )
-DEF_SDL_KEY( SDLK_s )
-DEF_SDL_KEY( SDLK_t )
-DEF_SDL_KEY( SDLK_u )
-DEF_SDL_KEY( SDLK_v )
-DEF_SDL_KEY( SDLK_w )
-DEF_SDL_KEY( SDLK_x )
-DEF_SDL_KEY( SDLK_y )
-DEF_SDL_KEY( SDLK_z )
-DEF_SDL_KEY( SDLK_DELETE )
-DEF_SDL_KEY( SDLK_WORLD_0 )
-DEF_SDL_KEY( SDLK_WORLD_1 )
-DEF_SDL_KEY( SDLK_WORLD_2 )
-DEF_SDL_KEY( SDLK_WORLD_3 )
-DEF_SDL_KEY( SDLK_WORLD_4 )
-DEF_SDL_KEY( SDLK_WORLD_5 )
-DEF_SDL_KEY( SDLK_WORLD_6 )
-DEF_SDL_KEY( SDLK_WORLD_7 )
-DEF_SDL_KEY( SDLK_WORLD_8 )
-DEF_SDL_KEY( SDLK_WORLD_9 )
-DEF_SDL_KEY( SDLK_WORLD_10 )
-DEF_SDL_KEY( SDLK_WORLD_11 )
-DEF_SDL_KEY( SDLK_WORLD_12 )
-DEF_SDL_KEY( SDLK_WORLD_13 )
-DEF_SDL_KEY( SDLK_WORLD_14 )
-DEF_SDL_KEY( SDLK_WORLD_15 )
-DEF_SDL_KEY( SDLK_WORLD_16 )
-DEF_SDL_KEY( SDLK_WORLD_17 )
-DEF_SDL_KEY( SDLK_WORLD_18 )
-DEF_SDL_KEY( SDLK_WORLD_19 )
-DEF_SDL_KEY( SDLK_WORLD_20 )
-DEF_SDL_KEY( SDLK_WORLD_21 )
-DEF_SDL_KEY( SDLK_WORLD_22 )
-DEF_SDL_KEY( SDLK_WORLD_23 )
-DEF_SDL_KEY( SDLK_WORLD_24 )
-DEF_SDL_KEY( SDLK_WORLD_25 )
-DEF_SDL_KEY( SDLK_WORLD_26 )
-DEF_SDL_KEY( SDLK_WORLD_27 )
-DEF_SDL_KEY( SDLK_WORLD_28 )
-DEF_SDL_KEY( SDLK_WORLD_29 )
-DEF_SDL_KEY( SDLK_WORLD_30 )
-DEF_SDL_KEY( SDLK_WORLD_31 )
-DEF_SDL_KEY( SDLK_WORLD_32 )
-DEF_SDL_KEY( SDLK_WORLD_33 )
-DEF_SDL_KEY( SDLK_WORLD_34 )
-DEF_SDL_KEY( SDLK_WORLD_35 )
-DEF_SDL_KEY( SDLK_WORLD_36 )
-DEF_SDL_KEY( SDLK_WORLD_37 )
-DEF_SDL_KEY( SDLK_WORLD_38 )
-DEF_SDL_KEY( SDLK_WORLD_39 )
-DEF_SDL_KEY( SDLK_WORLD_40 )
-DEF_SDL_KEY( SDLK_WORLD_41 )
-DEF_SDL_KEY( SDLK_WORLD_42 )
-DEF_SDL_KEY( SDLK_WORLD_43 )
-DEF_SDL_KEY( SDLK_WORLD_44 )
-DEF_SDL_KEY( SDLK_WORLD_45 )
-DEF_SDL_KEY( SDLK_WORLD_46 )
-DEF_SDL_KEY( SDLK_WORLD_47 )
-DEF_SDL_KEY( SDLK_WORLD_48 )
-DEF_SDL_KEY( SDLK_WORLD_49 )
-DEF_SDL_KEY( SDLK_WORLD_50 )
-DEF_SDL_KEY( SDLK_WORLD_51 )
-DEF_SDL_KEY( SDLK_WORLD_52 )
-DEF_SDL_KEY( SDLK_WORLD_53 )
-DEF_SDL_KEY( SDLK_WORLD_54 )
-DEF_SDL_KEY( SDLK_WORLD_55 )
-DEF_SDL_KEY( SDLK_WORLD_56 )
-DEF_SDL_KEY( SDLK_WORLD_57 )
-DEF_SDL_KEY( SDLK_WORLD_58 )
-DEF_SDL_KEY( SDLK_WORLD_59 )
-DEF_SDL_KEY( SDLK_WORLD_60 )
-DEF_SDL_KEY( SDLK_WORLD_61 )
-DEF_SDL_KEY( SDLK_WORLD_62 )
-DEF_SDL_KEY( SDLK_WORLD_63 )
-DEF_SDL_KEY( SDLK_WORLD_64 )
-DEF_SDL_KEY( SDLK_WORLD_65 )
-DEF_SDL_KEY( SDLK_WORLD_66 )
-DEF_SDL_KEY( SDLK_WORLD_67 )
-DEF_SDL_KEY( SDLK_WORLD_68 )
-DEF_SDL_KEY( SDLK_WORLD_69 )
-DEF_SDL_KEY( SDLK_WORLD_70 )
-DEF_SDL_KEY( SDLK_WORLD_71 )
-DEF_SDL_KEY( SDLK_WORLD_72 )
-DEF_SDL_KEY( SDLK_WORLD_73 )
-DEF_SDL_KEY( SDLK_WORLD_74 )
-DEF_SDL_KEY( SDLK_WORLD_75 )
-DEF_SDL_KEY( SDLK_WORLD_76 )
-DEF_SDL_KEY( SDLK_WORLD_77 )
-DEF_SDL_KEY( SDLK_WORLD_78 )
-DEF_SDL_KEY( SDLK_WORLD_79 )
-DEF_SDL_KEY( SDLK_WORLD_80 )
-DEF_SDL_KEY( SDLK_WORLD_81 )
-DEF_SDL_KEY( SDLK_WORLD_82 )
-DEF_SDL_KEY( SDLK_WORLD_83 )
-DEF_SDL_KEY( SDLK_WORLD_84 )
-DEF_SDL_KEY( SDLK_WORLD_85 )
-DEF_SDL_KEY( SDLK_WORLD_86 )
-DEF_SDL_KEY( SDLK_WORLD_87 )
-DEF_SDL_KEY( SDLK_WORLD_88 )
-DEF_SDL_KEY( SDLK_WORLD_89 )
-DEF_SDL_KEY( SDLK_WORLD_90 )
-DEF_SDL_KEY( SDLK_WORLD_91 )
-DEF_SDL_KEY( SDLK_WORLD_92 )
-DEF_SDL_KEY( SDLK_WORLD_93 )
-DEF_SDL_KEY( SDLK_WORLD_94 )
-DEF_SDL_KEY( SDLK_WORLD_95 )
-DEF_SDL_KEY( SDLK_KP0 )
-DEF_SDL_KEY( SDLK_KP1 )
-DEF_SDL_KEY( SDLK_KP2 )
-DEF_SDL_KEY( SDLK_KP3 )
-DEF_SDL_KEY( SDLK_KP4 )
-DEF_SDL_KEY( SDLK_KP5 )
-DEF_SDL_KEY( SDLK_KP6 )
-DEF_SDL_KEY( SDLK_KP7 )
-DEF_SDL_KEY( SDLK_KP8 )
-DEF_SDL_KEY( SDLK_KP9 )
-DEF_SDL_KEY( SDLK_KP_PERIOD )
-DEF_SDL_KEY( SDLK_KP_DIVIDE )
-DEF_SDL_KEY( SDLK_KP_MULTIPLY )
-DEF_SDL_KEY( SDLK_KP_MINUS )
-DEF_SDL_KEY( SDLK_KP_PLUS )
-DEF_SDL_KEY( SDLK_KP_ENTER )
-DEF_SDL_KEY( SDLK_KP_EQUALS )
-DEF_SDL_KEY( SDLK_UP )
-DEF_SDL_KEY( SDLK_DOWN )
-DEF_SDL_KEY( SDLK_RIGHT )
-DEF_SDL_KEY( SDLK_LEFT )
-DEF_SDL_KEY( SDLK_INSERT )
-DEF_SDL_KEY( SDLK_HOME )
-DEF_SDL_KEY( SDLK_END )
-DEF_SDL_KEY( SDLK_PAGEUP )
-DEF_SDL_KEY( SDLK_PAGEDOWN )
-DEF_SDL_KEY( SDLK_F1 )
-DEF_SDL_KEY( SDLK_F2 )
-DEF_SDL_KEY( SDLK_F3 )
-DEF_SDL_KEY( SDLK_F4 )
-DEF_SDL_KEY( SDLK_F5 )
-DEF_SDL_KEY( SDLK_F6 )
-DEF_SDL_KEY( SDLK_F7 )
-DEF_SDL_KEY( SDLK_F8 )
-DEF_SDL_KEY( SDLK_F9 )
-DEF_SDL_KEY( SDLK_F10 )
-DEF_SDL_KEY( SDLK_F11 )
-DEF_SDL_KEY( SDLK_F12 )
-DEF_SDL_KEY( SDLK_F13 )
-DEF_SDL_KEY( SDLK_F14 )
-DEF_SDL_KEY( SDLK_F15 )
-DEF_SDL_KEY( SDLK_NUMLOCK )
-DEF_SDL_KEY( SDLK_CAPSLOCK )
-DEF_SDL_KEY( SDLK_SCROLLOCK )
-DEF_SDL_KEY( SDLK_RSHIFT )
-DEF_SDL_KEY( SDLK_LSHIFT )
-DEF_SDL_KEY( SDLK_RCTRL )
-DEF_SDL_KEY( SDLK_LCTRL )
-DEF_SDL_KEY( SDLK_RALT )
-DEF_SDL_KEY( SDLK_LALT )
-DEF_SDL_KEY( SDLK_RMETA )
-DEF_SDL_KEY( SDLK_LMETA )
-DEF_SDL_KEY( SDLK_LSUPER )
-DEF_SDL_KEY( SDLK_RSUPER )
-DEF_SDL_KEY( SDLK_MODE )
-DEF_SDL_KEY( SDLK_COMPOSE )
-DEF_SDL_KEY( SDLK_HELP )
-DEF_SDL_KEY( SDLK_PRINT )
-DEF_SDL_KEY( SDLK_SYSREQ )
-DEF_SDL_KEY( SDLK_BREAK )
-DEF_SDL_KEY( SDLK_MENU )
-DEF_SDL_KEY( SDLK_POWER )
-DEF_SDL_KEY( SDLK_EURO )
-DEF_SDL_KEY( SDLK_UNDO )
diff --git a/tools/ioemu/gui/siminterface.cc b/tools/ioemu/gui/siminterface.cc
deleted file mode 100644 (file)
index 0284e6b..0000000
+++ /dev/null
@@ -1,1411 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: siminterface.cc,v 1.105 2004/01/05 22:18:01 cbothamy Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-// See siminterface.h for description of the siminterface concept.
-// Basically, the siminterface is visible from both the simulator and
-// the configuration user interface, and allows them to talk to each other.
-
-#include "bochs.h"
-
-bx_simulator_interface_c *SIM = NULL;
-logfunctions *siminterface_log = NULL;
-#define LOG_THIS siminterface_log->
-
-// bx_simulator_interface just defines the interface that the Bochs simulator
-// and the gui will use to talk to each other.  None of the methods of
-// bx_simulator_interface are implemented; they are all virtual.  The
-// bx_real_sim_c class is a child of bx_simulator_interface_c, and it
-// implements all the methods.  The idea is that a gui needs to know only
-// definition of bx_simulator_interface to talk to Bochs.  The gui should
-// not need to include bochs.h.  
-//
-// I made this separation to ensure that all guis use the siminterface to do
-// access bochs internals, instead of accessing things like
-// bx_keyboard.s.internal_buffer[4] (or whatever) directly. -Bryce
-// 
-
-class bx_real_sim_c : public bx_simulator_interface_c {
-  bxevent_handler bxevent_callback;
-  void *bxevent_callback_data;
-  const char *registered_ci_name;
-  config_interface_callback_t ci_callback;
-  void *ci_callback_data;
-  int init_done;
-  bx_param_c **param_registry;
-  int registry_alloc_size;
-  int enabled;
-  // save context to jump to if we must quit unexpectedly
-  jmp_buf *quit_context;
-  int exit_code;
-public:
-  bx_real_sim_c ();
-  virtual ~bx_real_sim_c ();
-  virtual void set_quit_context (jmp_buf *context) { quit_context = context; }
-  virtual int get_init_done () { return init_done; }
-  virtual int set_init_done (int n) { init_done = n; return 0;}
-  virtual void get_param_id_range (int *min, int *max) {
-    *min = BXP_NULL;
-    *max = BXP_THIS_IS_THE_LAST-1;
-  }
-  virtual int register_param (bx_id id, bx_param_c *it);
-  virtual void reset_all_param ();
-  virtual bx_param_c *get_param (bx_id id);
-  virtual bx_param_num_c *get_param_num (bx_id id);
-  virtual bx_param_string_c *get_param_string (bx_id id);
-  virtual bx_param_bool_c *get_param_bool (bx_id id);
-  virtual bx_param_enum_c *get_param_enum (bx_id id);
-  virtual int get_n_log_modules ();
-  virtual char *get_prefix (int mod);
-  virtual int get_log_action (int mod, int level);
-  virtual void set_log_action (int mod, int level, int action);
-  virtual char *get_action_name (int action);
-  virtual int get_default_log_action (int level) {
-       return logfunctions::get_default_action (level);
-  }
-  virtual void set_default_log_action (int level, int action) {
-       logfunctions::set_default_action (level, action);
-  }
-  virtual const char *get_log_level_name (int level);
-  virtual int get_max_log_level ();
-  virtual void quit_sim (int code);
-  virtual int get_exit_code () { return exit_code; }
-  virtual int get_default_rc (char *path, int len);
-  virtual int read_rc (char *path);
-  virtual int write_rc (char *path, int overwrite);
-  virtual int get_log_file (char *path, int len);
-  virtual int set_log_file (char *path);
-  virtual int get_log_prefix (char *prefix, int len);
-  virtual int set_log_prefix (char *prefix);
-  virtual int get_debugger_log_file (char *path, int len);
-  virtual int set_debugger_log_file (char *path);
-  virtual int get_floppy_options (int drive, bx_floppy_options *out);
-  virtual int get_cdrom_options (int drive, bx_atadevice_options *out, int *device = NULL);
-  virtual char *get_floppy_type_name (int type);
-  virtual void set_notify_callback (bxevent_handler func, void *arg);
-  virtual void get_notify_callback (bxevent_handler *func, void **arg);
-  virtual BxEvent* sim_to_ci_event (BxEvent *event);
-  virtual int log_msg (const char *prefix, int level, const char *msg);
-  virtual int ask_param (bx_id which);
-  // ask the user for a pathname
-  virtual int ask_filename (char *filename, int maxlen, char *prompt, char *the_default, int flags);
-  // called at a regular interval, currently by the keyboard handler.
-  virtual void periodic ();
-  virtual int create_disk_image (const char *filename, int sectors, bx_bool overwrite);
-  virtual void refresh_ci ();
-  virtual void refresh_vga () {
-    // maybe need to check if something has been initialized yet?
-    DEV_vga_refresh();
-  }
-  virtual void handle_events () {
-    // maybe need to check if something has been initialized yet?
-    bx_gui->handle_events ();
-  }
-  // find first hard drive or cdrom
-  bx_param_c *get_first_atadevice (Bit32u search_type);
-  bx_param_c *get_first_cdrom () {
-    return get_first_atadevice (BX_ATA_DEVICE_CDROM);
-  }
-  bx_param_c *get_first_hd () {
-    return get_first_atadevice (BX_ATA_DEVICE_DISK);
-  }
-#if BX_DEBUGGER
-  virtual void debug_break ();
-  virtual void debug_interpret_cmd (char *cmd);
-  virtual char *debug_get_next_command ();
-  virtual void debug_puts (const char *cmd);
-#endif
-  virtual void register_configuration_interface (
-    const char* name, 
-    config_interface_callback_t callback,
-    void *userdata);
-  virtual int configuration_interface(const char* name, ci_command_t command);
-  virtual int begin_simulation (int argc, char *argv[]);
-  virtual void set_sim_thread_func (is_sim_thread_func_t func) {}
-  virtual bool is_sim_thread ();
-  bool wxsel;
-  virtual bool is_wx_selected () { return wxsel; }
-  // provide interface to bx_gui->set_display_mode() method for config
-  // interfaces to use.
-  virtual void set_display_mode (disp_mode_t newmode) {
-    if (bx_gui != NULL)
-      bx_gui->set_display_mode (newmode);
-  }
-  virtual bool test_for_text_console ();
-};
-
-bx_param_c *
-bx_real_sim_c::get_param (bx_id id)
-{
-  BX_ASSERT (id >= BXP_NULL && id < BXP_THIS_IS_THE_LAST);
-  int index = (int)id - BXP_NULL;
-  bx_param_c *retval = param_registry[index];
-  if (!retval) 
-    BX_INFO (("get_param can't find id %u", id));
-  return retval;
-}
-
-bx_param_num_c *
-bx_real_sim_c::get_param_num (bx_id id) {
-  bx_param_c *generic = get_param(id);
-  if (generic==NULL) {
-    BX_PANIC (("get_param_num(%u) could not find a parameter", id));
-    return NULL;
-  }
-  int type = generic->get_type ();
-  if (type == BXT_PARAM_NUM || type == BXT_PARAM_BOOL || type == BXT_PARAM_ENUM)
-    return (bx_param_num_c *)generic;
-  BX_PANIC (("get_param_num %u could not find an integer parameter with that id", id));
-  return NULL;
-}
-
-bx_param_string_c *
-bx_real_sim_c::get_param_string (bx_id id) {
-  bx_param_c *generic = get_param(id);
-  if (generic==NULL) {
-    BX_PANIC (("get_param_string(%u) could not find a parameter", id));
-    return NULL;
-  }
-  if (generic->get_type () == BXT_PARAM_STRING)
-    return (bx_param_string_c *)generic;
-  BX_PANIC (("get_param_string %u could not find an integer parameter with that id", id));
-  return NULL;
-}
-
-bx_param_bool_c *
-bx_real_sim_c::get_param_bool (bx_id id) {
-  bx_param_c *generic = get_param(id);
-  if (generic==NULL) {
-    BX_PANIC (("get_param_bool(%u) could not find a parameter", id));
-    return NULL;
-  }
-  if (generic->get_type () == BXT_PARAM_BOOL)
-    return (bx_param_bool_c *)generic;
-  BX_PANIC (("get_param_bool %u could not find a bool parameter with that id", id));
-  return NULL;
-}
-
-bx_param_enum_c *
-bx_real_sim_c::get_param_enum (bx_id id) {
-  bx_param_c *generic = get_param(id);
-  if (generic==NULL) {
-    BX_PANIC (("get_param_enum(%u) could not find a parameter", id));
-    return NULL;
-  }
-  if (generic->get_type () == BXT_PARAM_ENUM)
-    return (bx_param_enum_c *)generic;
-  BX_PANIC (("get_param_enum %u could not find a enum parameter with that id", id));
-  return NULL;
-}
-
-void bx_init_siminterface ()
-{
-  siminterface_log = new logfunctions ();
-  siminterface_log->put ("CTRL");
-  siminterface_log->settype(CTRLLOG);
-  if (SIM == NULL) 
-    SIM = new bx_real_sim_c();
-}
-
-bx_simulator_interface_c::bx_simulator_interface_c ()
-{
-}
-
-bx_real_sim_c::bx_real_sim_c ()
-{
-  bxevent_callback = NULL;
-  bxevent_callback_data = NULL;
-  ci_callback = NULL;
-  ci_callback_data = NULL;
-  is_sim_thread_func = NULL;
-  wxsel = false;
-  
-  enabled = 1;
-  int i;
-  init_done = 0;
-  registry_alloc_size = BXP_THIS_IS_THE_LAST - BXP_NULL;
-  param_registry = new bx_param_c*  [registry_alloc_size];
-  for (i=0; i<registry_alloc_size; i++)
-    param_registry[i] = NULL;
-  quit_context = NULL;
-  exit_code = 0;
-}
-
-// called by constructor of bx_param_c, so that every parameter that is
-// initialized gets registered.  This builds a list of all parameters
-// which can be used to look them up by number (get_param).
-bx_real_sim_c::~bx_real_sim_c ()
-{
-    if ( param_registry != NULL )
-    {
-        delete [] param_registry;
-        param_registry = NULL;
-    }
-}
-
-int
-bx_real_sim_c::register_param (bx_id id, bx_param_c *it)
-{
-  if (id == BXP_NULL) return 0;
-  BX_ASSERT (id >= BXP_NULL && id < BXP_THIS_IS_THE_LAST);
-  int index = (int)id - BXP_NULL;
-  if (this->param_registry[index] != NULL) {
-    BX_INFO (("register_param is overwriting parameter id %d", id));
-  }
-  this->param_registry[index] = it;
-  return 0;
-}
-
-void 
-bx_real_sim_c::reset_all_param ()
-{
-  bx_reset_options ();
-}
-
-int 
-bx_real_sim_c::get_n_log_modules ()
-{
-  return io->get_n_logfns ();
-}
-
-char *
-bx_real_sim_c::get_prefix (int mod)
-{
-  logfunc_t *logfn = io->get_logfn (mod);
-  return logfn->getprefix ();
-}
-
-int 
-bx_real_sim_c::get_log_action (int mod, int level)
-{
-  logfunc_t *logfn = io->get_logfn (mod);
-  return logfn->getonoff (level);
-}
-
-void 
-bx_real_sim_c::set_log_action (int mod, int level, int action)
-{
-  // normal
-  if (mod >= 0) {
-       logfunc_t *logfn = io->get_logfn (mod);
-       logfn->setonoff (level, action);
-       return;
-  }
-  // if called with mod<0 loop over all
-  int nmod = get_n_log_modules ();
-  for (mod=0; mod<nmod; mod++)
-       set_log_action (mod, level, action);
-}
-
-char *
-bx_real_sim_c::get_action_name (int action)
-{
-  return io->getaction (action);
-}
-
-const char *
-bx_real_sim_c::get_log_level_name (int level)
-{
-  return io->getlevel (level);
-}
-
-int 
-bx_real_sim_c::get_max_log_level ()
-{
-  return N_LOGLEV;
-}
-
-void 
-bx_real_sim_c::quit_sim (int code) {
-  BX_INFO (("quit_sim called with exit code %d", code));
-  exit_code = code;
-  // use longjmp to quit cleanly, no matter where in the stack we are.
-  //fprintf (stderr, "using longjmp() to jump directly to the quit context!\n");
-  if (quit_context != NULL) {
-    longjmp (*quit_context, 1);
-    BX_PANIC (("in bx_real_sim_c::quit_sim, longjmp should never return"));
-  }
-  if (SIM->is_wx_selected ()) {
-    // in wxWindows, the whole simulator is running in a separate thread.
-    // our only job is to end the thread as soon as possible, NOT to shut
-    // down the whole application with an exit.
-    BX_CPU(0)->async_event = 1;
-    BX_CPU(0)->kill_bochs_request = 1;
-    // the cpu loop will exit very soon after this condition is set.
-  } else {
-    // just a single thread.  Use exit() to stop the application.
-    if (!code)
-      BX_PANIC (("Quit simulation command"));
-    ::exit (exit_code);
-  }
-}
-
-int
-bx_real_sim_c::get_default_rc (char *path, int len)
-{
-  char *rc = bx_find_bochsrc ();
-  if (rc == NULL) return -1;
-  strncpy (path, rc, len);
-  path[len-1] = 0;
-  return 0;
-}
-
-int 
-bx_real_sim_c::read_rc (char *rc)
-{
-  return bx_read_configuration (rc);
-}
-
-// return values:
-//   0: written ok
-//  -1: failed
-//  -2: already exists, and overwrite was off
-int 
-bx_real_sim_c::write_rc (char *rc, int overwrite)
-{
-  return bx_write_configuration (rc, overwrite);
-}
-
-int 
-bx_real_sim_c::get_log_file (char *path, int len)
-{
-  strncpy (path, bx_options.log.Ofilename->getptr (), len);
-  return 0;
-}
-
-int 
-bx_real_sim_c::set_log_file (char *path)
-{
-  bx_options.log.Ofilename->set (path);
-  return 0;
-}
-
-int 
-bx_real_sim_c::get_log_prefix (char *prefix, int len)
-{
-  strncpy (prefix, bx_options.log.Oprefix->getptr (), len);
-  return 0;
-}
-
-int 
-bx_real_sim_c::set_log_prefix (char *prefix)
-{
-  bx_options.log.Oprefix->set (prefix);
-  return 0;
-}
-
-int 
-bx_real_sim_c::get_debugger_log_file (char *path, int len)
-{
-  strncpy (path, bx_options.log.Odebugger_filename->getptr (), len);
-  return 0;
-}
-
-int 
-bx_real_sim_c::set_debugger_log_file (char *path)
-{
-  bx_options.log.Odebugger_filename->set (path);
-  return 0;
-}
-
-int 
-bx_real_sim_c::get_floppy_options (int drive, bx_floppy_options *out)
-{
-  *out = (drive==0)? bx_options.floppya : bx_options.floppyb;
-  return 0;
-}
-
-int 
-bx_real_sim_c::get_cdrom_options (int level, bx_atadevice_options *out, int *where)
-{
-  for (Bit8u channel=0; channel<BX_MAX_ATA_CHANNEL; channel++) {
-    for (Bit8u device=0; device<2; device++) {
-      if (bx_options.atadevice[channel][device].Otype->get() == BX_ATA_DEVICE_CDROM) {
-        if (level==0) {
-          *out = bx_options.atadevice[channel][device];
-         if (where != NULL) *where=(channel*2)+device;
-          return 1;
-          }
-        else level--;
-       }
-      }
-    }
-  return 0;
-}
-
-char *bochs_start_names[] = { "quick", "load", "edit", "run" };
-int n_bochs_start_names = 3;
-
-char *floppy_type_names[] = { "none", "1.2M", "1.44M", "2.88M", "720K", "360K", "160K", "180K", "320K", NULL };
-int floppy_type_n_sectors[] = { -1, 80*2*15, 80*2*18, 80*2*36, 80*2*9, 40*2*9, 40*1*8, 40*1*9, 40*2*8 };
-int n_floppy_type_names = 9;
-
-char *floppy_status_names[] = { "ejected", "inserted", NULL };
-int n_floppy_status_names = 2;
-char *floppy_bootdisk_names[] = { "floppy", "disk","cdrom", NULL };
-int n_floppy_bootdisk_names = 3;
-char *loader_os_names[] = { "none", "linux", "nullkernel", NULL };
-int n_loader_os_names = 3;
-char *keyboard_type_names[] = { "xt", "at", "mf", NULL };
-int n_keyboard_type_names = 3;
-
-char *atadevice_type_names[] = { "disk", "cdrom", NULL };
-int n_atadevice_type_names = 2;
-//char *atadevice_mode_names[] = { "flat", "concat", "external", "dll", "sparse", "vmware3", "split", "undoable", "growing", "volatile", "z-undoable", "z-volatile", NULL };
-char *atadevice_mode_names[] = { "flat", "concat", "external", "dll", "sparse", "vmware3", "undoable", "growing", "volatile", NULL };
-int n_atadevice_mode_names = 9;
-char *atadevice_status_names[] = { "ejected", "inserted", NULL };
-int n_atadevice_status_names = 2;
-char *atadevice_biosdetect_names[] = { "none", "auto", "cmos", NULL };
-int n_atadevice_biosdetect_names = 3;
-char *atadevice_translation_names[] = { "none", "lba", "large", "rechs", "auto", NULL };
-int n_atadevice_translation_names = 5;
-char *clock_sync_names[] = { "none", "realtime", "slowdown", "both", NULL };
-int clock_sync_n_names=4;
-
-
-
-char *
-bx_real_sim_c::get_floppy_type_name (int type)
-{
-  BX_ASSERT (type >= BX_FLOPPY_NONE && type <= BX_FLOPPY_LAST);
-  type -= BX_FLOPPY_NONE;
-  return floppy_type_names[type];
-}
-
-void 
-bx_real_sim_c::set_notify_callback (bxevent_handler func, void *arg)
-{
-  bxevent_callback = func;
-  bxevent_callback_data = arg;
-}
-
-void bx_real_sim_c::get_notify_callback (
-    bxevent_handler *func,
-    void **arg)
-{
-  *func = bxevent_callback;
-  *arg = bxevent_callback_data;
-}
-
-BxEvent *
-bx_real_sim_c::sim_to_ci_event (BxEvent *event)
-{
-  if (bxevent_callback == NULL) {
-    BX_ERROR (("notify called, but no bxevent_callback function is registered"));
-    return NULL;
-  } else {
-    return (*bxevent_callback)(bxevent_callback_data, event);
-  }
-}
-
-// returns 0 for continue, 1 for alwayscontinue, 2 for die.
-int 
-bx_real_sim_c::log_msg (const char *prefix, int level, const char *msg)
-{
-  BxEvent be;
-  be.type = BX_SYNC_EVT_LOG_ASK;
-  be.u.logmsg.prefix = prefix;
-  be.u.logmsg.level = level;
-  be.u.logmsg.msg = msg;
-  // default return value in case something goes wrong.
-  be.retcode = BX_LOG_ASK_CHOICE_DIE;
-  //fprintf (stderr, "calling notify.\n");
-  sim_to_ci_event (&be);
-  return be.retcode;
-}
-
-// Called by simulator whenever it needs the user to choose a new value
-// for a registered parameter.  Create a synchronous ASK_PARAM event, 
-// send it to the CI, and wait for the response.  The CI will call the
-// set() method on the parameter if the user changes the value.
-int 
-bx_real_sim_c::ask_param (bx_id param)
-{
-  bx_param_c *paramptr = SIM->get_param(param);
-  BX_ASSERT (paramptr != NULL);
-  // create appropriate event
-  BxEvent event;
-  event.type = BX_SYNC_EVT_ASK_PARAM;
-  event.u.param.param = paramptr;
-  sim_to_ci_event (&event);
-  return event.retcode;
-}
-
-int
-bx_real_sim_c::ask_filename (char *filename, int maxlen, char *prompt, char *the_default, int flags)
-{
-  // implement using ASK_PARAM on a newly created param.  I can't use
-  // ask_param because I don't intend to register this param.
-  BxEvent event;
-  bx_param_string_c param (BXP_NULL, prompt, "filename", the_default, maxlen);
-  flags |= param.IS_FILENAME;
-  param.get_options()->set (flags);
-  event.type = BX_SYNC_EVT_ASK_PARAM;
-  event.u.param.param = &param;
-  sim_to_ci_event (&event);
-  if (event.retcode >= 0)
-    memcpy (filename, param.getptr(), maxlen);
-  return event.retcode;
-}
-
-void
-bx_real_sim_c::periodic ()
-{
-  // give the GUI a chance to do periodic things on the bochs thread. in 
-  // particular, notice if the thread has been asked to die.
-  BxEvent tick;
-  tick.type = BX_SYNC_EVT_TICK;
-  sim_to_ci_event (&tick);
-  if (tick.retcode < 0) {
-    BX_INFO (("Bochs thread has been asked to quit."));
-    bx_atexit ();
-    quit_sim (0);
-  }
-  static int refresh_counter = 0;
-  if (++refresh_counter == 50) {
-    // only ask the CI to refresh every 50 times periodic() is called.
-    // This should obviously be configurable because system speeds and
-    // user preferences vary.
-    refresh_ci ();
-    refresh_counter = 0;
-  }
-#if 0
-  // watch for memory leaks.  Allocate a small block of memory, print the
-  // pointer that is returned, then free.
-  BxEvent *memcheck = new BxEvent ();
-  BX_INFO(("memory allocation at %p", memcheck));
-  delete memcheck;
-#endif
-}
-
-// create a disk image file called filename, size=512 bytes * sectors.
-// If overwrite is true and the file exists, returns -1 without changing it.
-// Otherwise, opens up the image and starts writing.  Returns -2 if
-// the image could not be opened, or -3 if there are failures during
-// write, e.g. disk full.
-// 
-// wxWindows: This may be called from the gui thread.
-int 
-bx_real_sim_c::create_disk_image (
-    const char *filename,
-    int sectors,
-    bx_bool overwrite) 
-{
-  FILE *fp;
-  if (!overwrite) {
-    // check for existence first
-    fp = fopen (filename, "r");
-    if (fp) {
-      // yes it exists
-      fclose (fp);
-      return -1;
-    }
-  }
-  fp = fopen (filename, "w");
-  if (fp == NULL) {
-#ifdef HAVE_PERROR
-    char buffer[1024];
-    sprintf (buffer, "while opening '%s' for writing", filename);
-    perror (buffer);
-    // not sure how to get this back into the CI
-#endif
-    return -2;
-  }
-  int sec = sectors;
-  /*
-   * seek to sec*512-1 and write a single character.
-   * can't just do: fseek(fp, 512*sec-1, SEEK_SET)
-   * because 512*sec may be too large for signed int.
-   */
-  while (sec > 0)
-  {
-    /* temp <-- min(sec, 4194303)
-     * 4194303 is (int)(0x7FFFFFFF/512)
-     */
-    int temp = ((sec < 4194303) ? sec : 4194303);
-    fseek(fp, 512*temp, SEEK_CUR);
-    sec -= temp;
-  }
-
-  fseek(fp, -1, SEEK_CUR);
-  if (fputc('\0', fp) == EOF)
-  {
-    fclose (fp);
-    return -3;
-  }
-  fclose (fp);
-  return 0;
-}
-
-void bx_real_sim_c::refresh_ci () {
-  if (SIM->is_wx_selected ()) {
-    // presently, only wxWindows interface uses these events
-    // It's an async event, so allocate a pointer and send it.
-    // The event will be freed by the recipient.
-    BxEvent *event = new BxEvent ();
-    event->type = BX_ASYNC_EVT_REFRESH;
-    sim_to_ci_event (event);
-  }
-}
-
-bx_param_c *
-bx_real_sim_c::get_first_atadevice (Bit32u search_type) {
-  for (int channel=0; channel<BX_MAX_ATA_CHANNEL; channel++) {
-    if (!bx_options.ata[channel].Opresent->get ())
-      continue;
-    for (int slave=0; slave<2; slave++) {
-      Bit32u present = bx_options.atadevice[channel][slave].Opresent->get ();
-      Bit32u type = bx_options.atadevice[channel][slave].Otype->get ();
-      if (present && (type == search_type)) {
-       return bx_options.atadevice[channel][slave].Omenu;
-      }
-    }
-  }
-  return NULL;
-}
-
-#if BX_DEBUGGER
-
-// this can be safely called from either thread.
-void bx_real_sim_c::debug_break () {
-  bx_debug_break ();
-}
-
-// this should only be called from the sim_thread.
-void bx_real_sim_c::debug_interpret_cmd (char *cmd) {
-  if (!is_sim_thread ()) {
-    fprintf (stderr, "ERROR: debug_interpret_cmd called but not from sim_thread\n");
-    return;
-  }
-  bx_dbg_interpret_line (cmd);
-}
-
-char *bx_real_sim_c::debug_get_next_command ()
-{
-  fprintf (stderr, "begin debug_get_next_command\n");
-  BxEvent event;
-  event.type = BX_SYNC_EVT_GET_DBG_COMMAND;
-  BX_INFO (("asking for next debug command"));
-  sim_to_ci_event (&event);
-  BX_INFO (("received next debug command: '%s'", event.u.debugcmd.command));
-  if (event.retcode >= 0)
-    return event.u.debugcmd.command;
-  return NULL;
-}
-
-void bx_real_sim_c::debug_puts (const char *text)
-{
-  if (SIM->is_wx_selected ()) {
-    // send message to the wxWindows debugger
-    BxEvent *event = new BxEvent ();
-    event->type = BX_ASYNC_EVT_DBG_MSG;
-    event->u.logmsg.msg = text;
-    sim_to_ci_event (event);
-    // the event will be freed by the recipient
-  } else {
-    // text mode debugger: just write to console
-    fputs (text, stderr);
-    delete [] (char *)text;
-  }
-}
-#endif
-
-void 
-bx_real_sim_c::register_configuration_interface (
-  const char* name, 
-  config_interface_callback_t callback,
-  void *userdata)
-{
-  ci_callback = callback;
-  ci_callback_data = userdata;
-  registered_ci_name = name;
-}
-
-int 
-bx_real_sim_c::configuration_interface(const char *ignore, ci_command_t command)
-{
-  bx_param_enum_c *ci_param = SIM->get_param_enum (BXP_SEL_CONFIG_INTERFACE);
-  char *name = ci_param->get_choice (ci_param->get ());
-  if (!ci_callback) {
-    BX_PANIC (("no configuration interface was loaded"));
-    return -1;
-  }
-  if (strcmp (name, registered_ci_name) != 0) {
-    BX_PANIC (("siminterface does not support loading one configuration interface and then calling another"));
-    return -1;
-  }
-  if (!strcmp (name, "wx")) 
-    wxsel = true;
-  else
-    wxsel = false;
-  // enter configuration mode, just while running the configuration interface
-  set_display_mode (DISP_MODE_CONFIG);
-  int retval = (*ci_callback)(ci_callback_data, command);
-  set_display_mode (DISP_MODE_SIM);
-  return retval;
-}
-
-int 
-bx_real_sim_c::begin_simulation (int argc, char *argv[])
-{
-  return bx_begin_simulation (argc, argv);
-}
-
-bool bx_real_sim_c::is_sim_thread ()
-{
-  if (is_sim_thread_func == NULL) return true;
-  return (*is_sim_thread_func)();
-}
-
-// check if the text console exists.  On some platforms, if Bochs is
-// started from the "Start Menu" or by double clicking on it on a Mac,
-// there may be nothing attached to stdin/stdout/stderr.  This function
-// tests if stdin/stdout/stderr are usable and returns false if not.
-bool 
-bx_real_sim_c::test_for_text_console ()
-{
-#if BX_WITH_CARBON
-  // In a Carbon application, you have a text console if you run the app from
-  // the command line, but if you start it from the finder you don't.
-  if(!isatty(STDIN_FILENO)) return false;
-#endif
-  // default: yes
-  return true;
-}
-
-
-/////////////////////////////////////////////////////////////////////////
-// define methods of bx_param_* and family
-/////////////////////////////////////////////////////////////////////////
-
-bx_object_c::bx_object_c (bx_id id)
-{
-  this->id = id;
-  this->type = BXT_OBJECT;
-}
-
-void
-bx_object_c::set_type (bx_objtype type)
-{
-  this->type = type;
-}
-
-const char* bx_param_c::default_text_format = NULL;
-
-bx_param_c::bx_param_c (bx_id id, char *name, char *description)
-  : bx_object_c (id)
-{
-  set_type (BXT_PARAM);
-  this->name = name;
-  this->description = description;
-  this->text_format = default_text_format;
-  this->ask_format = NULL;
-  this->label = NULL;
-  this->runtime_param = 0;
-  this->enabled = 1;
-  SIM->register_param (id, this);
-}
-
-const char* bx_param_c::set_default_format (const char *f) {
-  const char *old = default_text_format;
-  default_text_format = f; 
-  return old;
-}
-
-bx_param_num_c::bx_param_num_c (bx_id id,
-    char *name,
-    char *description,
-    Bit64s min, Bit64s max, Bit64s initial_val)
-  : bx_param_c (id, name, description)
-{
-  set_type (BXT_PARAM_NUM);
-  this->min = min;
-  this->max = max;
-  this->initial_val = initial_val;
-  this->val.number = initial_val;
-  this->handler = NULL;
-  this->enable_handler = NULL;
-  this->base = default_base;
-  // dependent_list must be initialized before the set(),
-  // because set calls update_dependents().
-  dependent_list = NULL;
-  set (initial_val);
-}
-
-Bit32u bx_param_num_c::default_base = 10;
-
-Bit32u bx_param_num_c::set_default_base (Bit32u val) {
-  Bit32u old = default_base;
-  default_base = val; 
-  return old;
-}
-
-void 
-bx_param_num_c::reset ()
-{
-  this->val.number = initial_val;
-}
-
-void 
-bx_param_num_c::set_handler (param_event_handler handler)
-{ 
-  this->handler = handler; 
-  // now that there's a handler, call set once to run the handler immediately
-  //set (get ());
-}
-
-void 
-bx_param_num_c::set_enable_handler (param_enable_handler handler)
-{ 
-  this->enable_handler = handler; 
-}
-
-void bx_param_num_c::set_dependent_list (bx_list_c *l) {
-  dependent_list = l; 
-  update_dependents ();
-}
-
-Bit64s 
-bx_param_num_c::get64 ()
-{
-  if (handler) {
-    // the handler can decide what value to return and/or do some side effect
-    return (*handler)(this, 0, val.number);
-  } else {
-    // just return the value
-    return val.number;
-  }
-}
-
-void
-bx_param_num_c::set (Bit64s newval)
-{
-  if (handler) {
-    // the handler can override the new value and/or perform some side effect
-    val.number = newval;
-    (*handler)(this, 1, newval);
-  } else {
-    // just set the value.  This code does not check max/min.
-    val.number = newval;
-  }
-  if ((val.number < min || val.number > max) && (Bit64u)max != BX_MAX_BIT64U)
-    BX_PANIC (("numerical parameter %s was set to " FMT_LL "d, which is out of range " FMT_LL "d to " FMT_LL "d", get_name (), val.number, min, max));
-  if (dependent_list != NULL) update_dependents ();
-}
-
-void bx_param_num_c::set_range (Bit64u min, Bit64u max)
-{
-  this->min = min;
-  this->max = max;
-}
-
-void bx_param_num_c::set_initial_val (Bit64s initial_val) { 
-  this->val.number = this->initial_val = initial_val;
-}
-
-void bx_param_num_c::update_dependents ()
-{
-  if (dependent_list) {
-    int en = val.number && enabled;
-    for (int i=0; i<dependent_list->get_size (); i++) {
-      bx_param_c *param = dependent_list->get (i);
-      if (param != this)
-       param->set_enabled (en);
-    }
-  }
-}
-
-void
-bx_param_num_c::set_enabled (int en)
-{
-  // The enable handler may wish to allow/disallow the action
-  if (enable_handler) {
-    en = (*enable_handler) (this, en);
-    }
-  bx_param_c::set_enabled (en);
-  update_dependents ();
-}
-
-// Signed 64 bit
-bx_shadow_num_c::bx_shadow_num_c (bx_id id,
-    char *name,
-    char *description,
-    Bit64s *ptr_to_real_val,
-    Bit8u highbit,
-    Bit8u lowbit)
-: bx_param_num_c (id, name, description, BX_MIN_BIT64S, BX_MAX_BIT64S, *ptr_to_real_val)
-{
-  this->varsize = 16;
-  this->lowbit = lowbit;
-  this->mask = (1 << (highbit - lowbit)) - 1;
-  val.p64bit = ptr_to_real_val;
-}
-
-// Unsigned 64 bit
-bx_shadow_num_c::bx_shadow_num_c (bx_id id,
-    char *name,
-    char *description,
-    Bit64u *ptr_to_real_val,
-    Bit8u highbit,
-    Bit8u lowbit)
-: bx_param_num_c (id, name, description, BX_MIN_BIT64U, BX_MAX_BIT64U, *ptr_to_real_val)
-{
-  this->varsize = 16;
-  this->lowbit = lowbit;
-  this->mask = (1 << (highbit - lowbit)) - 1;
-  val.p64bit = (Bit64s*) ptr_to_real_val;
-}
-
-// Signed 32 bit
-bx_shadow_num_c::bx_shadow_num_c (bx_id id,
-    char *name,
-    char *description,
-    Bit32s *ptr_to_real_val,
-    Bit8u highbit,
-    Bit8u lowbit)
-: bx_param_num_c (id, name, description, BX_MIN_BIT32S, BX_MAX_BIT32S, *ptr_to_real_val)
-{
-  this->varsize = 16;
-  this->lowbit = lowbit;
-  this->mask = (1 << (highbit - lowbit)) - 1;
-  val.p32bit = ptr_to_real_val;
-}
-
-// Unsigned 32 bit
-bx_shadow_num_c::bx_shadow_num_c (bx_id id,
-    char *name,
-    char *description,
-    Bit32u *ptr_to_real_val,
-    Bit8u highbit,
-    Bit8u lowbit)
-: bx_param_num_c (id, name, description, BX_MIN_BIT32U, BX_MAX_BIT32U, *ptr_to_real_val)
-{
-  this->varsize = 32;
-  this->lowbit = lowbit;
-  this->mask = (1 << (highbit - lowbit)) - 1;
-  val.p32bit = (Bit32s*) ptr_to_real_val;
-}
-
-// Signed 16 bit
-bx_shadow_num_c::bx_shadow_num_c (bx_id id,
-    char *name,
-    char *description,
-    Bit16s *ptr_to_real_val,
-    Bit8u highbit,
-    Bit8u lowbit)
-: bx_param_num_c (id, name, description, BX_MIN_BIT16S, BX_MAX_BIT16S, *ptr_to_real_val)
-{
-  this->varsize = 16;
-  this->lowbit = lowbit;
-  this->mask = (1 << (highbit - lowbit)) - 1;
-  val.p16bit = ptr_to_real_val;
-}
-
-// Unsigned 16 bit
-bx_shadow_num_c::bx_shadow_num_c (bx_id id,
-    char *name,
-    char *description,
-    Bit16u *ptr_to_real_val,
-    Bit8u highbit,
-    Bit8u lowbit)
-: bx_param_num_c (id, name, description, BX_MIN_BIT16U, BX_MAX_BIT16U, *ptr_to_real_val)
-{
-  this->varsize = 16;
-  this->lowbit = lowbit;
-  this->mask = (1 << (highbit - lowbit)) - 1;
-  val.p16bit = (Bit16s*) ptr_to_real_val;
-}
-
-// Signed 8 bit
-bx_shadow_num_c::bx_shadow_num_c (bx_id id,
-    char *name,
-    char *description,
-    Bit8s *ptr_to_real_val,
-    Bit8u highbit,
-    Bit8u lowbit)
-: bx_param_num_c (id, name, description, BX_MIN_BIT8S, BX_MAX_BIT8S, *ptr_to_real_val)
-{
-  this->varsize = 16;
-  this->lowbit = lowbit;
-  this->mask = (1 << (highbit - lowbit)) - 1;
-  val.p8bit = ptr_to_real_val;
-}
-
-// Unsigned 8 bit
-bx_shadow_num_c::bx_shadow_num_c (bx_id id,
-    char *name,
-    char *description,
-    Bit8u *ptr_to_real_val,
-    Bit8u highbit,
-    Bit8u lowbit)
-: bx_param_num_c (id, name, description, BX_MIN_BIT8U, BX_MAX_BIT8U, *ptr_to_real_val)
-{
-  this->varsize = 8;
-  this->lowbit = lowbit;
-  this->mask = (1 << (highbit - lowbit)) - 1;
-  val.p8bit = (Bit8s*) ptr_to_real_val;
-}
-
-Bit64s
-bx_shadow_num_c::get64 () {
-  Bit64u current = 0;
-  switch (varsize) {
-    case 8: current = *(val.p8bit);  break;
-    case 16: current = *(val.p16bit);  break;
-    case 32: current = *(val.p32bit);  break;
-    case 64: current = *(val.p64bit);  break;
-    default: BX_PANIC(("unsupported varsize %d", varsize));
-  }
-  current = (current >> lowbit) & mask;
-  if (handler) {
-    // the handler can decide what value to return and/or do some side effect
-    return (*handler)(this, 0, current) & mask;
-  } else {
-    // just return the value
-    return current;
-  }
-}
-
-void
-bx_shadow_num_c::set (Bit64s newval)
-{
-  Bit64u tmp = 0;
-  if ((newval < min || newval > max) && (Bit64u)max != BX_MAX_BIT64U)
-    BX_PANIC (("numerical parameter %s was set to " FMT_LL "d, which is out of range " FMT_LL "d to " FMT_LL "d", get_name (), newval, min, max));
-  switch (varsize) {
-    case 8: 
-      tmp = (*(val.p8bit) >> lowbit) & mask;
-      tmp |= (newval & mask) << lowbit;
-      *(val.p8bit) = (Bit8s)tmp;
-      break;
-    case 16:
-      tmp = (*(val.p16bit) >> lowbit) & mask;
-      tmp |= (newval & mask) << lowbit;
-      *(val.p16bit) = (Bit16s)tmp;
-      break;
-    case 32:
-      tmp = (*(val.p32bit) >> lowbit) & mask;
-      tmp |= (newval & mask) << lowbit;
-      *(val.p32bit) = (Bit32s)tmp;
-      break;
-    case 64:
-      tmp = (*(val.p64bit) >> lowbit) & mask;
-      tmp |= (newval & mask) << lowbit;
-      *(val.p64bit) = tmp;
-      break;
-    default: 
-      BX_PANIC(("unsupported varsize %d", varsize));
-  }
-  if (handler) {
-    // the handler can override the new value and/or perform some side effect
-    (*handler)(this, 1, tmp);
-  }
-}
-
-bx_param_bool_c::bx_param_bool_c (bx_id id,
-    char *name,
-    char *description,
-    Bit64s initial_val)
-  : bx_param_num_c (id, name, description, 0, 1, initial_val)
-{
-  set_type (BXT_PARAM_BOOL);
-  set (initial_val);
-}
-
-bx_shadow_bool_c::bx_shadow_bool_c (bx_id id,
-      char *name,
-      char *description,
-      bx_bool *ptr_to_real_val,
-      Bit8u bitnum)
-  : bx_param_bool_c (id, name, description, (Bit64s) *ptr_to_real_val)
-{
-  val.pbool = ptr_to_real_val;
-  this->bitnum = bitnum;
-}
-
-Bit64s
-bx_shadow_bool_c::get64 () {
-  if (handler) {
-    // the handler can decide what value to return and/or do some side effect
-    Bit64s ret = (*handler)(this, 0, (Bit64s) *(val.pbool));
-    return (ret>>bitnum) & 1;
-  } else {
-    // just return the value
-    return (*(val.pbool)) & 1;
-  }
-}
-
-void
-bx_shadow_bool_c::set (Bit64s newval)
-{
-  // only change the bitnum bit
-  Bit64s tmp = (newval&1) << bitnum;
-  *(val.pbool) &= ~tmp;
-  *(val.pbool) |= tmp;
-  if (handler) {
-    // the handler can override the new value and/or perform some side effect
-    (*handler)(this, 1, newval&1);
-  }
-}
-
-bx_param_enum_c::bx_param_enum_c (bx_id id, 
-      char *name,
-      char *description,
-      char **choices,
-      Bit64s initial_val,
-      Bit64s value_base)
-  : bx_param_num_c (id, name, description, value_base, BX_MAX_BIT64S, initial_val)
-{
-  set_type (BXT_PARAM_ENUM);
-  this->choices = choices;
-  // count number of choices, set max
-  char **p = choices;
-  while (*p != NULL) p++;
-  this->min = value_base;
-  // now that the max is known, replace the BX_MAX_BIT64S sent to the parent
-  // class constructor with the real max.
-  this->max = value_base + (p - choices - 1);
-  set (initial_val);
-}
-
-int 
-bx_param_enum_c::find_by_name (const char *string)
-{
-  char **p;
-  for (p=&choices[0]; *p; p++) {
-    if (!strcmp (string, *p))
-      return p-choices;
-  }
-  return -1;
-}
-
-bool 
-bx_param_enum_c::set_by_name (const char *string)
-{
-  int n = find_by_name (string);
-  if (n<0) return false;
-  set (n);
-  return true;
-}
-
-bx_param_string_c::bx_param_string_c (bx_id id,
-    char *name,
-    char *description,
-    char *initial_val,
-    int maxsize)
-  : bx_param_c (id, name, description)
-{
-  set_type (BXT_PARAM_STRING);
-  if (maxsize < 0) 
-    maxsize = strlen(initial_val) + 1;
-  this->val = new char[maxsize];
-  this->initial_val = new char[maxsize];
-  this->handler = NULL;
-  this->enable_handler = NULL;
-  this->maxsize = maxsize;
-  strncpy (this->val, initial_val, maxsize);
-  strncpy (this->initial_val, initial_val, maxsize);
-  this->options = new bx_param_num_c (BXP_NULL,
-      "stringoptions", NULL, 0, BX_MAX_BIT64S, 0);
-  set (initial_val);
-}
-
-bx_param_filename_c::bx_param_filename_c (bx_id id,
-    char *name,
-    char *description,
-    char *initial_val,
-    int maxsize)
-  : bx_param_string_c (id, name, description, initial_val, maxsize)
-{
-  get_options()->set (IS_FILENAME);
-}
-
-bx_param_string_c::~bx_param_string_c ()
-{
-    if ( this->val != NULL )
-    {
-        delete [] this->val;
-        this->val = NULL;
-    }
-    if ( this->initial_val != NULL )
-    {
-        delete [] this->initial_val;
-        this->initial_val = NULL;
-    }
-
-    if ( this->options != NULL )
-    {
-        delete [] this->options;
-        this->options = NULL;
-    }
-}
-
-void 
-bx_param_string_c::reset () {
-  strncpy (this->val, this->initial_val, maxsize);
-}
-
-void 
-bx_param_string_c::set_handler (param_string_event_handler handler)
-{
-  this->handler = handler; 
-  // now that there's a handler, call set once to run the handler immediately
-  //set (getptr ());
-}
-
-void 
-bx_param_string_c::set_enable_handler (param_enable_handler handler)
-{ 
-  this->enable_handler = handler; 
-}
-
-void
-bx_param_string_c::set_enabled (int en)
-{
-  // The enable handler may wish to allow/disallow the action
-  if (enable_handler) {
-    en = (*enable_handler) (this, en);
-    }
-  bx_param_c::set_enabled (en);
-}
-
-Bit32s
-bx_param_string_c::get (char *buf, int len)
-{
-  if (options->get () & RAW_BYTES)
-    memcpy (buf, val, len);
-  else
-    strncpy (buf, val, len);
-  if (handler) {
-    // the handler can choose to replace the value in val/len.  Also its
-    // return value is passed back as the return value of get.
-    (*handler)(this, 0, buf, len);
-  }
-  return 0;
-}
-
-void 
-bx_param_string_c::set (char *buf)
-{
-  if (options->get () & RAW_BYTES)
-    memcpy (val, buf, maxsize);
-  else
-    strncpy (val, buf, maxsize);
-  if (handler) {
-    // the handler can return a different char* to be copied into the value
-    buf = (*handler)(this, 1, buf, -1);
-  }
-}
-
-bx_bool
-bx_param_string_c::equals (const char *buf)
-{
-  if (options->get () & RAW_BYTES)
-    return (memcmp (val, buf, maxsize) == 0);
-  else
-    return (strncmp (val, buf, maxsize) == 0);
-}
-
-bx_list_c::bx_list_c (bx_id id, int maxsize)
-  : bx_param_c (id, "list", "")
-{
-  set_type (BXT_LIST);
-  this->size = 0;
-  this->maxsize = maxsize;
-  this->list = new bx_param_c*  [maxsize];
-  init ();
-}
-
-bx_list_c::bx_list_c (bx_id id, char *name, char *description, int maxsize)
-  : bx_param_c (id, name, description)
-{
-  set_type (BXT_LIST);
-  this->size = 0;
-  this->maxsize = maxsize;
-  this->list = new bx_param_c*  [maxsize];
-  init ();
-}
-
-bx_list_c::bx_list_c (bx_id id, char *name, char *description, bx_param_c **init_list)
-  : bx_param_c (id, name, description)
-{
-  set_type (BXT_LIST);
-  this->size = 0;
-  while (init_list[this->size] != NULL)
-    this->size++;
-  this->maxsize = this->size;
-  this->list = new bx_param_c*  [maxsize];
-  for (int i=0; i<this->size; i++)
-    this->list[i] = init_list[i];
-  init ();
-}
-
-bx_list_c::~bx_list_c()
-{
-    if (this->list)
-    {
-        delete [] this->list;
-        this->list = NULL;
-    }
-    if ( this->title != NULL)
-    {
-        delete this->title;
-        this->title = NULL;
-    }
-    if (this->options != NULL)
-    {
-        delete this->options;
-        this->options = NULL;
-    }
-    if ( this->choice != NULL )
-    {
-        delete this->choice;
-        this->choice = NULL;
-    }
-}
-
-void
-bx_list_c::init ()
-{
-  // the title defaults to the name
-  this->title = new bx_param_string_c (BXP_NULL,
-      "title of list",
-      "",
-      get_name (), 80);
-  this->options = new bx_param_num_c (BXP_NULL,
-      "list_option", "", 0, BX_MAX_BIT64S,
-      0);
-  this->choice = new bx_param_num_c (BXP_NULL,
-      "list_choice", "", 0, BX_MAX_BIT64S,
-      1);
-  this->parent = NULL;
-}
-
-bx_list_c *
-bx_list_c::clone ()
-{
-  bx_list_c *newlist = new bx_list_c (BXP_NULL, name, description, maxsize);
-  for (int i=0; i<get_size (); i++)
-    newlist->add (get(i));
-  newlist->set_options (get_options ());
-  newlist->set_parent (get_parent ());
-  return newlist;
-}
-
-void
-bx_list_c::add (bx_param_c *param)
-{
-  if (this->size >= this->maxsize)
-    BX_PANIC (("add param %u to bx_list_c id=%u: list capacity exceeded", param->get_id (), get_id ()));
-  list[size] = param;
-  size++;
-}
-
-bx_param_c *
-bx_list_c::get (int index)
-{
-  BX_ASSERT (index >= 0 && index < size);
-  return list[index];
-}
-
diff --git a/tools/ioemu/gui/siminterface.h b/tools/ioemu/gui/siminterface.h
deleted file mode 100644 (file)
index 9a02847..0000000
+++ /dev/null
@@ -1,1460 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: siminterface.h,v 1.113.2.2 2004/02/06 22:14:35 danielg4 Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-// Before I can describe what this file is for, I have to make the
-// distinction between a configuration interface (CI) and the VGA display
-// window (VGAW).  I will try to avoid the term 'GUI' because it is unclear 
-// if that means CI or VGAW, and because not all interfaces are graphical 
-// anyway.
-//
-// The traditional Bochs screen is a window with a large VGA display panel and
-// a series of buttons (floppy, cdrom, snapshot, power).  Over the years, we
-// have collected many implementations of the VGAW for different environments
-// and platforms; each implementation is in a separate file under gui/*:
-// x.cc, win32.cc, beos.cc, macintosh.cc, etc.  The files gui.h and gui.cc
-// define the platform independent part of the VGAW, leaving about 15 methods
-// of the bx_gui_c class undefined.  The platform dependent file must 
-// implement the remaining 15 methods.
-//
-// The configuration interface is relatively new, started by Bryce Denney in
-// June 2001.  The CI is intended to allow the user to edit a variety of
-// configuration and runtime options.  Some options, such as memory size or
-// enabling the ethernet card, should only be changed before the simulation
-// begins; others, such as floppy disk image, instructions per second, and
-// logging options can be safely changed at runtime.  The CI allows the user to
-// make these changes.  Before the CI existed, only a few things could be
-// changed at runtime, all linked to clicking on the VGAW buttons.
-//
-// At the time that the CI was conceived, we were still debating what form the
-// user interface part would take: stdin/stdout menus, a graphical application
-// with menus and dialogs running in a separate thread, or even a tiny web
-// server that you can connect to with a web browser.  As a result the
-// interface to the CI was designed so that the user interface of the CI 
-// could be replaced easily at compile time, or maybe even at runtime via
-// a plugin architecture.  To this end, we kept a clear separation between
-// the user interface code and the siminterface, the code that interfaces with
-// the simulator.  The same siminterface is used all the time, while 
-// different implementations of the CI can be switched in reasonably easily.
-// Only the CI code uses library specific graphics and I/O functions; the
-// siminterface deals in portable abstractions and callback functions.
-// The first CI implementation was a series of text mode menus implemented in
-// control.cc.
-//
-// The configuration interface MUST use the siminterface methods to access the
-// simulator.  It should not modify settings in some device with code like
-// bx_floppy.s.media[2].heads = 17.  If such access is needed, then a
-// siminterface method should be written to make the change on the CI's behalf.
-// This separation is enforced by the fact that the CI does not even include
-// bochs.h.  You'll notice that control.cc include osdep.h, control.h, and
-// siminterface.h, so it doesn't know what bx_floppy or bx_cpu_c are.  I'm sure
-// some people will say is overly restrictive and/or annoying.  When I set it
-// up this way, we were still talking about making the CI in a seperate
-// process, where direct method calls would be impossible.  Also, we have been
-// considering turning devices into plugin modules which are dynamically 
-// linked.  Any direct references to something like bx_floppy.s.media[2].heads
-// would have to be reworked before a plugin interface was possible as well.
-//
-// The siminterface is the glue between the CI and the simulator.  There is
-// just one global instance of the siminterface object, which can be referred
-// to by the global variable bx_simulator_interface_c *SIM; The base class
-// bx_simulator_interface_c, contains only virtual functions and it defines the
-// interface that the CI is allowed to use.  In siminterface.cc, a class
-// called bx_real_sim_c is defined with bx_simulator_interface_c as its parent
-// class.  Bx_real_sim_c implements each of the functions.  The separation into
-// parent class and child class leaves the possibility of making a different
-// child class that talks to the simulator in a different way (networking for
-// example).  If you were writing a user interface in a separate process, you
-// could define a subclass of bx_simulator_interface_c called
-// bx_siminterface_proxy_c which opens up a network port and turns all method
-// calls into network sends and receives.  Because the interface is defined
-// entirely by the base class, the code that calls the methods would not know
-// the difference.
-//
-// An important part of the siminterface implementation is the use of parameter
-// classes, or bx_param_*.  The parameter classes are described below, where
-// they are declared.  Search for "parameter classes" below for detals.
-//
-// Also this header file declares data structures for certain events that pass
-// between the siminterface and the CI.  Search for "event structures" below.
-
-
-
-//////////////////////////////////////////////////////
-// BX_UI_TEXT should be set to 1 when the text mode configuration interface
-// is compiled in.  This gives each type of parameter a text_print and text_ask
-// method (defined in gui/control.cc) so that you can call text_ask() on any
-// kind of parameter to ask the user to edit the value.
-//
-// I have been considering whether to use the same strategy for the
-// wxWindows interface, but I'm not sure if I like it.  One problem is
-// that in order to declare member functions that are useful for
-// wxWindows, the wxWindows header files would have to be included
-// before the param object definitions.  That means that all the
-// wxwindows headers would have be included when compiling every
-// single bochs file.  One of the things I like about the separation
-// between the simulator and CI is that the two parts can be
-// compiled without any knowledge of the other.  Bochs doesn't include
-// <wx.h>, and the wxwindows CI (wxmain.cc) doesn't need to include <bochs.h>.
-// Aside from making compiles faster, this enforces the use of the siminterface
-// so it keeps the interface clean (important when we may have multiple UI
-// implementations for example).  This argues for keeping UI-specific
-// structures out of the simulator interface.  It certainly works ok for the
-// text interface, but that's because FILE* is standard and portable.
-#define BX_UI_TEXT 1
-
-//////////////////////////////////////////////////////
-
-// list of possible types for bx_param_c and descendant objects
-typedef enum {
-  BXT_OBJECT = 201,
-  BXT_PARAM,
-  BXT_PARAM_NUM,
-  BXT_PARAM_BOOL,
-  BXT_PARAM_ENUM,
-  BXT_PARAM_STRING,
-  BXT_LIST
-} bx_objtype;
-
-// list if parameter id values.  The actual values are not important;
-// it's only important that they all be different from each other.
-typedef enum {
-  BXP_NULL = 301,
-  BXP_IPS,
-  BXP_REALTIME_PIT,
-  BXP_TEXT_SNAPSHOT_CHECK,
-  BXP_VGA_UPDATE_INTERVAL,
-  BXP_MOUSE_ENABLED,
-  BXP_MEM_SIZE,
-  BXP_ROM_PATH,
-  BXP_ROM_ADDRESS,
-  BXP_VGA_ROM_PATH,
-  BXP_OPTROM1_PATH,
-  BXP_OPTROM2_PATH,
-  BXP_OPTROM3_PATH,
-  BXP_OPTROM4_PATH,
-  BXP_OPTROM1_ADDRESS,
-  BXP_OPTROM2_ADDRESS,
-  BXP_OPTROM3_ADDRESS,
-  BXP_OPTROM4_ADDRESS,
-  BXP_KBD_SERIAL_DELAY,
-  BXP_KBD_PASTE_DELAY,
-  BXP_KBD_TYPE,
-  BXP_FLOPPY_CMD_DELAY,
-  BXP_FLOPPYA_DEVTYPE,
-  BXP_FLOPPYA_PATH,
-  BXP_FLOPPYA_TYPE,
-  BXP_FLOPPYA_STATUS,
-  BXP_FLOPPYA,
-  BXP_FLOPPYB_DEVTYPE,
-  BXP_FLOPPYB_PATH,
-  BXP_FLOPPYB_TYPE,
-  BXP_FLOPPYB_STATUS,
-  BXP_FLOPPYB,
-
-  BXP_ATA0_MENU,
-  BXP_ATA1_MENU,
-  BXP_ATA2_MENU,
-  BXP_ATA3_MENU,
-#define BXP_ATAx_MENU(i) (BXP_ATA0_MENU + (i))
-  BXP_ATA0,
-  BXP_ATA1,
-  BXP_ATA2,
-  BXP_ATA3,
-#define BXP_ATAx(i) (BXP_ATA0 + (i))
-  BXP_ATA0_PRESENT,
-  BXP_ATA1_PRESENT,
-  BXP_ATA2_PRESENT,
-  BXP_ATA3_PRESENT,
-#define BXP_ATAx_PRESENT(i) (BXP_ATA0_PRESENT + (i))
-  BXP_ATA0_IOADDR1,
-  BXP_ATA1_IOADDR1,
-  BXP_ATA2_IOADDR1,
-  BXP_ATA3_IOADDR1,
-#define BXP_ATAx_IOADDR1(i) (BXP_ATA0_IOADDR1 + (i))
-  BXP_ATA0_IOADDR2,
-  BXP_ATA1_IOADDR2,
-  BXP_ATA2_IOADDR2,
-  BXP_ATA3_IOADDR2,
-#define BXP_ATAx_IOADDR2(i) (BXP_ATA0_IOADDR2 + (i))
-  BXP_ATA0_IRQ,
-  BXP_ATA1_IRQ,
-  BXP_ATA2_IRQ,
-  BXP_ATA3_IRQ,
-#define BXP_ATAx_IRQ(i) (BXP_ATA0_IRQ + (i))
-
-  BXP_ATA0_MASTER,
-  BXP_ATA0_SLAVE,
-  BXP_ATA1_MASTER,
-  BXP_ATA1_SLAVE,
-  BXP_ATA2_MASTER,
-  BXP_ATA2_SLAVE,
-  BXP_ATA3_MASTER,
-  BXP_ATA3_SLAVE,
-#define BXP_ATAx_DEVICE(i, s) (BXP_ATA0_MASTER + (2*(i)) + (s))
-
-#define BXP_PARAMS_PER_ATA_DEVICE 12
-
-  BXP_ATA0_MASTER_PRESENT,
-  BXP_ATA0_SLAVE_PRESENT,
-  BXP_ATA1_MASTER_PRESENT,
-  BXP_ATA1_SLAVE_PRESENT,
-  BXP_ATA2_MASTER_PRESENT,
-  BXP_ATA2_SLAVE_PRESENT,
-  BXP_ATA3_MASTER_PRESENT,
-  BXP_ATA3_SLAVE_PRESENT,
-#define BXP_ATAx_DEVICE_PRESENT(i, s) (BXP_ATA0_MASTER_PRESENT + (2*(i)) + (s))
-
-  BXP_ATA0_MASTER_TYPE,
-  BXP_ATA0_SLAVE_TYPE,
-  BXP_ATA1_MASTER_TYPE,
-  BXP_ATA1_SLAVE_TYPE,
-  BXP_ATA2_MASTER_TYPE,
-  BXP_ATA2_SLAVE_TYPE,
-  BXP_ATA3_MASTER_TYPE,
-  BXP_ATA3_SLAVE_TYPE,
-#define BXP_ATAx_DEVICE_TYPE(i, s) (BXP_ATA0_MASTER_TYPE + (2*(i)) + (s))
-
-  BXP_ATA0_MASTER_MODE,
-  BXP_ATA0_SLAVE_MODE,
-  BXP_ATA1_MASTER_MODE,
-  BXP_ATA1_SLAVE_MODE,
-  BXP_ATA2_MASTER_MODE,
-  BXP_ATA2_SLAVE_MODE,
-  BXP_ATA3_MASTER_MODE,
-  BXP_ATA3_SLAVE_MODE,
-#define BXP_ATAx_DEVICE_MODE(i, s) (BXP_ATA0_MASTER_MODE + (2*(i)) + (s))
-
-  BXP_ATA0_MASTER_PATH,
-  BXP_ATA0_SLAVE_PATH,
-  BXP_ATA1_MASTER_PATH,
-  BXP_ATA1_SLAVE_PATH,
-  BXP_ATA2_MASTER_PATH,
-  BXP_ATA2_SLAVE_PATH,
-  BXP_ATA3_MASTER_PATH,
-  BXP_ATA3_SLAVE_PATH,
-#define BXP_ATAx_DEVICE_PATH(i, s) (BXP_ATA0_MASTER_PATH + (2*(i)) + (s))
-
-  BXP_ATA0_MASTER_CYLINDERS,
-  BXP_ATA0_SLAVE_CYLINDERS,
-  BXP_ATA1_MASTER_CYLINDERS,
-  BXP_ATA1_SLAVE_CYLINDERS,
-  BXP_ATA2_MASTER_CYLINDERS,
-  BXP_ATA2_SLAVE_CYLINDERS,
-  BXP_ATA3_MASTER_CYLINDERS,
-  BXP_ATA3_SLAVE_CYLINDERS,
-#define BXP_ATAx_DEVICE_CYLINDERS(i, s) (BXP_ATA0_MASTER_CYLINDERS + (2*(i)) + (s))
-
-  BXP_ATA0_MASTER_HEADS,
-  BXP_ATA0_SLAVE_HEADS,
-  BXP_ATA1_MASTER_HEADS,
-  BXP_ATA1_SLAVE_HEADS,
-  BXP_ATA2_MASTER_HEADS,
-  BXP_ATA2_SLAVE_HEADS,
-  BXP_ATA3_MASTER_HEADS,
-  BXP_ATA3_SLAVE_HEADS,
-#define BXP_ATAx_DEVICE_HEADS(i, s) (BXP_ATA0_MASTER_HEADS + (2*(i)) + (s))
-
-  BXP_ATA0_MASTER_SPT,
-  BXP_ATA0_SLAVE_SPT,
-  BXP_ATA1_MASTER_SPT,
-  BXP_ATA1_SLAVE_SPT,
-  BXP_ATA2_MASTER_SPT,
-  BXP_ATA2_SLAVE_SPT,
-  BXP_ATA3_MASTER_SPT,
-  BXP_ATA3_SLAVE_SPT,
-#define BXP_ATAx_DEVICE_SPT(i, s) (BXP_ATA0_MASTER_SPT + (2*(i)) + (s))
-
-  BXP_ATA0_MASTER_STATUS,
-  BXP_ATA0_SLAVE_STATUS,
-  BXP_ATA1_MASTER_STATUS,
-  BXP_ATA1_SLAVE_STATUS,
-  BXP_ATA2_MASTER_STATUS,
-  BXP_ATA2_SLAVE_STATUS,
-  BXP_ATA3_MASTER_STATUS,
-  BXP_ATA3_SLAVE_STATUS,
-#define BXP_ATAx_DEVICE_STATUS(i, s) (BXP_ATA0_MASTER_STATUS + (2*(i)) + (s))
-
-  BXP_ATA0_MASTER_MODEL,
-  BXP_ATA0_SLAVE_MODEL,
-  BXP_ATA1_MASTER_MODEL,
-  BXP_ATA1_SLAVE_MODEL,
-  BXP_ATA2_MASTER_MODEL,
-  BXP_ATA2_SLAVE_MODEL,
-  BXP_ATA3_MASTER_MODEL,
-  BXP_ATA3_SLAVE_MODEL,
-#define BXP_ATAx_DEVICE_MODEL(i, s) (BXP_ATA0_MASTER_MODEL + (2*(i)) + (s))
-
-  BXP_ATA0_MASTER_BIOSDETECT,
-  BXP_ATA0_SLAVE_BIOSDETECT,
-  BXP_ATA1_MASTER_BIOSDETECT,
-  BXP_ATA1_SLAVE_BIOSDETECT,
-  BXP_ATA2_MASTER_BIOSDETECT,
-  BXP_ATA2_SLAVE_BIOSDETECT,
-  BXP_ATA3_MASTER_BIOSDETECT,
-  BXP_ATA3_SLAVE_BIOSDETECT,
-#define BXP_ATAx_DEVICE_BIOSDETECT(i, s) (BXP_ATA0_MASTER_BIOSDETECT + (2*(i)) + (s))
-
-  BXP_ATA0_MASTER_TRANSLATION,
-  BXP_ATA0_SLAVE_TRANSLATION,
-  BXP_ATA1_MASTER_TRANSLATION,
-  BXP_ATA1_SLAVE_TRANSLATION,
-  BXP_ATA2_MASTER_TRANSLATION,
-  BXP_ATA2_SLAVE_TRANSLATION,
-  BXP_ATA3_MASTER_TRANSLATION,
-  BXP_ATA3_SLAVE_TRANSLATION,
-#define BXP_ATAx_DEVICE_TRANSLATION(i, s) (BXP_ATA0_MASTER_TRANSLATION + (2*(i)) + (s))
-
-  BXP_ATA0_MASTER_JOURNAL,
-  BXP_ATA0_SLAVE_JOURNAL,
-  BXP_ATA1_MASTER_JOURNAL,
-  BXP_ATA1_SLAVE_JOURNAL,
-  BXP_ATA2_MASTER_JOURNAL,
-  BXP_ATA2_SLAVE_JOURNAL,
-  BXP_ATA3_MASTER_JOURNAL,
-  BXP_ATA3_SLAVE_JOURNAL,
-#define BXP_ATAx_DEVICE_JOURNAL(i, s) (BXP_ATA0_MASTER_JOURNAL + (2*(i)) + (s))
-
-#define BXP_PARAMS_PER_SERIAL_PORT 2
-  BXP_COM1_ENABLED,
-  BXP_COM1_PATH,
-  BXP_COM2_ENABLED,
-  BXP_COM2_PATH,
-  BXP_COM3_ENABLED,
-  BXP_COM3_PATH,
-  BXP_COM4_ENABLED,
-  BXP_COM4_PATH,
-#define BXP_PARAMS_PER_USB_HUB 3
-  BXP_USB1_ENABLED,
-  BXP_USB1_IOADDR,
-  BXP_USB1_IRQ,
-  BXP_PRIVATE_COLORMAP,
-  BXP_FULLSCREEN,
-  BXP_SCREENMODE,
-  BXP_I440FX_SUPPORT,
-  BXP_NEWHARDDRIVESUPPORT,
-  BXP_LOG_FILENAME,
-  BXP_LOG_PREFIX,
-  BXP_DEBUGGER_LOG_FILENAME,
-  BXP_CMOS_PATH,
-  BXP_CMOS_IMAGE,
-  BXP_CLOCK,
-  BXP_CLOCK_TIME0,
-  BXP_CLOCK_SYNC,
-  BXP_LOAD32BITOS_WHICH,
-  BXP_LOAD32BITOS_PATH,
-  BXP_LOAD32BITOS_IOLOG,
-  BXP_LOAD32BITOS_INITRD,
-  BXP_LOAD32BITOS,
-  BXP_BOOTDRIVE,
-  BXP_FLOPPYSIGCHECK,
-  BXP_MENU_MAIN,
-  BXP_MENU_MEMORY,
-  BXP_MENU_INTERFACE,
-  BXP_MENU_DISK,
-  BXP_MENU_SERIAL_PARALLEL,
-  BXP_MENU_SOUND,
-  BXP_MENU_KEYBOARD,
-  BXP_MENU_MISC,
-  BXP_MENU_MISC_2,
-  BXP_MENU_RUNTIME,
-  BXP_MAX_IPS,
-  BXP_NE2K_PRESENT,
-  BXP_NE2K_IOADDR,
-  BXP_NE2K_IRQ,
-  BXP_NE2K_MACADDR,
-  BXP_NE2K_ETHMOD,
-  BXP_NE2K_ETHDEV,
-  BXP_NE2K_SCRIPT,
-  BXP_NE2K,
-  BXP_SB16_PRESENT,
-  BXP_SB16_MIDIFILE,
-  BXP_SB16_WAVEFILE,
-  BXP_SB16_LOGFILE,
-  BXP_SB16_MIDIMODE,
-  BXP_SB16_WAVEMODE,
-  BXP_SB16_LOGLEVEL,
-  BXP_SB16_DMATIMER,
-  BXP_SB16,
-#define BXP_PARAMS_PER_PARALLEL_PORT 2
-  BXP_PARPORT1_ENABLED,
-  BXP_PARPORT1_OUTFILE,
-  BXP_PARPORT2_ENABLED,
-  BXP_PARPORT2_OUTFILE,
-  BXP_KEYBOARD_USEMAPPING,
-  BXP_KEYBOARD_MAP,
-  BXP_KEYBOARD,
-  BXP_USER_SHORTCUT,
-  BXP_ASK_FOR_PATHNAME,   // for general file selection dialog
-  BXP_BOCHS_START,        // How Bochs starts
-  // experiment: add params for CPU registers
-  BXP_CPU_PARAMETERS,
-  BXP_CPU_EAX,
-  BXP_CPU_EBX,
-  BXP_CPU_ECX,
-  BXP_CPU_EDX,
-  BXP_CPU_EBP,
-  BXP_CPU_ESI,
-  BXP_CPU_EDI,
-  BXP_CPU_ESP,
-  BXP_CPU_EIP,
-  BXP_CPU_SEG_CS,
-  BXP_CPU_SEG_DS,
-  BXP_CPU_SEG_SS,
-  BXP_CPU_SEG_ES,
-  BXP_CPU_SEG_FS,
-  BXP_CPU_SEG_GS,
-  BXP_CPU_SEG_LDTR,
-  BXP_CPU_SEG_TR,
-  BXP_CPU_GDTR_BASE,
-  BXP_CPU_GDTR_LIMIT,
-  BXP_CPU_IDTR_BASE,
-  BXP_CPU_IDTR_LIMIT,
-  BXP_CPU_EFLAGS,
-  BXP_CPU_EFLAGS_ID,
-  BXP_CPU_EFLAGS_VIP,
-  BXP_CPU_EFLAGS_VIF,
-  BXP_CPU_EFLAGS_AC,
-  BXP_CPU_EFLAGS_VM,
-  BXP_CPU_EFLAGS_RF,
-  BXP_CPU_EFLAGS_NT,
-  BXP_CPU_EFLAGS_IOPL,
-  BXP_CPU_EFLAGS_OF,
-  BXP_CPU_EFLAGS_DF,
-  BXP_CPU_EFLAGS_IF,
-  BXP_CPU_EFLAGS_TF,
-  BXP_CPU_EFLAGS_SF,
-  BXP_CPU_EFLAGS_ZF,
-  BXP_CPU_EFLAGS_AF,
-  BXP_CPU_EFLAGS_PF,
-  BXP_CPU_EFLAGS_CF,
-  BXP_CPU_DR0,
-  BXP_CPU_DR1,
-  BXP_CPU_DR2,
-  BXP_CPU_DR3,
-  BXP_CPU_DR6,
-  BXP_CPU_DR7,
-  BXP_CPU_TR3,
-  BXP_CPU_TR4,
-  BXP_CPU_TR5,
-  BXP_CPU_TR6,
-  BXP_CPU_TR7,
-  BXP_CPU_CR0,
-  BXP_CPU_CR1,
-  BXP_CPU_CR2,
-  BXP_CPU_CR3,
-  BXP_CPU_CR4,
-  // a few parameters for the keyboard
-  BXP_KBD_PARAMETERS,
-  BXP_KBD_PARE,
-  BXP_KBD_TIM ,
-  BXP_KBD_AUXB,
-  BXP_KBD_KEYL,
-  BXP_KBD_C_D,
-  BXP_KBD_SYSF,
-  BXP_KBD_INPB,
-  BXP_KBD_OUTB,
-  BXP_KBD_TIMER_PENDING,
-  BXP_KBD_IRQ1_REQ,
-  BXP_KBD_IRQ12_REQ,
-#if BX_DEBUGGER
-  // in debugger, is the simulation running (continue command) or waiting.
-  // This is only modified by debugger code, not by the user.
-  BXP_DEBUG_RUNNING,
-#endif
-  BXP_SEL_CONFIG_INTERFACE,
-  BXP_SEL_DISPLAY_LIBRARY,
-  BXP_THIS_IS_THE_LAST    // used to determine length of list
-} bx_id;
-
-// use x=1,2,3,4
-#define BXP_COMx_ENABLED(x) \
-   (bx_id)(BXP_COM1_ENABLED + (((x)-1)*BXP_PARAMS_PER_SERIAL_PORT))
-#define BXP_COMx_PATH(x) \
-  (bx_id)(BXP_COM1_PATH + (((x)-1)*BXP_PARAMS_PER_SERIAL_PORT))
-
-// use x=1
-#define BXP_USBx_ENABLED(x) \
-   (bx_id)(BXP_USB1_ENABLED + (((x)-1)*BXP_PARAMS_PER_USB_HUB))
-#define BXP_USBx_IOADDR(x) \
-   (bx_id)(BXP_USB1_IOADDR + (((x)-1)*BXP_PARAMS_PER_USB_HUB))
-#define BXP_USBx_IRQ(x) \
-   (bx_id)(BXP_USB1_IRQ + (((x)-1)*BXP_PARAMS_PER_USB_HUB))
-
-// use x=1,2
-#define BXP_PARPORTx_ENABLED(x) \
-  (bx_id)(BXP_PARPORT1_ENABLED + (((x)-1)*BXP_PARAMS_PER_PARALLEL_PORT))
-#define BXP_PARPORTx_OUTFILE(x) \
-  (bx_id)(BXP_PARPORT1_OUTFILE + (((x)-1)*BXP_PARAMS_PER_PARALLEL_PORT))
-
-typedef enum {
-  BX_TOOLBAR_UNDEFINED,
-  BX_TOOLBAR_FLOPPYA,
-  BX_TOOLBAR_FLOPPYB,
-  BX_TOOLBAR_CDROMD,
-  BX_TOOLBAR_RESET,
-  BX_TOOLBAR_POWER,
-  BX_TOOLBAR_COPY,
-  BX_TOOLBAR_PASTE,
-  BX_TOOLBAR_SNAPSHOT,
-  BX_TOOLBAR_CONFIG,
-  BX_TOOLBAR_MOUSE_EN,
-  BX_TOOLBAR_USER
-} bx_toolbar_buttons;
-
-// Log level defines
-typedef enum {
-  LOGLEV_DEBUG = 0,
-  LOGLEV_INFO,
-  LOGLEV_ERROR,
-  LOGLEV_PANIC,
-  LOGLEV_PASS,
-  N_LOGLEV
-} bx_log_levels;
-
-// types of reset
-#define BX_RESET_SOFTWARE 10
-#define BX_RESET_HARDWARE 11
-
-//cdrom
-#define BX_EJECTED   10
-#define BX_INSERTED  11
-
-// boot devices
-#define BX_BOOT_FLOPPYA 0
-#define BX_BOOT_DISKC   1
-#define BX_BOOT_CDROM   2
-
-// loader hack
-#define Load32bitOSNone        0
-#define Load32bitOSLinux       1
-#define Load32bitOSNullKernel  2 // being developed for plex86
-#define Load32bitOSLast        2
-
-///////////////////////////////////////////////////////////////////
-// event structures for communication between simulator and CI
-///////////////////////////////////////////////////////////////////
-// Because the CI (configuration interface) might be in a different
-// thread or even a different process, we pass events encoded in data
-// structures to it instead of just calling functions.  Each type of
-// event is declared as a different structure, and then all those
-// structures are squished into a union in BxEvent.  (BTW, this is
-// almost exactly how X windows event structs work.)
-//
-// These are simple structs, unblemished by C++ methods and tricks.
-// No matter what event type it is, we allocate a BxEvent for each
-// one, as opposed to trying to save a few bytes on small events by
-// allocating only the bytes necessary for it.  This makes it easy and
-// fast to store events in a queue, like this
-//   BxEvent event_queue[MAX_EVENTS];
-//
-// Events come in two varieties: synchronous and asynchronous.  We
-// have to worry about sync and async events because the CI and the
-// simulation may be running in different threads.  An async event is
-// the simplest.  Whichever thread originates the event just builds
-// the data structure, sends it, and then continues with its business.
-// Async events can go in either direction.  Synchronous events
-// require the other thread to "respond" before the originating thread
-// can continue.  It's like a function with a return value; you can't
-// continue until you get the return value back.
-//
-// Examples:
-//
-// async event: In the wxWindows implementation, both the CI and the
-// VGAW operate in the wxWindows GUI thread.  When the user presses a
-// key, wxWindows sends a wxKeyEvent to the VGAW event handler code in
-// wx.cc.  The VGAW handler then builds a BxEvent with
-// type=BX_ASYNC_EVT_KEY, and fills in the bx_key and raw_scancode
-// fields.  The asynchronous event is placed on the event_queue for
-// the simulator, then the VGAW handler returns.  (With wxWindows and
-// many other graphical libaries, the event handler must return
-// quickly because the window will not be updated until it's done.)
-// Some time later, the simulator reaches the point where it checks
-// for new events from the user (actually controlled by
-// bx_keyb_c::periodic() in iodev/keyboard.cc) and calls
-// bx_gui.handle_events().  Then all the events in the queue are
-// processed by the simulator.  There is no "response" sent back to
-// the originating thread.
-//
-// sync event: Sometimes the simulator reaches a point where it needs
-// to ask the user how to proceed.  In this case, the simulator sends
-// a synchronous event because it requires a response before it can 
-// continue.  It builds an event structure, perhaps with type
-// BX_SYNC_EVT_ASK_PARAM, sends it to the user interface 
-// using the event handler function defined by set_notify_callback(),
-// and pauses the simulation.  The user interface asks the user the
-// question, and puts the answer into the BxEvent.retcode field.  The
-// event handler function returns the modified BxEvent with retcode
-// filled in, and the simulation continues.  The details of this
-// transaction can be complicated if the simulation and CI are not
-// in the same thread, but the behavior is as described.
-//
-
-///// types and definitions used in event structures
-
-#define BX_EVT_IS_ASYNC(type) ((type) > __ALL_EVENTS_BELOW_ARE_ASYNC__)
-
-typedef enum {
-  __ALL_EVENTS_BELOW_ARE_SYNCHRONOUS__ = 2000,
-  BX_SYNC_EVT_GET_PARAM,          // CI -> simulator -> CI
-  BX_SYNC_EVT_ASK_PARAM,          // simulator -> CI -> simulator
-  BX_SYNC_EVT_TICK,               // simulator -> CI, wait for response.
-  BX_SYNC_EVT_LOG_ASK,            // simulator -> CI, wait for response.
-  BX_SYNC_EVT_GET_DBG_COMMAND,    // simulator -> CI, wait for response.
-  __ALL_EVENTS_BELOW_ARE_ASYNC__,
-  BX_ASYNC_EVT_KEY,               // vga window -> simulator
-  BX_ASYNC_EVT_MOUSE,             // vga window -> simulator
-  BX_ASYNC_EVT_SET_PARAM,         // CI -> simulator
-  BX_ASYNC_EVT_LOG_MSG,           // simulator -> CI
-  BX_ASYNC_EVT_DBG_MSG,           // simulator -> CI
-  BX_ASYNC_EVT_VALUE_CHANGED,     // simulator -> CI
-  BX_ASYNC_EVT_TOOLBAR,           // CI -> simulator
-  BX_ASYNC_EVT_REFRESH            // simulator -> CI
-} BxEventType;
-
-typedef union {
-  Bit32s s32;
-  char *charptr;
-} AnyParamVal;
-
-// Define substructures which make up the interior of BxEvent.  The
-// substructures, such as BxKeyEvent or BxMouseEvent, should never be
-// allocated on their own.  They are only intended to be used within
-// the union in the BxEvent structure.
-
-// Event type: BX_SYNC_EVT_TICK
-//
-// A tick event is synchronous, sent from the simulator to the GUI.  The
-// event doesn't do anything visible.  Primarily it gives the GUI a chance
-// to tell the simulator to quit, if necessary.  There may be other uses
-// for the tick in the future, such as giving some kind of regular
-// status report or mentioning watched values that changed, but so far
-// it's just for that one thing.  There is no data associated with a
-// tick event.
-
-// Event type: BX_ASYNC_EVT_KEY
-//
-// A key event can be sent from the VGA window to the Bochs simulator.  
-// It is asynchronous.
-typedef struct {
-  // what was pressed?  This is a BX_KEY_* value.  For key releases,
-  // BX_KEY_RELEASED is ORed with the base BX_KEY_*.
-  Bit32u bx_key;
-  bx_bool raw_scancode;
-} BxKeyEvent;
-
-// Event type: BX_ASYNC_EVT_MOUSE
-//
-// A mouse event can be sent from the VGA window to the Bochs
-// simulator.  It is asynchronous.  Currently unused because mouse
-// events aren't implemented in our wxWindows code yet.
-typedef struct {
-  // type is BX_EVT_MOUSE
-  Bit16s dx, dy;           // mouse motion delta
-  Bit8u buttons;           // which buttons are pressed.
-                           // bit 0: 1=left button down, 0=up
-                           // bit 1: 1=right button down, 0=up
-} BxMouseEvent;
-
-// Event type: BX_SYNC_EVT_GET_PARAM, BX_ASYNC_EVT_SET_PARAM
-//
-// Parameter set/get events are initiated by the CI, since Bochs can
-// always access the parameters directly.  So far, I haven't used
-// these event types.  In the CI I just call
-// SIM->get_param(parameter_id) to get a pointer to the bx_param_c
-// object and then call the get/set methods.  This is okay for
-// configuration since bochs is not running.  However it could be
-// dangerous for the GUI thread to poke around in Bochs structures
-// while the thread is running.  For these cases, I may have to be
-// more careful and actually build get/set events and place them on
-// Bochs's event queue to be processed during SIM->periodic() or
-// something.
-typedef struct {
-  // type is BX_EVT_GET_PARAM, BX_EVT_SET_PARAM
-  class bx_param_c *param;         // pointer to param structure
-  AnyParamVal val;
-} BxParamEvent;
-
-// Event type: BX_SYNC_EVT_ASK_PARAM
-// Synchronous event sent from the simulator to the CI.  This tells the
-// CI to ask the user to choose the value of a parameter.  The CI may 
-// need to discover the type of parameter so that it can use the right
-// kind of graphical display.  The BxParamEvent is used for these events
-// too.
-// FIXME: at the moment the GUI implements the ASK_PARAM event for just
-// a few parameter types.  I need to implement the event for all parameter
-// types.
-
-// Event type: BX_ASYNC_EVT_VALUE_CHANGED
-// 
-// Asynchronous event sent from the simulator to the CI, telling it that
-// some value that it (hopefully) cares about has changed.  This isn't
-// being used yet, but a good example is in a debugger interface, you might
-// want to maintain a reasonably current display of the PC or some other
-// simulation state.  The CI would set some kind of event mask (which
-// doesn't exist now of course) and then when certain values change, the
-// simulator would send this event so that the CI can update.  We may need
-// some kind of "flow control" since the simulator will be able to produce
-// new events much faster than the gui can accept them.
-
-// Event type: BX_ASYNC_EVT_LOG_MSG   (unused)
-//
-// Asynchronous event from the simulator to the CI.  When a BX_PANIC,
-// BX_ERROR, BX_INFO, or BX_DEBUG is found in the simulator code, this 
-// event type can be used to inform the CI of the condition.  There is
-// no point in sending messages to the CI that will not be displayed; these
-// would only slow the simulation.  So we will need some mechanism for 
-// choosing what kinds of events will be delivered to the CI.  Normally,
-// you wouldn't want to look at the log unless something is going wrong.
-// At that point, you might want to open up a window to watch the debug
-// messages from one or two devices only.
-//
-// Idea: Except for panics that require user attention to continue, it
-// might be most efficient to just append log messages to a file.
-// When the user wants to look at the log messages, the gui can reopen
-// the file (read only), skip to the end, and look backward for a
-// reasonable number of lines to display (200?).  This allows it to
-// skip over huge bursts of log entries without allocating memory,
-// synchronizing threads, etc. for each.
-typedef struct {
-  Bit8u level;
-  const char *prefix;
-  const char *msg;
-} BxLogMsgEvent;
-
-// Event type: BX_ASYNC_EVT_DBG_MSG   (unused)
-//
-// Also uses BxLogMsgEvent, but this is a message to be displayed in
-// the debugger history window.
-
-// Event type: BX_SYNC_EVT_LOG_ASK
-//
-// This is a synchronous version of BX_ASYNC_EVT_LOG_MSG, which is used
-// when the "action=ask" setting is used.  If the simulator runs into a
-// panic, it sends a synchronous BX_SYNC_EVT_LOG_ASK to the CI to be
-// displayed.  The CI shows a dialog that asks if the user wants to 
-// continue, quit, etc. and sends the answer back to the simulator.
-// This event also uses BxLogMsgEvent.
-enum {
-  BX_LOG_ASK_CHOICE_CONTINUE,
-  BX_LOG_ASK_CHOICE_CONTINUE_ALWAYS,
-  BX_LOG_ASK_CHOICE_DIE,
-  BX_LOG_ASK_CHOICE_DUMP_CORE,
-  BX_LOG_ASK_CHOICE_ENTER_DEBUG,
-  BX_LOG_ASK_N_CHOICES
-};
-
-// Event type: BX_SYNC_EVT_GET_DBG_COMMAND
-//
-// This is a synchronous event sent from the simulator to the debugger
-// requesting the next action.  In a text mode debugger, this would prompt
-// the user for the next command.  When a new command is ready, the
-// synchronous event is sent back with its fields filled in.
-typedef struct {
-  char *command;   // null terminated string. allocated by debugger interface
-                   // with new operator, freed by simulator with delete.
-} BxDebugCommand;
-
-
-
-// Event type: BX_EVT_TOOLBAR
-// Asynchronous event from the VGAW to the simulator, sent when the user
-// clicks on a toolbar button.  This may one day become something more 
-// general, like a command event, but at the moment it's only needed for
-// the toolbar events.
-typedef struct {
-  bx_toolbar_buttons button;
-  bool on;   // for toggling buttons, on=true means the toolbar button is
-             // pressed. on=false means it is not pressed.
-} BxToolbarEvent;
-
-// The BxEvent structure should be used for all events.  Every event has
-// a type and a spot for a return code (only used for synchronous events).
-typedef struct {
-  BxEventType type; // what kind is this?
-  Bit32s retcode;   // sucess or failure. only used for synchronous events.
-  union {
-    BxKeyEvent key;
-    BxMouseEvent mouse;
-    BxParamEvent param;
-    BxLogMsgEvent logmsg;
-    BxToolbarEvent toolbar;
-    BxDebugCommand debugcmd;
-  } u;
-} BxEvent;
-
-
-////////////////////////////////////////////////////////////////////
-// parameter classes: bx_param_c and family
-////////////////////////////////////////////////////////////////////
-//
-// All variables that can be configured through the CI are declared as
-// "parameters" or objects of type bx_param_*.  There is a bx_param_*
-// class for each type of data that the user would need to see and
-// edit, e.g. integer, boolean, enum, string, filename, or list of
-// other parameters.  The purpose of the bx_param_* class, in addition
-// to storing the parameter's value, is to hold the name, description,
-// and constraints on the value.  The bx_param_* class should hold
-// everything that the CI would need to display the value and allow
-// the user to modify it.  For integer parameters, the minimum and
-// maximum allowed value can be defined, and the base in which it
-// should be displayed and interpreted.  For enums, the
-// bx_param_enum_c structure includes the list of values which the
-// parameter can have.
-//
-// Also, some parameter classes support get/set callback functions to
-// allow arbitrary code to be executed when the parameter is get/set. 
-// An example of where this is useful: if you disable the NE2K card,
-// the set() handler for that parameter can tell the user interface
-// that the NE2K's irq, I/O address, and mac address should be
-// disabled (greyed out, hidden, or made inaccessible).  The get/set
-// methods can also check if the set() value is acceptable using
-// whatever means and override it.
-//
-// The parameter concept is similar to the use of parameters in JavaBeans.
-
-class bx_object_c;
-class bx_param_c;
-class bx_param_num_c;
-class bx_param_enum_c;
-class bx_param_bool_c;
-class bx_param_string_c;
-class bx_param_filename_c;
-class bx_list_c;
-
-class BOCHSAPI bx_object_c {
-private:
-  bx_id id;
-  bx_objtype type;
-protected:
-  void set_type (bx_objtype type);
-public:
-  bx_object_c (bx_id id);
-  bx_id get_id () { return id; }
-  Bit8u get_type () { return type; }
-};
-
-class BOCHSAPI bx_param_c : public bx_object_c {
-  BOCHSAPI_CYGONLY static const char *default_text_format;
-protected:
-  char *name;
-  char *description;
-  char *label; // label string for text menus and gui dialogs
-  const char *text_format;  // printf format string. %d for ints, %s for strings, etc.
-  char *ask_format;  // format string for asking for a new value
-  int runtime_param;
-  int enabled;
-public:
-  bx_param_c (bx_id id, char *name, char *description);
-  void set_format (const char *format) {text_format = format;}
-  const char *get_format () {return text_format;}
-  void set_ask_format (char *format) {ask_format = format; }
-  char *get_ask_format () {return ask_format;}
-  void set_label (char *text) {label = text;}
-  char *get_label () {return label;}
-  void set_runtime_param (int val) { runtime_param = val; }
-  int get_runtime_param () { return runtime_param; }
-  char *get_name () { return name; }
-  char *get_description () { return description; }
-  int get_enabled () { return enabled; }
-  virtual void set_enabled (int enabled) { this->enabled = enabled; }
-  void reset () {}
-  int getint () {return -1;}
-  static const char* set_default_format (const char *f);
-  static const char *get_default_format () { return default_text_format; }
-  virtual bx_list_c *get_dependent_list () { return NULL; }
-#if BX_UI_TEXT
-  virtual void text_print (FILE *fp) {}
-  virtual int text_ask (FILE *fpin, FILE *fpout) {return -1;}
-#endif
-};
-
-typedef Bit64s (*param_event_handler)(class bx_param_c *, int set, Bit64s val);
-typedef int (*param_enable_handler)(class bx_param_c *, int en);
-
-class BOCHSAPI bx_param_num_c : public bx_param_c {
-  BOCHSAPI_CYGONLY static Bit32u default_base;
-  // The dependent_list is initialized to NULL.  If dependent_list is modified
-  // to point to a bx_list_c of other parameters, the set() method of
-  // bx_param_bool_c will enable those parameters when this bool is true, and
-  // disable them when this bool is false.
-  bx_list_c *dependent_list;
-  void update_dependents ();
-protected:
-  Bit64s min, max, initial_val;
-  union _uval_ {
-    Bit64s number;   // used by bx_param_num_c
-    Bit64s *p64bit;  // used by bx_shadow_num_c
-    Bit32s *p32bit;  // used by bx_shadow_num_c
-    Bit16s *p16bit;  // used by bx_shadow_num_c
-    Bit8s  *p8bit;    // used by bx_shadow_num_c
-    bx_bool *pbool;  // used by bx_shadow_bool_c
-  } val;
-  param_event_handler handler;
-  param_enable_handler enable_handler;
-  int base;
-  Bit32u options;
-public:
-  enum {
-    // When a bx_param_num_c is displayed in dialog, USE_SPIN_CONTROL controls
-    // whether a spin control should be used instead of a simple text control.
-    USE_SPIN_CONTROL = (1<<0)
-  } bx_numopt_bits;
-  bx_param_num_c (bx_id id,
-      char *name,
-      char *description,
-      Bit64s min, Bit64s max, Bit64s initial_val);
-  void reset ();
-  void set_handler (param_event_handler handler);
-  void set_enable_handler (param_enable_handler handler);
-  virtual bx_list_c *get_dependent_list () { return dependent_list; }
-  void set_dependent_list (bx_list_c *l);
-  virtual void set_enabled (int enabled);
-  virtual Bit32s get () { return (Bit32s) get64(); }
-  virtual Bit64s get64 ();
-  virtual void set (Bit64s val);
-  void set_base (int base) { this->base = base; }
-  void set_initial_val (Bit64s initial_val);
-  int get_base () { return base; }
-  void set_range (Bit64u min, Bit64u max);
-  Bit64s get_min () { return min; }
-  Bit64s get_max () { return max; }
-  static Bit32u set_default_base (Bit32u val);
-  static Bit32u get_default_base () { return default_base; }
-  void set_options (Bit32u options) { this->options = options; }
-  Bit32u get_options () { return options; }
-#if BX_UI_TEXT
-  virtual void text_print (FILE *fp);
-  virtual int text_ask (FILE *fpin, FILE *fpout);
-#endif
-};
-
-// a bx_shadow_num_c is like a bx_param_num_c except that it doesn't
-// store the actual value with its data. Instead, it uses val.p32bit
-// to keep a pointer to the actual data.  This is used to register
-// existing variables as parameters, without have to access it via
-// set/get methods.
-class BOCHSAPI bx_shadow_num_c : public bx_param_num_c {
-  Bit8u varsize;   // must be 64, 32, 16, or 8
-  Bit8u lowbit;   // range of bits associated with this param
-  Bit64u mask;     // mask is ANDed with value before it is returned from get
-public:
-  bx_shadow_num_c (bx_id id,
-      char *name,
-      char *description,
-      Bit64s *ptr_to_real_val,
-      Bit8u highbit = 63,
-      Bit8u lowbit = 0);
-  bx_shadow_num_c (bx_id id,
-      char *name,
-      char *description,
-      Bit64u *ptr_to_real_val,
-      Bit8u highbit = 63,
-      Bit8u lowbit = 0);
-  bx_shadow_num_c (bx_id id,
-      char *name,
-      char *description,
-      Bit32s *ptr_to_real_val,
-      Bit8u highbit = 31,
-      Bit8u lowbit = 0);
-  bx_shadow_num_c (bx_id id,
-      char *name,
-      char *description,
-      Bit32u *ptr_to_real_val,
-      Bit8u highbit = 31,
-      Bit8u lowbit = 0);
-  bx_shadow_num_c (bx_id id,
-      char *name,
-      char *description,
-      Bit16s *ptr_to_real_val,
-      Bit8u highbit = 15,
-      Bit8u lowbit = 0);
-  bx_shadow_num_c (bx_id id,
-      char *name,
-      char *description,
-      Bit16u *ptr_to_real_val,
-      Bit8u highbit = 15,
-      Bit8u lowbit = 0);
-  bx_shadow_num_c (bx_id id,
-      char *name,
-      char *description,
-      Bit8s *ptr_to_real_val,
-      Bit8u highbit = 7,
-      Bit8u lowbit = 0);
-  bx_shadow_num_c (bx_id id,
-      char *name,
-      char *description,
-      Bit8u *ptr_to_real_val,
-      Bit8u highbit = 7,
-      Bit8u lowbit = 0);
-  virtual Bit64s get64 ();
-  virtual void set (Bit64s val);
-};
-
-class BOCHSAPI bx_param_bool_c : public bx_param_num_c {
-  // many boolean variables are used to enable/disable modules.  In the
-  // user interface, the enable variable should enable/disable all the
-  // other parameters associated with that module.
-public:
-  bx_param_bool_c (bx_id id, 
-      char *name,
-      char *description,
-      Bit64s initial_val);
-#if BX_UI_TEXT
-  virtual void text_print (FILE *fp);
-  virtual int text_ask (FILE *fpin, FILE *fpout);
-#endif
-};
-
-// a bx_shadow_bool_c is a shadow param based on bx_param_bool_c.
-class BOCHSAPI bx_shadow_bool_c : public bx_param_bool_c {
-  // each bit of a bitfield can be a separate value.  bitnum tells which
-  // bit is used.  get/set will only modify that bit.
-  Bit8u bitnum;
-public:
-  bx_shadow_bool_c (bx_id id,
-      char *name,
-      char *description,
-      bx_bool *ptr_to_real_val,
-      Bit8u bitnum = 0);
-  virtual Bit64s get64 ();
-  virtual void set (Bit64s val);
-};
-
-
-class BOCHSAPI bx_param_enum_c : public bx_param_num_c {
-  char **choices;
-public:
-  bx_param_enum_c (bx_id id, 
-      char *name,
-      char *description,
-      char **choices,
-      Bit64s initial_val,
-      Bit64s value_base = 0);
-  char *get_choice (int n) { return choices[n]; }
-  int find_by_name (const char *string);
-  bool set_by_name (const char *string);
-#if BX_UI_TEXT
-  virtual void text_print (FILE *fp);
-  virtual int text_ask (FILE *fpin, FILE *fpout);
-#endif
-};
-
-typedef char* (*param_string_event_handler)(class bx_param_string_c *, int set, char *val, int maxlen);
-
-class BOCHSAPI bx_param_string_c : public bx_param_c {
-  int maxsize;
-  char *val, *initial_val;
-  param_string_event_handler handler;
-  param_enable_handler enable_handler;
-  bx_param_num_c *options;
-  char separator;
-public:
-  enum {
-    RAW_BYTES = 1,         // use binary text editor, like MAC addr
-    IS_FILENAME = 2,       // 1=yes it's a filename, 0=not a filename.
-                           // Some guis have a file browser. This
-                           // bit suggests that they use it.
-    SAVE_FILE_DIALOG = 4   // Use save dialog opposed to open file dialog
-  } bx_string_opt_bits;
-  bx_param_string_c (bx_id id,
-      char *name,
-      char *description,
-      char *initial_val,
-      int maxsize=-1);
-  virtual ~bx_param_string_c ();
-  void reset ();
-  void set_handler (param_string_event_handler handler);
-  void set_enable_handler (param_enable_handler handler);
-  virtual void set_enabled (int enabled);
-  Bit32s get (char *buf, int len);
-  char *getptr () {return val; }
-  void set (char *buf);
-  bx_bool equals (const char *buf);
-  bx_param_num_c *get_options () { return options; }
-  void set_separator (char sep) {separator = sep; }
-  char get_separator () {return separator; }
-  int get_maxsize () {return maxsize; }
-#if BX_UI_TEXT
-  virtual void text_print (FILE *fp);
-  virtual int text_ask (FILE *fpin, FILE *fpout);
-#endif
-};
-
-// Declare a filename class.  It is identical to a string, except that
-// it initializes the options differently.  This is just a shortcut
-// for declaring a string param and setting the options with IS_FILENAME.
-class BOCHSAPI bx_param_filename_c : public bx_param_string_c {
-public:
-  bx_param_filename_c (bx_id id,
-      char *name,
-      char *description,
-      char *initial_val,
-      int maxsize=-1);
-};
-
-class BOCHSAPI bx_list_c : public bx_param_c {
-private:
-  // just a list of bx_param_c objects.  size tells current number of
-  // objects in the list, and maxsize tells how many list items are
-  // allocated in the constructor.
-  bx_param_c **list;
-  int size, maxsize;
-  // options is a bit field whose bits are defined by bx_listopt_bits ORed
-  // together.  Options is a bx_param so that if necessary the bx_list could
-  // install a handler to cause get/set of options to have side effects.
-  bx_param_num_c *options;
-  // for a menu, the value of choice before the call to "ask" is default.
-  // After ask, choice holds the value that the user chose.  Choice defaults
-  // to 1 in the constructor.
-  bx_param_num_c *choice;
-  // title of the menu or series
-  bx_param_string_c *title;
-  // if the menu shows a "return to previous menu" type of choice,
-  // this controls where that choice will go.
-  bx_param_c *parent;
-  void init ();
-public:
-  enum {
-    // When a bx_list_c is displayed as a menu, SHOW_PARENT controls whether or
-    // not the menu shows a "Return to parent menu" choice or not.
-    SHOW_PARENT = (1<<0),
-    // Some lists are best displayed shown as menus, others as a series of
-    // related questions.  This bit suggests to the CI that the series of
-    // questions format is preferred.
-    SERIES_ASK = (1<<1),
-    // When a bx_list_c is displayed in a dialog, USE_TAB_WINDOW suggests
-    // to the CI that each item in the list should be shown as a separate
-    // tab.  This would be most appropriate when each item is another list
-    // of parameters.
-    USE_TAB_WINDOW = (1<<2),
-    // When a bx_list_c is displayed in a dialog, the list name is used as the
-    // label of the group box if USE_BOX_TITLE is set. This is only necessary if
-    // more than one list appears in a dialog box.
-    USE_BOX_TITLE = (1<<3)
-  } bx_listopt_bits;
-  bx_list_c (bx_id id, int maxsize);
-  bx_list_c (bx_id id, char *name, char *description, bx_param_c **init_list);
-  bx_list_c (bx_id id, char *name, char *description, int maxsize);
-  virtual ~bx_list_c();
-  bx_list_c *clone ();
-  void add (bx_param_c *param);
-  bx_param_c *get (int index);
-  int get_size () { return size; }
-  bx_param_num_c *get_options () { return options; }
-  void set_options (bx_param_num_c *newopt) { options = newopt; }
-  bx_param_num_c *get_choice () { return choice; }
-  bx_param_string_c *get_title () { return title; }
-  void set_parent (bx_param_c *newparent) { parent = newparent; }
-  bx_param_c *get_parent () { return parent; }
-#if BX_UI_TEXT
-  virtual void text_print (FILE *);
-  virtual int text_ask (FILE *fpin, FILE *fpout);
-#endif
-};
-
-////////////////////////////////////////////////////////////////
-
-
-// These are the different start modes.
-enum {
-  // Just start the simulation without running the configuration interface
-  // at all, unless something goes wrong.
-  BX_QUICK_START = 200,
-  // Run the configuration interface.  The default action will be to load a
-  // configuration file.  This makes sense if a config file could not be
-  // loaded, either because it wasn't found or because it had errors.
-  BX_LOAD_START,
-  // Run the configuration interface.  The default action will be to
-  // edit the configuration.
-  BX_EDIT_START,
-  // Run the configuration interface, but make the default action be to
-  // start the simulation.
-  BX_RUN_START
-};
-
-#define BX_FLOPPY_NONE   10 // floppy not present
-#define BX_FLOPPY_1_2    11 // 1.2M  5.25"
-#define BX_FLOPPY_1_44   12 // 1.44M 3.5"
-#define BX_FLOPPY_2_88   13 // 2.88M 3.5"
-#define BX_FLOPPY_720K   14 // 720K  3.5"
-#define BX_FLOPPY_360K   15 // 360K  5.25"
-#define BX_FLOPPY_160K   16 // 160K  5.25"
-#define BX_FLOPPY_180K   17 // 180K  5.25"
-#define BX_FLOPPY_320K   18 // 320K  5.25"
-#define BX_FLOPPY_LAST   18 // last legal value of floppy type
-
-#define BX_FLOPPY_GUESS  20 // decide based on image size
-
-#define BX_ATA_DEVICE_DISK      0
-#define BX_ATA_DEVICE_CDROM     1
-#define BX_ATA_DEVICE_LAST      1
-
-#define BX_ATA_BIOSDETECT_NONE      0
-#define BX_ATA_BIOSDETECT_AUTO      1
-#define BX_ATA_BIOSDETECT_CMOS      2
-
-#define BX_ATA_TRANSLATION_NONE      0
-#define BX_ATA_TRANSLATION_LBA       1
-#define BX_ATA_TRANSLATION_LARGE     2
-#define BX_ATA_TRANSLATION_RECHS     3
-#define BX_ATA_TRANSLATION_AUTO      4
-#define BX_ATA_TRANSLATION_LAST      4
-
-#define BX_ATA_MODE_FLAT        0
-#define BX_ATA_MODE_CONCAT      1
-#define BX_ATA_MODE_EXTDISKSIM  2
-#define BX_ATA_MODE_DLL_HD      3
-#define BX_ATA_MODE_SPARSE      4
-#define BX_ATA_MODE_VMWARE3     5
-#define BX_ATA_MODE_UNDOABLE    6
-#define BX_ATA_MODE_GROWING     7
-#define BX_ATA_MODE_VOLATILE    8
-#define BX_ATA_MODE_LAST        8
-//#define BX_ATA_MODE_Z_UNDOABLE  9
-//#define BX_ATA_MODE_Z_VOLATILE  10
-//#define BX_ATA_MODE_SPLIT       6
-
-#define BX_CLOCK_SYNC_NONE     0
-#define BX_CLOCK_SYNC_REALTIME 1
-#define BX_CLOCK_SYNC_SLOWDOWN 2
-#define BX_CLOCK_SYNC_BOTH     3
-#define BX_CLOCK_SYNC_LAST     3
-
-#define BX_CLOCK_TIME0_LOCAL     1
-#define BX_CLOCK_TIME0_UTC       2
-
-BOCHSAPI extern char *bochs_start_names[];
-BOCHSAPI extern int n_bochs_start_names;
-BOCHSAPI extern char *floppy_type_names[];
-BOCHSAPI extern int floppy_type_n_sectors[];
-BOCHSAPI extern int n_floppy_type_names;
-BOCHSAPI extern char *floppy_status_names[];
-BOCHSAPI extern int n_floppy_status_names;
-BOCHSAPI extern char *floppy_bootdisk_names[];
-BOCHSAPI extern int n_floppy_bootdisk_names;
-BOCHSAPI extern char *loader_os_names[];
-BOCHSAPI extern int n_loader_os_names;
-BOCHSAPI extern char *keyboard_type_names[];
-BOCHSAPI extern int n_keyboard_type_names;
-BOCHSAPI extern char *atadevice_type_names[];
-BOCHSAPI extern int n_atadevice_type_names;
-BOCHSAPI extern char *atadevice_mode_names[];
-BOCHSAPI extern int n_atadevice_mode_names;
-BOCHSAPI extern char *atadevice_status_names[];
-BOCHSAPI extern int n_atadevice_status_names;
-BOCHSAPI extern char *atadevice_biosdetect_names[];
-BOCHSAPI extern int n_atadevice_biosdetect_names;
-BOCHSAPI extern char *atadevice_translation_names[];
-BOCHSAPI extern int n_atadevice_translation_names;
-BOCHSAPI extern char *clock_sync_names[];
-BOCHSAPI extern int clock_sync_n_names;
-
-typedef struct {
-  bx_param_enum_c *Odevtype;
-  bx_param_string_c *Opath;
-  bx_param_enum_c *Otype;
-  bx_param_enum_c *Ostatus;
-  } bx_floppy_options;
-
-typedef struct {
-  bx_list_c *Omenu;
-  bx_param_bool_c *Opresent;
-  bx_param_enum_c *Otype;
-  bx_param_enum_c *Omode;
-  bx_param_string_c *Opath;
-  bx_param_string_c *Ojournal;
-  bx_param_num_c *Ocylinders;
-  bx_param_num_c *Oheads;
-  bx_param_num_c *Ospt;
-  bx_param_enum_c *Ostatus;
-  bx_param_string_c *Omodel;
-  bx_param_enum_c *Obiosdetect;
-  bx_param_enum_c *Otranslation;
-  } bx_atadevice_options;
-
-typedef struct {
-  bx_param_bool_c *Oenabled;
-  bx_param_string_c *Odev;
-  } bx_serial_options;
-
-typedef struct {
-  bx_param_bool_c *Oenabled;
-  bx_param_num_c *Oioaddr;
-  bx_param_num_c *Oirq;
-  } bx_usb_options;
-
-
-////////////////////////////////////////////////////////////////////
-// base class simulator interface, contains just virtual functions.
-// I'm not longer sure that having a base class is going to be of any
-// use... -Bryce
-
-#include <setjmp.h>
-
-enum ci_command_t { CI_START, CI_RUNTIME_CONFIG, CI_SHUTDOWN };
-enum ci_return_t { 
-  CI_OK,                  // normal return value 
-  CI_ERR_NO_TEXT_CONSOLE  // err: can't work because there's no text console
-  };
-typedef int (*config_interface_callback_t)(void *userdata, ci_command_t command);
-
-// bx_gui->set_display_mode() changes the mode between the configuration
-// interface and the simulation.  This is primarily intended for display
-// libraries which have a full-screen mode such as SDL, term, and svgalib.  The
-// display mode is set to DISP_MODE_CONFIG before displaying any configuration
-// menus, for panics that requires user input, when entering the debugger, etc.
-// It is set to DISP_MODE_SIM when the Bochs simulation resumes.  The constants
-// are defined here so that configuration interfaces can use them with the
-// bx_simulator_interface_c::set_display_mode() method.
-enum disp_mode_t { DISP_MODE_CONFIG=100, DISP_MODE_SIM };
-
-class BOCHSAPI bx_simulator_interface_c {
-public:
-  bx_simulator_interface_c ();
-  virtual void set_quit_context (jmp_buf *context) {}
-  virtual int get_init_done () { return -1; }
-  virtual int set_init_done (int n) {return -1;}
-  virtual void get_param_id_range (int *min, int *max) {}
-  virtual int register_param (bx_id id, bx_param_c *it) {return -1;}
-  virtual void reset_all_param () {}
-  virtual bx_param_c *get_param (bx_id id) {return NULL;}
-  virtual bx_param_num_c *get_param_num (bx_id id) {return NULL;}
-  virtual bx_param_string_c *get_param_string (bx_id id) {return NULL;}
-  virtual bx_param_bool_c *get_param_bool (bx_id id) {return NULL;}
-  virtual bx_param_enum_c *get_param_enum (bx_id id) {return NULL;}
-  virtual int get_n_log_modules () {return -1;}
-  virtual char *get_prefix (int mod) {return 0;}
-  virtual int get_log_action (int mod, int level) {return -1;}
-  virtual void set_log_action (int mod, int level, int action) {}
-  virtual int get_default_log_action (int level) {return -1;}
-  virtual void set_default_log_action (int level, int action) {}
-  virtual char *get_action_name (int action) {return 0;}
-  virtual const char *get_log_level_name (int level) {return 0;}
-  virtual int get_max_log_level () {return -1;}
-
-  // exiting is somewhat complicated!  The preferred way to exit bochs is
-  // to call BX_EXIT(exitcode).  That is defined to call 
-  // SIM->quit_sim(exitcode).  The quit_sim function first calls
-  // the cleanup functions in bochs so that it can destroy windows
-  // and free up memory, then sends a notify message to the CI 
-  // telling it that bochs has stopped.
-  virtual void quit_sim (int code) {}
-
-  virtual int get_exit_code () { return 0; }
-
-  virtual int get_default_rc (char *path, int len) {return -1;}
-  virtual int read_rc (char *path) {return -1;}
-  virtual int write_rc (char *rc, int overwrite) {return -1;}
-  virtual int get_log_file (char *path, int len) {return -1;}
-  virtual int set_log_file (char *path) {return -1;}
-  virtual int get_log_prefix (char *prefix, int len) {return -1;}
-  virtual int set_log_prefix (char *prefix) {return -1;}
-  virtual int get_debugger_log_file (char *path, int len) {return -1;}
-  virtual int set_debugger_log_file (char *path) {return -1;}
-  virtual int get_floppy_options (int drive, bx_floppy_options *out) {return -1;}
-  virtual int get_cdrom_options (int drive, bx_atadevice_options *out, int *where = NULL) {return -1;}
-  virtual char *get_floppy_type_name (int type) {return NULL;}
-
-  // The CI calls set_notify_callback to register its event handler function.
-  // This event handler function is called whenever the simulator needs to
-  // send an event to the CI.  For example, if the simulator hits a panic and
-  // wants to ask the user how to proceed, it would call the CI event handler
-  // to ask the CI to display a dialog.
-  //
-  // NOTE: At present, the standard VGAW buttons (floppy, snapshot, power,
-  // etc.) are displayed and handled by gui.cc, not by the CI or siminterface.
-  // gui.cc uses its own callback functions to implement the behavior of
-  // the buttons.  Some of these implementations call the siminterface.
-  typedef BxEvent* (*bxevent_handler)(void *theclass, BxEvent *event);
-  virtual void set_notify_callback (bxevent_handler func, void *arg) {}
-  virtual void get_notify_callback (bxevent_handler *func, void **arg) {}
-
-  // send an event from the simulator to the CI.
-  virtual BxEvent* sim_to_ci_event (BxEvent *event) {return NULL;}
-
-  // called from simulator when it hits serious errors, to ask if the user
-  // wants to continue or not
-  virtual int log_msg (const char *prefix, int level, const char *msg) {return -1;}
-
-  // tell the CI to ask the user for the value of a parameter.
-  virtual int ask_param (bx_id param) {return -1;}
-
-  // ask the user for a pathname
-  virtual int ask_filename (char *filename, int maxlen, char *prompt, char *the_default, int flags) {return -1;}
-  // called at a regular interval, currently by the keyboard handler.
-  virtual void periodic () {}
-  virtual int create_disk_image (const char *filename, int sectors, bx_bool overwrite) {return -3;}
-  // Tell the configuration interface (CI) that some parameter values have
-  // changed.  The CI will reread the parameters and change its display if it's
-  // appropriate.  Maybe later: mention which params have changed to save time.
-  virtual void refresh_ci () {}
-  // forces a vga update.  This was added so that a debugger can force
-  // a vga update when single stepping, without having to wait thousands
-  // of cycles for the normal vga refresh triggered by iodev/keyboard.cc.
-  virtual void refresh_vga () {}
-  // forces a call to bx_gui.handle_events.  This was added so that a debugger
-  // can force the gui events to be handled, so that interactive things such
-  // as a toolbar click will be processed.
-  virtual void handle_events () {}
-  // return first hard disk in ATA interface
-  virtual bx_param_c *get_first_cdrom () {return NULL;}
-  // return first cdrom in ATA interface
-  virtual bx_param_c *get_first_hd () {return NULL;}
-#if BX_DEBUGGER
-  // for debugger: same behavior as pressing control-C
-  virtual void debug_break () {}
-  virtual void debug_interpret_cmd (char *cmd) {}
-  virtual char *debug_get_next_command () {return NULL;}
-  virtual void debug_puts (const char *text) {}
-#endif
-  virtual void register_configuration_interface (
-    const char* name, 
-    config_interface_callback_t callback,
-    void *userdata) {}
-  virtual int configuration_interface(const char* name, ci_command_t command) {return -1; }
-  virtual int begin_simulation (int argc, char *argv[]) {return -1;}
-  typedef bool (*is_sim_thread_func_t)();
-  is_sim_thread_func_t is_sim_thread_func;
-  virtual void set_sim_thread_func (is_sim_thread_func_t func) {
-    is_sim_thread_func = func;
-  }
-  virtual bool is_sim_thread () {return true;}
-  virtual bool is_wx_selected () {return false;}
-  // provide interface to bx_gui->set_display_mode() method for config
-  // interfaces to use.
-  virtual void set_display_mode (disp_mode_t newmode) {}
-  virtual bool test_for_text_console () { return true; }
-};
-
-BOCHSAPI extern bx_simulator_interface_c *SIM;
-
-BOCHSAPI extern void bx_init_siminterface ();
-BOCHSAPI extern int bx_init_main (int argc, char *argv[]);
-
-#if defined(__WXMSW__) || defined(WIN32)
-// Just to provide HINSTANCE, etc. in files that have not included bochs.h.
-// I don't like this at all, but I don't see a way around it.
-#include <windows.h>
-#endif
-
-// define structure to hold data that is passed into our main function.
-typedef struct BOCHSAPI {
-  // standard argc,argv
-  int argc;
-  char **argv;
-#ifdef WIN32
-  char initial_dir[MAX_PATH];
-#endif
-#ifdef __WXMSW__
-  // these are only used when compiling with wxWindows.  This gives us a
-  // place to store the data that was passed to WinMain.
-  HINSTANCE hInstance;
-  HINSTANCE hPrevInstance;
-  LPSTR m_lpCmdLine;
-  int nCmdShow;
-#endif
-} bx_startup_flags_t;
-
-BOCHSAPI extern bx_startup_flags_t bx_startup_flags;
-BOCHSAPI extern bx_bool bx_user_quit;
diff --git a/tools/ioemu/gui/svga.cc b/tools/ioemu/gui/svga.cc
deleted file mode 100644 (file)
index 33020fc..0000000
+++ /dev/null
@@ -1,514 +0,0 @@
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-#define _MULTI_THREAD
-
-// Define BX_PLUGGABLE in files that can be compiled into plugins.  For
-// platforms that require a special tag on exported symbols, BX_PLUGGABLE 
-// is used to know when we are exporting symbols and when we are importing.
-#define BX_PLUGGABLE
-
-#include "bochs.h"
-#if BX_WITH_SVGA
-
-#include <stdlib.h>
-#include </usr/include/vga.h>
-#include <vgagl.h>
-#include <vgakeyboard.h>
-#include <vgamouse.h>
-
-#include "font/vga.bitmap.h"
-//#include "icon_bochs.h"
-
-class bx_svga_gui_c : public bx_gui_c {
-public:
-  bx_svga_gui_c (void);
-  DECLARE_GUI_VIRTUAL_METHODS()
-  virtual void set_display_mode (disp_mode_t newmode);
-};
-
-// declare one instance of the gui object and call macro to insert the
-// plugin code
-static bx_svga_gui_c *theGui = NULL;
-
-IMPLEMENT_GUI_PLUGIN_CODE(svga)
-
-#define LOG_THIS theGui->
-
-static unsigned res_x, res_y;
-static int fontwidth = 8, fontheight = 16;
-static unsigned tilewidth, tileheight;
-static unsigned char vgafont[256 * 16];
-static int clut8 = 0;
-GraphicsContext *screen = NULL;
-static int save_vga_mode;
-static int save_vga_pal[256 * 3];
-
-void keyboard_handler(int scancode, int press);
-void mouse_handler(int button, int dx, int dy, int dz, 
-                   int drx, int dry, int drz);
-
-unsigned char reverse_byteorder(unsigned char b)
-{
-    unsigned char ret = 0;
-    
-    for (unsigned i=0;i<8;i++){
-       ret |= (b & 0x01) << (7 - i);
-       b >>= 1;
-    }
-    return ret;
-}
-
-void create_vga_font()
-{
-    memcpy(vgafont, bx_vgafont, sizeof(bx_vgafont));
-    
-    for (unsigned i=0;i< sizeof(bx_vgafont);i++) {
-       vgafont[i] = reverse_byteorder(vgafont[i]);
-    }    
-}
-
-bx_svga_gui_c::bx_svga_gui_c ()
-{
-  put("SVGA");
-}
-
-void bx_svga_gui_c::specific_init(
-    int argc,
-    char **argv,
-    unsigned x_tilesize,
-    unsigned y_tilesize,
-    unsigned header_bar_y)
-{
-  tilewidth = x_tilesize;
-  tileheight = y_tilesize;
-
-  if(vga_init() != 0 )
-  {
-    LOG_THIS setonoff(LOGLEV_PANIC, ACT_FATAL);
-    BX_PANIC (("Unable to initialize SVGAlib"));
-    return;
-  }
-  
-  screen = gl_allocatecontext();
-  
-  dimension_update(640,400);
-  create_vga_font();
-  gl_setfont(8, 16, (void *)vgafont);
-  gl_setwritemode(FONT_COMPRESSED);
-  
-  keyboard_init();
-  keyboard_seteventhandler((__keyboard_handler) keyboard_handler);
-
-  vga_setmousesupport(1);
-  mouse_seteventhandler((__mouse_handler) mouse_handler);
-  if (vga_ext_set(VGA_EXT_AVAILABLE, VGA_AVAIL_FLAGS) & VGA_CLUT8) {
-    vga_ext_set(VGA_EXT_SET, VGA_CLUT8);
-    clut8 = 1;
-  }
-  // Save settings to prepare for mode transition in set_display_mode.
-  // If DISP_MODE_SIM is called first, these values will be used.
-  save_vga_mode = vga_getcurrentmode();
-  vga_getpalvec(0, 256, save_vga_pal);
-}
-
-void bx_svga_gui_c::text_update(
-    Bit8u *old_text,
-    Bit8u *new_text,
-    unsigned long cursor_x,
-    unsigned long cursor_y,
-    bx_vga_tminfo_t tm_info,
-    unsigned rows)
-{
-   unsigned x, y, i;
-   unsigned chars, cols;
-   char s[] = " ";
-   static unsigned int previ;
-   unsigned int cursori;
-   
-   cols = res_x/fontwidth;
-
-   cursori = (cursor_y*cols + cursor_x) * 2;
-   
-   chars = cols*rows;
-   
-   for (i=0; i<chars*2; i+=2) {
-        if (i == cursori || i == previ || old_text[i] != new_text[i] ||
-           old_text[i+1] != new_text[i+1]) {
-           
-       s[0] = new_text[i];
-       x = (i/2) % cols;
-       y = (i/2) / cols;
-
-       if (i == cursori) {
-           gl_setfontcolors(new_text[i+1] & 0x0F, (new_text[i+1] & 0xF0) >> 4);
-       } else {
-           gl_setfontcolors((new_text[i+1] & 0xF0) >> 4, new_text[i+1] & 0x0F);
-       }
-       gl_write(x * fontwidth, y * fontheight, s);
-       }
-    }
-    previ = cursori;
-}
-
-  int
-bx_svga_gui_c::get_clipboard_text(Bit8u **bytes, Bit32s *nbytes)
-{
-  return 0;
-}
-
-  int
-bx_svga_gui_c::set_clipboard_text(char *text_snapshot, Bit32u len)
-{
-  return 0;
-}
-
-
-void bx_svga_gui_c::graphics_tile_update(
-    Bit8u *snapshot,
-    unsigned x,
-    unsigned y)
-{
-   gl_putbox(x, y, tilewidth, tileheight, snapshot);
-}
-
-static Bit32u vga_to_bx_key(int key)
-{
-    switch (key) {
-       case SCANCODE_ESCAPE: return BX_KEY_ESC;
-       case SCANCODE_1: return BX_KEY_1;
-       case SCANCODE_2: return BX_KEY_2;
-       case SCANCODE_3: return BX_KEY_3;
-       case SCANCODE_4: return BX_KEY_4;
-       case SCANCODE_5: return BX_KEY_5;
-       case SCANCODE_6: return BX_KEY_6;
-       case SCANCODE_7: return BX_KEY_7;
-       case SCANCODE_8: return BX_KEY_8;
-       case SCANCODE_9: return BX_KEY_9;
-       case SCANCODE_0: return BX_KEY_0;
-
-       case SCANCODE_MINUS: return BX_KEY_MINUS;
-       case SCANCODE_EQUAL: return BX_KEY_EQUALS;
-       case SCANCODE_TAB: return BX_KEY_TAB;
-       case SCANCODE_BACKSPACE: return BX_KEY_BACKSPACE;
-
-       case SCANCODE_Q: return BX_KEY_Q;
-       case SCANCODE_W: return BX_KEY_W;
-       case SCANCODE_E: return BX_KEY_E;
-       case SCANCODE_R: return BX_KEY_R;
-       case SCANCODE_T: return BX_KEY_T;
-       case SCANCODE_Y: return BX_KEY_Y;
-       case SCANCODE_U: return BX_KEY_U;
-       case SCANCODE_I: return BX_KEY_I;
-       case SCANCODE_O: return BX_KEY_O;
-       case SCANCODE_P: return BX_KEY_P;
-
-       case SCANCODE_BRACKET_LEFT: return BX_KEY_LEFT_BRACKET;
-       case SCANCODE_BRACKET_RIGHT: return BX_KEY_RIGHT_BRACKET;
-
-       case SCANCODE_ENTER: return BX_KEY_ENTER;
-       case SCANCODE_LEFTCONTROL: return BX_KEY_CTRL_L;
-
-       case SCANCODE_A: return BX_KEY_A;
-       case SCANCODE_S: return BX_KEY_S;
-       case SCANCODE_D: return BX_KEY_D;
-       case SCANCODE_F: return BX_KEY_F;
-       case SCANCODE_G: return BX_KEY_G;
-       case SCANCODE_H: return BX_KEY_H;
-       case SCANCODE_J: return BX_KEY_J;
-       case SCANCODE_K: return BX_KEY_K;
-       case SCANCODE_L: return BX_KEY_L;
-
-       case SCANCODE_SEMICOLON: return BX_KEY_SEMICOLON;
-       case SCANCODE_APOSTROPHE: return BX_KEY_SINGLE_QUOTE;
-       case SCANCODE_GRAVE: return BX_KEY_GRAVE;
-
-       case SCANCODE_LEFTSHIFT: return BX_KEY_SHIFT_L;
-       case SCANCODE_BACKSLASH: return BX_KEY_BACKSLASH;
-
-       case SCANCODE_Z: return BX_KEY_Z;
-       case SCANCODE_X: return BX_KEY_X;
-       case SCANCODE_C: return BX_KEY_C;
-       case SCANCODE_V: return BX_KEY_V;
-       case SCANCODE_B: return BX_KEY_B;
-       case SCANCODE_N: return BX_KEY_N;
-       case SCANCODE_M: return BX_KEY_M;
-
-       case SCANCODE_COMMA: return BX_KEY_COMMA;
-       case SCANCODE_PERIOD: return BX_KEY_PERIOD;
-       case SCANCODE_SLASH: return BX_KEY_SLASH;
-
-       case SCANCODE_RIGHTSHIFT: return BX_KEY_SHIFT_R;
-       case SCANCODE_KEYPADMULTIPLY: return BX_KEY_KP_MULTIPLY;
-       
-       case SCANCODE_LEFTALT: return BX_KEY_ALT_L;
-       case SCANCODE_SPACE: return BX_KEY_SPACE;
-       case SCANCODE_CAPSLOCK: return BX_KEY_CAPS_LOCK;
-
-       case SCANCODE_F1: return BX_KEY_F1;
-       case SCANCODE_F2: return BX_KEY_F2;
-       case SCANCODE_F3: return BX_KEY_F3;
-       case SCANCODE_F4: return BX_KEY_F4;
-       case SCANCODE_F5: return BX_KEY_F5;
-       case SCANCODE_F6: return BX_KEY_F6;
-       case SCANCODE_F7: return BX_KEY_F7;
-       case SCANCODE_F8: return BX_KEY_F8;
-       case SCANCODE_F9: return BX_KEY_F9;
-       case SCANCODE_F10: return BX_KEY_F10;
-
-       case SCANCODE_NUMLOCK: return BX_KEY_NUM_LOCK;
-       case SCANCODE_SCROLLLOCK: return BX_KEY_SCRL_LOCK;
-       
-       case SCANCODE_KEYPAD7: return BX_KEY_KP_HOME;
-       case SCANCODE_KEYPAD8: return BX_KEY_KP_UP;
-       case SCANCODE_KEYPAD9: return BX_KEY_KP_PAGE_UP;
-       case SCANCODE_KEYPADMINUS: return BX_KEY_KP_SUBTRACT;
-       case SCANCODE_KEYPAD4: return BX_KEY_KP_LEFT;
-       case SCANCODE_KEYPAD5: return BX_KEY_KP_5;
-       case SCANCODE_KEYPAD6: return BX_KEY_KP_RIGHT;
-       case SCANCODE_KEYPADPLUS: return BX_KEY_KP_ADD;
-       case SCANCODE_KEYPAD1: return BX_KEY_KP_END;
-       case SCANCODE_KEYPAD2: return BX_KEY_KP_DOWN;
-       case SCANCODE_KEYPAD3: return BX_KEY_KP_PAGE_DOWN;
-       case SCANCODE_KEYPAD0: return BX_KEY_KP_INSERT;
-//     case SCANCODE_KEYPADPERIOD: return BX_KEY_KP_; /* ??? */
-
-//     case SCANCODE_LESS: return BX_KEY_KP_LESS;      /* ??? */
-
-       case SCANCODE_F11: return BX_KEY_F11;
-       case SCANCODE_F12: return BX_KEY_F12;
-
-       case SCANCODE_KEYPADENTER: return BX_KEY_KP_ENTER;
-       case SCANCODE_RIGHTCONTROL: return BX_KEY_CTRL_R;
-       case SCANCODE_KEYPADDIVIDE: return BX_KEY_KP_DIVIDE;
-       case SCANCODE_PRINTSCREEN: return BX_KEY_PRINT;
-       case SCANCODE_RIGHTALT: return BX_KEY_ALT_R;
-       case SCANCODE_BREAK: return BX_KEY_PAUSE;
-
-       case SCANCODE_HOME: return BX_KEY_HOME;
-       case SCANCODE_CURSORBLOCKUP: return BX_KEY_UP;
-       case SCANCODE_PAGEUP: return BX_KEY_PAGE_UP;
-       case SCANCODE_CURSORBLOCKLEFT: return BX_KEY_LEFT;
-       case SCANCODE_CURSORBLOCKRIGHT: return BX_KEY_RIGHT;
-       case SCANCODE_END: return BX_KEY_END;
-       case SCANCODE_CURSORBLOCKDOWN: return BX_KEY_DOWN;
-       case SCANCODE_PAGEDOWN: return BX_KEY_PAGE_DOWN;
-       case SCANCODE_INSERT: return BX_KEY_INSERT;
-       case SCANCODE_REMOVE: return BX_KEY_DELETE;
-
-       case SCANCODE_RIGHTWIN: return BX_KEY_WIN_R;
-       case SCANCODE_LEFTWIN: return BX_KEY_WIN_L;
-
-       default: return 0;
-    }
-}
-
-void keyboard_handler(int scancode, int press)
-{
-    if (scancode != SCANCODE_F12) {
-       int bx_key = vga_to_bx_key(scancode);
-       Bit32u key_state;
-               
-       if (press) {
-           key_state = BX_KEY_PRESSED;
-       } else { 
-           key_state = BX_KEY_RELEASED;
-       }
-       
-       DEV_kbd_gen_scancode(bx_key | key_state);
-    } else {
-       BX_INFO(("F12 pressed"));
-       // show runtime options menu, which uses stdin/stdout   
-       SIM->configuration_interface (NULL, CI_RUNTIME_CONFIG);
-    }
-}
-
-void mouse_handler(int button, int dx, int dy, int dz, 
-                   int drx, int dry, int drz)
-{
-    int buttons = 0;
-
-    if (button & MOUSE_LEFTBUTTON) {
-       buttons |= 0x01;
-    }
-
-    if (button & MOUSE_RIGHTBUTTON) {
-       buttons |= 0x02;
-    }
-    DEV_mouse_motion((int) (0.25 * dx), (int) -(0.25 * dy), buttons);
-}
-
-void bx_svga_gui_c::handle_events(void)
-{
-    keyboard_update();
-    keyboard_clearstate();
-    mouse_update();
-}
-
-void bx_svga_gui_c::flush(void)
-{
-    gl_copyscreen(screen);
-}
-
-void bx_svga_gui_c::clear_screen(void)
-{
-    gl_clearscreen(0);
-}
-
-bx_bool bx_svga_gui_c::palette_change(
-    unsigned index,
-    unsigned red,
-    unsigned green,
-    unsigned blue)
-{
-  if( index > 255 ) return 0;
-
-  // without VGA_CLUT8 extension we have only 6 bits for each r,g,b value   
-  if (!clut8 && (red > 63 || green > 63 || blue > 63)) {
-       red   = red >> 2;
-       green = green >> 2;
-       blue  = blue >> 2;
-  }
-  
-  vga_setpalette(index, red, green, blue);
-  
-  return 1;
-}
-
-
-void bx_svga_gui_c::dimension_update(
-    unsigned x,
-    unsigned y,
-    unsigned fheight,
-    unsigned fwidth,
-    unsigned bpp)
-{
-  int newmode = 0;
-
-  if (bpp > 8) {
-    BX_PANIC(("%d bpp graphics mode not supported yet", bpp));
-  }
-  if( fheight > 0 )
-  {
-    fontheight = fheight;
-    if (fwidth != 8) {
-      x = x * 8 / fwidth;
-    }
-    fontwidth = 8;
-  }
-
-  if( (x == res_x) && (y == res_y )) return;
-
-  if (x == 640 && y == 480) { 
-    newmode = G640x480x256;
-  } else if (x == 640 && y == 400) {
-    newmode = G640x400x256;
-  } else if (x == 320 && y == 200) {
-    newmode = G320x200x256;
-  }
-  
-  if (!vga_hasmode(newmode)) {
-    newmode = G640x480x256; // trying "default" mode...
-  }
-  
-  if (vga_setmode(newmode) != 0)
-  {
-      LOG_THIS setonoff(LOGLEV_PANIC, ACT_FATAL);
-      BX_PANIC (("Unable to set requested videomode: %ix%i", x, y));
-  }
-  
-  gl_setcontextvga(newmode);
-  gl_getcontext(screen);
-  gl_setcontextvgavirtual(newmode);
-  save_vga_mode = newmode;
-
-  res_x = x;
-  res_y = y;
-}
-
-
-unsigned bx_svga_gui_c::create_bitmap(
-    const unsigned char *bmap,
-    unsigned xdim,
-    unsigned ydim)
-{
-  return 0;
-}
-
-
-unsigned bx_svga_gui_c::headerbar_bitmap(
-    unsigned bmap_id,
-    unsigned alignment,
-    void (*f)(void))
-{
-  return 0;
-}
-
-
-void bx_svga_gui_c::replace_bitmap(
-    unsigned hbar_id,
-    unsigned bmap_id)
-{
-}
-
-
-void bx_svga_gui_c::show_headerbar(void)
-{
-}
-
-
-void bx_svga_gui_c::mouse_enabled_changed_specific (bx_bool val)
-{
-}
-
-
-void headerbar_click(int x)
-{
-}
-
-void bx_svga_gui_c::exit(void)
-{
-    vga_setmode(TEXT);
-    keyboard_close();
-    mouse_close();
-}
-
-void 
-bx_svga_gui_c::set_display_mode (disp_mode_t newmode)
-{
-  // if no mode change, do nothing.
-  if (disp_mode == newmode) return;
-  // remember the display mode for next time
-  disp_mode = newmode;
-  switch (newmode) {
-    case DISP_MODE_CONFIG:
-      BX_DEBUG (("switch to configuration mode (back to console)"));
-      // remember old values and switch to text mode
-      save_vga_mode = vga_getcurrentmode();
-      vga_getpalvec(0, 256, save_vga_pal);
-      keyboard_close();
-      vga_setmode(TEXT);
-      break;
-    case DISP_MODE_SIM:
-      BX_DEBUG (("switch to simulation mode (fullscreen)"));
-      keyboard_init();
-      keyboard_seteventhandler((__keyboard_handler) keyboard_handler);
-      vga_setmode(save_vga_mode);
-      vga_setpalvec(0, 256, save_vga_pal);
-      break;
-  }
-}
-
-#endif /* if BX_WITH_SVGA */
diff --git a/tools/ioemu/gui/term.cc b/tools/ioemu/gui/term.cc
deleted file mode 100644 (file)
index 37bf9c5..0000000
+++ /dev/null
@@ -1,843 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: term.cc,v 1.31 2003/08/17 23:40:38 cbothamy Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2000  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-
-// Define BX_PLUGGABLE in files that can be compiled into plugins.  For
-// platforms that require a special tag on exported symbols, BX_PLUGGABLE 
-// is used to know when we are exporting symbols and when we are importing.
-#define BX_PLUGGABLE
-
-#include "bochs.h"
-#if BX_WITH_TERM
-
-#include "icon_bochs.h"
-
-extern "C" {
-#include <curses.h>
-#include <signal.h>
-};
-
-class bx_term_gui_c : public bx_gui_c {
-public:
-  bx_term_gui_c (void) {}
-  DECLARE_GUI_VIRTUAL_METHODS()
-
-  virtual Bit32u get_sighandler_mask ();
-  // called when registered signal arrives
-  virtual void sighandler (int sig);
-};
-
-// declare one instance of the gui object and call macro to insert the
-// plugin code
-static bx_term_gui_c *theGui = NULL;
-IMPLEMENT_GUI_PLUGIN_CODE(term)
-
-#define LOG_THIS theGui->
-
-bx_bool initialized = 0;
-static unsigned int text_cols = 80, text_rows = 25;
-
-static short curses_color[8] = {
-  /* 0 */ COLOR_BLACK,
-  /* 1 */ COLOR_BLUE,
-  /* 2 */ COLOR_GREEN,
-  /* 3 */ COLOR_CYAN,
-  /* 4 */ COLOR_RED,
-  /* 5 */ COLOR_MAGENTA,
-  /* 6 */ COLOR_YELLOW,
-  /* 7 */ COLOR_WHITE
-};
-
-static chtype vga_to_term[128] = {
-  0xc7, 0xfc, 0xe9, 0xe2, 0xe4, 0xe0, 0xe5, 0xe7,
-  0xea, 0xeb, 0xe8, 0xef, 0xee, 0xec, 0xc4, 0xc5,
-  0xc9, 0xe6, 0xc6, 0xf4, 0xf6, 0xf2, 0xfb, 0xf9,
-  0xff, 0xd6, 0xdc, 0xe7, 0xa3, 0xa5, ' ',  ' ',
-  0xe1, 0xed, 0xf3, 0xfa, 0xf1, 0xd1, 0xaa, 0xba,
-  0xbf, ' ',  0xac, ' ',  ' ',  0xa1, 0xab, 0xbb,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, ' ',  ' ',  ' ',  ' ',
-  ' ',  ' ',  ' ',  ' ',  ' ',  ' ',  0xb5, ' ',
-  ' ',  ' ',  ' ',  ' ',  ' ',  ' ',  ' ',  ' ',
-  ' ',  0xb1, ' ',  ' ',  ' ',  ' ',  0xf7, ' ',
-  0xb0, ' ',  ' ',  ' ',  ' ',  0xb2, ' ',  ' '
-};
-
-static void
-do_scan(int key_event, int shift, int ctrl, int alt)
-{
-       /* XXX At some point, cache alt/ctrl/shift so only when the state
-                changes do we simulate a press or release, to cut down on
-                keyboard input to the simulated machine */
-
-       BX_DEBUG(("key_event %d/0x%x %s%s%s",
-                 key_event,key_event,
-                 shift?"(shift)":"",
-                 ctrl?"(ctrl)":"",
-                 alt?"(alt)":""));
-       if(shift)
-               DEV_kbd_gen_scancode(BX_KEY_SHIFT_L);
-       if(ctrl)
-               DEV_kbd_gen_scancode(BX_KEY_CTRL_L);
-       if(alt)
-               DEV_kbd_gen_scancode(BX_KEY_ALT_L);
-       DEV_kbd_gen_scancode(key_event);
-       key_event |= BX_KEY_RELEASED;
-
-       DEV_kbd_gen_scancode(key_event);
-       if(alt)
-               DEV_kbd_gen_scancode(BX_KEY_ALT_L|BX_KEY_RELEASED);
-       if(ctrl)
-               DEV_kbd_gen_scancode(BX_KEY_CTRL_L|BX_KEY_RELEASED);
-       if(shift)
-               DEV_kbd_gen_scancode(BX_KEY_SHIFT_L|BX_KEY_RELEASED);
-}
-
-Bit32u 
-bx_term_gui_c::get_sighandler_mask ()
-{
-  return 
-    (1<<SIGHUP)
-    | (1<<SIGINT)
-    | (1<<SIGQUIT)
-#ifdef SIGSTOP
-    | (1<<SIGSTOP)
-#endif
-#ifdef SIGTSTP
-    | (1<<SIGTSTP)
-#endif
-    | (1<<SIGTERM);
-}
-
-void
-bx_term_gui_c::sighandler(int signo)
-{
-       switch(signo) {
-       case SIGINT:
-               do_scan(BX_KEY_C,0,1,0);
-               break;
-#ifdef SIGSTOP
-       case SIGSTOP:
-               do_scan(BX_KEY_S,0,1,0);
-               break;
-#endif
-#ifdef SIGTSTP
-       case SIGTSTP:
-               do_scan(BX_KEY_Z,0,1,0);
-               break;
-#endif
-       default:
-               BX_INFO(("sig %d caught",signo));
-               break;
-       }
-}
-
-// ::SPECIFIC_INIT()
-//
-// Called from gui.cc, once upon program startup, to allow for the
-// specific GUI code (X11, BeOS, ...) to be initialized.
-//
-// argc, argv: not used right now, but the intention is to pass native GUI
-//     specific options from the command line.  (X11 options, BeOS options,...)
-//
-// tilewidth, tileheight: for optimization, graphics_tile_update() passes
-//     only updated regions of the screen to the gui code to be redrawn.
-//     These define the dimensions of a region (tile).
-// headerbar_y:  A headerbar (toolbar) is display on the top of the
-//     VGA window, showing floppy status, and other information.  It
-//     always assumes the width of the current VGA mode width, but
-//     it's height is defined by this parameter.
-
-       void
-bx_term_gui_c::specific_init(int argc, char **argv, unsigned tilewidth, unsigned tileheight,
-       unsigned headerbar_y)
-{
-       put("TGUI");
-       UNUSED(argc);
-       UNUSED(argv);
-       UNUSED(tilewidth);
-       UNUSED(tileheight);
-       UNUSED(headerbar_y);
-
-       UNUSED(bochs_icon_bits);  // global variable
-
-       // the ask menu causes trouble
-       io->set_log_action(LOGLEV_PANIC, ACT_FATAL);
-       // logfile should be different from stderr, otherwise terminal mode
-       // really ends up having fun
-       if (!strcmp(bx_options.log.Ofilename->getptr(), "-"))
-               BX_PANIC(("cannot log to stderr in term mode"));
-
-       initscr();
-       start_color();
-       cbreak();
-       curs_set(2);
-       keypad(stdscr,TRUE);
-       nodelay(stdscr, TRUE);
-       noecho();
-
-#if BX_HAVE_COLOR_SET
-       if (has_colors()) {
-               for (int i=0; i<COLORS; i++) {
-                       for (int j=0; j<COLORS; j++) {
-                               if ((i!=0)||(j!=0)) init_pair(i * COLORS + j, j, i);
-                       }
-               }
-       }
-#endif
-
-       if (bx_options.Oprivate_colormap->get ())
-               BX_ERROR(("WARNING: private_colormap option ignored."));
-       initialized = 1;
-}
-
-
-
-void
-do_char(int character,int alt)
-{
-       switch (character) {
-       // control keys
-       case   0x9: do_scan(BX_KEY_TAB,0,0,alt); break;
-       case   0xa: do_scan(BX_KEY_KP_ENTER,0,0,alt); break;
-       case   0xd: do_scan(BX_KEY_KP_DELETE,0,0,alt); break;
-       case   0x1: do_scan(BX_KEY_A,0,1,alt); break;
-       case   0x2: do_scan(BX_KEY_B,0,1,alt); break;
-       case   0x3: do_scan(BX_KEY_C,0,1,alt); break;
-       case   0x4: do_scan(BX_KEY_D,0,1,alt); break;
-       case   0x5: do_scan(BX_KEY_E,0,1,alt); break;
-       case   0x6: do_scan(BX_KEY_F,0,1,alt); break;
-       case   0x7: do_scan(BX_KEY_G,0,1,alt); break;
-       case   0x8: do_scan(BX_KEY_H,0,1,alt); break;
-       case   0xb: do_scan(BX_KEY_K,0,1,alt); break;
-       case   0xc: do_scan(BX_KEY_L,0,1,alt); break;
-       case   0xe: do_scan(BX_KEY_N,0,1,alt); break;
-       case   0xf: do_scan(BX_KEY_O,0,1,alt); break;
-       case  0x10: do_scan(BX_KEY_P,0,1,alt); break;
-       case  0x11: do_scan(BX_KEY_Q,0,1,alt); break;
-       case  0x12: do_scan(BX_KEY_R,0,1,alt); break;
-       case  0x13: do_scan(BX_KEY_S,0,1,alt); break;
-       case  0x14: do_scan(BX_KEY_T,0,1,alt); break;
-       case  0x15: do_scan(BX_KEY_U,0,1,alt); break;
-       case  0x16: do_scan(BX_KEY_V,0,1,alt); break;
-       case  0x17: do_scan(BX_KEY_W,0,1,alt); break;
-       case  0x18: do_scan(BX_KEY_X,0,1,alt); break;
-       case  0x19: do_scan(BX_KEY_Y,0,1,alt); break;
-       case  0x1a: do_scan(BX_KEY_Z,0,1,alt); break;
-       case  0x20: do_scan(BX_KEY_SPACE,0,0,alt); break;
-       case 0x107: do_scan(BX_KEY_BACKSPACE,0,0,alt); break;
-       case 0x102: do_scan(BX_KEY_DOWN,0,0,alt); break;
-       case 0x103: do_scan(BX_KEY_UP,0,0,alt); break;
-       case 0x104: do_scan(BX_KEY_LEFT,0,0,alt); break;
-       case 0x105: do_scan(BX_KEY_RIGHT,0,0,alt); break;
-       case 0x152: do_scan(BX_KEY_PAGE_DOWN,0,0,alt); break;
-       case 0x153: do_scan(BX_KEY_PAGE_UP,0,0,alt); break;
-       case 0x106: do_scan(BX_KEY_HOME,0,0,alt); break;
-       case 0x168: do_scan(BX_KEY_END,0,0,alt); break;
-       case 0x14b: do_scan(BX_KEY_INSERT,0,0,alt); break;
-       case 0x7f:  do_scan(BX_KEY_DELETE,0,0,alt); break;
-       case 0x1b:  do_scan(BX_KEY_ESC,0,0,alt); break;
-       case '!': do_scan(BX_KEY_1,1,0,alt); break;
-       case '\'': do_scan(BX_KEY_SINGLE_QUOTE,0,0,alt); break;
-       case '#': do_scan(BX_KEY_3,1,0,alt); break;
-       case '$': do_scan(BX_KEY_4,1,0,alt); break;
-       case '%': do_scan(BX_KEY_5,1,0,alt); break;
-       case '^': do_scan(BX_KEY_6,1,0,alt); break;
-       case '&': do_scan(BX_KEY_7,1,0,alt); break;
-       case '"': do_scan(BX_KEY_SINGLE_QUOTE,1,0,alt); break;
-
-       // ()*+,-./
-       case '(': do_scan(BX_KEY_9,1,0,alt); break;
-       case ')': do_scan(BX_KEY_0,1,0,alt); break;
-       case '*': do_scan(BX_KEY_8,1,0,alt); break;
-       case '+': do_scan(BX_KEY_EQUALS,1,0,alt); break;
-       case ',': do_scan(BX_KEY_COMMA,0,0,alt); break;
-       case '-': do_scan(BX_KEY_MINUS,0,0,alt); break;
-       case '.': do_scan(BX_KEY_PERIOD,0,0,alt); break;
-       case '/': do_scan(BX_KEY_SLASH,0,0,alt); break;
-
-       // 01234567
-       case '0': do_scan(BX_KEY_0,0,0,alt); break;
-       case '1': do_scan(BX_KEY_1,0,0,alt); break;
-       case '2': do_scan(BX_KEY_2,0,0,alt); break;
-       case '3': do_scan(BX_KEY_3,0,0,alt); break;
-       case '4': do_scan(BX_KEY_4,0,0,alt); break;
-       case '5': do_scan(BX_KEY_5,0,0,alt); break;
-       case '6': do_scan(BX_KEY_6,0,0,alt); break;
-       case '7': do_scan(BX_KEY_7,0,0,alt); break;
-
-       // 89:;<=>?
-       case '8': do_scan(BX_KEY_8,0,0,alt); break;
-       case '9': do_scan(BX_KEY_9,0,0,alt); break;
-       case ':': do_scan(BX_KEY_SEMICOLON,1,0,alt); break;
-       case ';': do_scan(BX_KEY_SEMICOLON,0,0,alt); break;
-       case '<': do_scan(BX_KEY_COMMA,1,0,alt); break;
-       case '=': do_scan(BX_KEY_EQUALS,0,0,alt); break;
-       case '>': do_scan(BX_KEY_PERIOD,1,0,alt); break;
-       case '?': do_scan(BX_KEY_SLASH,1,0,alt); break;
-
-       // @ABCDEFG
-       case '@': do_scan(BX_KEY_2,1,0,alt); break;
-       case 'A': do_scan(BX_KEY_A,1,0,alt); break;
-       case 'B': do_scan(BX_KEY_B,1,0,alt); break;
-       case 'C': do_scan(BX_KEY_C,1,0,alt); break;
-       case 'D': do_scan(BX_KEY_D,1,0,alt); break;
-       case 'E': do_scan(BX_KEY_E,1,0,alt); break;
-       case 'F': do_scan(BX_KEY_F,1,0,alt); break;
-       case 'G': do_scan(BX_KEY_G,1,0,alt); break;
-
-
-       // HIJKLMNO
-       case 'H': do_scan(BX_KEY_H,1,0,alt); break;
-       case 'I': do_scan(BX_KEY_I,1,0,alt); break;
-       case 'J': do_scan(BX_KEY_J,1,0,alt); break;
-       case 'K': do_scan(BX_KEY_K,1,0,alt); break;
-       case 'L': do_scan(BX_KEY_L,1,0,alt); break;
-       case 'M': do_scan(BX_KEY_M,1,0,alt); break;
-       case 'N': do_scan(BX_KEY_N,1,0,alt); break;
-       case 'O': do_scan(BX_KEY_O,1,0,alt); break;
-
-
-       // PQRSTUVW
-       case 'P': do_scan(BX_KEY_P,1,0,alt); break;
-       case 'Q': do_scan(BX_KEY_Q,1,0,alt); break;
-       case 'R': do_scan(BX_KEY_R,1,0,alt); break;
-       case 'S': do_scan(BX_KEY_S,1,0,alt); break;
-       case 'T': do_scan(BX_KEY_T,1,0,alt); break;
-       case 'U': do_scan(BX_KEY_U,1,0,alt); break;
-       case 'V': do_scan(BX_KEY_V,1,0,alt); break;
-       case 'W': do_scan(BX_KEY_W,1,0,alt); break;
-
-       // XYZ[\]^_
-       case 'X': do_scan(BX_KEY_X,1,0,alt); break;
-       case 'Y': do_scan(BX_KEY_Y,1,0,alt); break;
-       case 'Z': do_scan(BX_KEY_Z,1,0,alt); break;
-       case '{': do_scan(BX_KEY_LEFT_BRACKET,1,0,alt); break;
-       case '|': do_scan(BX_KEY_BACKSLASH,1,0,alt); break;
-       case '}': do_scan(BX_KEY_RIGHT_BRACKET,1,0,alt); break;
-       case '_': do_scan(BX_KEY_MINUS,1,0,alt); break;
-
-       // `abcdefg
-       case '`': do_scan(BX_KEY_GRAVE,0,0,alt); break;
-       case 'a': do_scan(BX_KEY_A,0,0,alt); break;
-       case 'b': do_scan(BX_KEY_B,0,0,alt); break;
-       case 'c': do_scan(BX_KEY_C,0,0,alt); break;
-       case 'd': do_scan(BX_KEY_D,0,0,alt); break;
-       case 'e': do_scan(BX_KEY_E,0,0,alt); break;
-       case 'f': do_scan(BX_KEY_F,0,0,alt); break;
-       case 'g': do_scan(BX_KEY_G,0,0,alt); break;
-
-       // hijklmno
-       case 'h': do_scan(BX_KEY_H,0,0,alt); break;
-       case 'i': do_scan(BX_KEY_I,0,0,alt); break;
-       case 'j': do_scan(BX_KEY_J,0,0,alt); break;
-       case 'k': do_scan(BX_KEY_K,0,0,alt); break;
-       case 'l': do_scan(BX_KEY_L,0,0,alt); break;
-       case 'm': do_scan(BX_KEY_M,0,0,alt); break;
-       case 'n': do_scan(BX_KEY_N,0,0,alt); break;
-       case 'o': do_scan(BX_KEY_O,0,0,alt); break;
-
-       // pqrstuvw
-       case 'p': do_scan(BX_KEY_P,0,0,alt); break;
-       case 'q': do_scan(BX_KEY_Q,0,0,alt); break;
-       case 'r': do_scan(BX_KEY_R,0,0,alt); break;
-       case 's': do_scan(BX_KEY_S,0,0,alt); break;
-       case 't': do_scan(BX_KEY_T,0,0,alt); break;
-       case 'u': do_scan(BX_KEY_U,0,0,alt); break;
-       case 'v': do_scan(BX_KEY_V,0,0,alt); break;
-       case 'w': do_scan(BX_KEY_W,0,0,alt); break;
-
-       // xyz{|}~
-       case 'x': do_scan(BX_KEY_X,0,0,alt); break;
-       case 'y': do_scan(BX_KEY_Y,0,0,alt); break;
-       case 'z': do_scan(BX_KEY_Z,0,0,alt); break;
-       case '[': do_scan(BX_KEY_LEFT_BRACKET,0,0,alt); break;
-       case '\\': do_scan(BX_KEY_BACKSLASH,0,0,alt); break;
-       case ']': do_scan(BX_KEY_RIGHT_BRACKET,0,0,alt); break;
-       case '~': do_scan(BX_KEY_GRAVE,1,0,alt); break;
-
-       // function keys
-       case KEY_F(1): do_scan(BX_KEY_F1,0,0,alt); break;
-       case KEY_F(2): do_scan(BX_KEY_F2,0,0,alt); break;
-       case KEY_F(3): do_scan(BX_KEY_F3,0,0,alt); break;
-       case KEY_F(4): do_scan(BX_KEY_F4,0,0,alt); break;
-       case KEY_F(5): do_scan(BX_KEY_F5,0,0,alt); break;
-       case KEY_F(6): do_scan(BX_KEY_F6,0,0,alt); break;
-       case KEY_F(7): do_scan(BX_KEY_F7,0,0,alt); break;
-       case KEY_F(8): do_scan(BX_KEY_F8,0,0,alt); break;
-       case KEY_F(9): do_scan(BX_KEY_F9,0,0,alt); break;
-       case KEY_F(10): do_scan(BX_KEY_F10,0,0,alt); break;
-       case KEY_F(11): do_scan(BX_KEY_F11,0,0,alt); break;
-       case KEY_F(12): do_scan(BX_KEY_F12,0,0,alt); break;
-
-       // shifted function keys
-       case KEY_F(13): do_scan(BX_KEY_F1,1,0,alt); break;
-       case KEY_F(14): do_scan(BX_KEY_F2,1,0,alt); break;
-       case KEY_F(15): do_scan(BX_KEY_F3,1,0,alt); break;
-       case KEY_F(16): do_scan(BX_KEY_F4,1,0,alt); break;
-       case KEY_F(17): do_scan(BX_KEY_F5,1,0,alt); break;
-       case KEY_F(18): do_scan(BX_KEY_F6,1,0,alt); break;
-       case KEY_F(19): do_scan(BX_KEY_F7,1,0,alt); break;
-       case KEY_F(20): do_scan(BX_KEY_F8,1,0,alt); break;
-
-       default:
-               if(character > 0x79) {
-                       do_char(character - 0x80,1);
-                       break;
-               }
-
-               BX_INFO(("character unhandled: 0x%x",character));
-               break;
-       }
-}
-
-
-// ::HANDLE_EVENTS()
-//
-// Called periodically (vga_update_interval in .bochsrc) so the
-// the gui code can poll for keyboard, mouse, and other
-// relevant events.
-
-       void
-bx_term_gui_c::handle_events(void)
-{
-       int character;
-       while((character = getch()) != ERR) {
-               BX_DEBUG(("scancode(0x%x)",character));
-               do_char(character,0);
-       }
-}
-
-
-
-// ::FLUSH()
-//
-// Called periodically, requesting that the gui code flush all pending
-// screen update requests.
-
-       void
-bx_term_gui_c::flush(void)
-{
-       if (initialized)
-         refresh();
-}
-
-
-// ::CLEAR_SCREEN()
-//
-// Called to request that the VGA region is cleared.  Don't
-// clear the area that defines the headerbar.
-
-       void
-bx_term_gui_c::clear_screen(void)
-{
-  clear();
-#if BX_HAVE_COLOR_SET
-  color_set(7, NULL);
-#endif
-#if BX_HAVE_MVHLINE
-  if (LINES > (int)text_rows) {
-    mvhline(text_rows, 0, ACS_HLINE, text_cols);
-  }
-#endif
-#if BX_HAVE_MVVLINE
-  if (COLS > (int)text_cols) {
-    mvvline(0, text_cols, ACS_VLINE, text_rows);
-  }
-#endif
-  if ((LINES > (int)text_rows) && (COLS > (int)text_cols)) {
-    mvaddch(text_rows, text_cols, ACS_LRCORNER);
-  }
-}
-
-int
-get_color_pair(Bit8u vga_attr)
-{
-       int term_attr;
-
-       term_attr = curses_color[vga_attr & 0x07];
-       term_attr |= (curses_color[(vga_attr & 0x70) >> 4] << 3);
-       return term_attr;
-}
-
-chtype
-get_term_char(Bit8u vga_char[])
-{
-  int term_char;
-
-  if ((vga_char[1] & 0x0f) == ((vga_char[1] >> 4) & 0x0f)) {
-    return ' ';
-  }
-  switch (vga_char[0]) {
-    case 0x04: term_char = ACS_DIAMOND; break;
-    case 0x18: term_char = ACS_UARROW; break;
-    case 0x19: term_char = ACS_DARROW; break;
-    case 0x1a: term_char = ACS_RARROW; break;
-    case 0x1b: term_char = ACS_LARROW; break;
-    case 0xc4:
-    case 0xcd: term_char = ACS_HLINE; break;
-    case 0xb3:
-    case 0xba: term_char = ACS_VLINE; break;
-    case 0xc9:
-    case 0xd5:
-    case 0xd6:
-    case 0xda: term_char = ACS_ULCORNER; break;
-    case 0xb7:
-    case 0xb8:
-    case 0xbb:
-    case 0xbf: term_char = ACS_URCORNER; break;
-    case 0xc0:
-    case 0xc8:
-    case 0xd3:
-    case 0xd4: term_char = ACS_LLCORNER; break;
-    case 0xbc:
-    case 0xbd:
-    case 0xbe:
-    case 0xd9: term_char = ACS_LRCORNER; break;
-    case 0xc3:
-    case 0xc6:
-    case 0xc7:
-    case 0xcc: term_char = ACS_LTEE; break;
-    case 0xb4:
-    case 0xb5:
-    case 0xb6:
-    case 0xb9: term_char = ACS_RTEE; break;
-    case 0xc2:
-    case 0xcb:
-    case 0xd1:
-    case 0xd2: term_char = ACS_TTEE; break;
-    case 0xc1:
-    case 0xca:
-    case 0xcf:
-    case 0xd0: term_char = ACS_BTEE; break;
-    case 0xc5:
-    case 0xce:
-    case 0xd7:
-    case 0xd8: term_char = ACS_PLUS; break;
-    case 0xb0:
-    case 0xb1: term_char = ACS_CKBOARD; break;
-    case 0xb2: term_char = ACS_BOARD; break;
-    case 0xdb: term_char = ACS_BLOCK; break;
-    default:
-      if (vga_char[0] > 0x7f) {
-        term_char = vga_to_term[vga_char[0]-0x80];
-      } else if (vga_char[0] > 0x1f) {
-        term_char = vga_char[0];
-      } else {
-        term_char = ' ';
-      }
-  }
-  return term_char;
-}
-
-// ::TEXT_UPDATE()
-//
-// Called in a VGA text mode, to update the screen with
-// new content.
-//
-// old_text: array of character/attributes making up the contents
-//           of the screen from the last call.  See below
-// new_text: array of character/attributes making up the current
-//           contents, which should now be displayed.  See below
-//
-// format of old_text & new_text: each is 4000 bytes long.
-//     This represents 80 characters wide by 25 high, with
-//     each character being 2 bytes.  The first by is the
-//     character value, the second is the attribute byte.
-//     I currently don't handle the attribute byte.
-//
-// cursor_x: new x location of cursor
-// cursor_y: new y location of cursor
-
-       void
-bx_term_gui_c::text_update(Bit8u *old_text, Bit8u *new_text,
-       unsigned long cursor_x, unsigned long cursor_y,
-       bx_vga_tminfo_t tm_info, unsigned nrows)
-{
-  unsigned char *old_line, *new_line, *new_start;
-  unsigned char cAttr;
-  unsigned int hchars, rows, x, y;
-  chtype ch;
-  bx_bool force_update = 0;
-
-  UNUSED(nrows);
-
-  if(charmap_updated) {
-    force_update = 1;
-    charmap_updated = 0;
-  }
-
-  new_start = new_text;
-  rows = text_rows;
-  y = 0;
-  do {
-    hchars = text_cols;
-    new_line = new_text;
-    old_line = old_text;
-    x = 0;
-    do {
-      if (force_update || (old_text[0] != new_text[0])
-          || (old_text[1] != new_text[1])) {
-#if BX_HAVE_COLOR_SET
-        if (has_colors()) {
-          color_set(get_color_pair(new_text[1]), NULL);
-        }
-#endif
-        ch = get_term_char(&new_text[0]);
-        if ((new_text[1] & 0x08) > 0) ch |= A_BOLD;
-        if ((new_text[1] & 0x80) > 0) ch |= A_BLINK;
-        mvaddch(y, x, ch);
-      }
-      x++;
-      new_text+=2;
-      old_text+=2;
-    } while (--hchars);
-    y++;
-    new_text = new_line + tm_info.line_offset;
-    old_text = old_line + tm_info.line_offset;
-  } while (--rows);
-
-  if ((cursor_x<text_cols) && (cursor_y<text_rows)
-      && (tm_info.cs_start <= tm_info.cs_end)) {
-    if(cursor_x>0)
-      cursor_x--;
-    else {
-      cursor_x=COLS-1;
-      cursor_y--;
-    }
-    cAttr = new_start[cursor_y*tm_info.line_offset+cursor_x*2+1];
-#if BX_HAVE_COLOR_SET
-    if (has_colors()) {
-      color_set(get_color_pair(cAttr), NULL);
-    }
-#endif
-    ch = get_term_char(&new_start[cursor_y*tm_info.line_offset+cursor_x*2]);
-    if ((cAttr & 0x08) > 0) ch |= A_BOLD;
-    if ((cAttr & 0x80) > 0) ch |= A_REVERSE;
-    mvaddch(cursor_y, cursor_x, ch);
-    curs_set(2);
-  } else {
-    curs_set(0);
-  }
-}
-
-  int
-bx_term_gui_c::get_clipboard_text(Bit8u **bytes, Bit32s *nbytes)
-{
-  return 0;
-}
-
-  int
-bx_term_gui_c::set_clipboard_text(char *text_snapshot, Bit32u len)
-{
-  return 0;
-}
-
-
-// ::PALETTE_CHANGE()
-//
-// Allocate a color in the native GUI, for this color, and put
-// it in the colormap location 'index'.
-// returns: 0=no screen update needed (color map change has direct effect)
-//          1=screen updated needed (redraw using current colormap)
-
-       bx_bool
-bx_term_gui_c::palette_change(unsigned index, unsigned red, unsigned green, unsigned blue)
-{
-       BX_DEBUG(("color pallete request (%d,%d,%d,%d) ignored",
-                 index,red,green,blue));
-       return(0);
-}
-
-
-// ::GRAPHICS_TILE_UPDATE()
-//
-// Called to request that a tile of graphics be drawn to the
-// screen, since info in this region has changed.
-//
-// tile: array of 8bit values representing a block of pixels with
-//       dimension equal to the 'tilewidth' & 'tileheight' parameters to
-//       ::specific_init().  Each value specifies an index into the
-//       array of colors you allocated for ::palette_change()
-// x0: x origin of tile
-// y0: y origin of tile
-//
-// note: origin of tile and of window based on (0,0) being in the upper
-//       left of the window.
-
-       void
-bx_term_gui_c::graphics_tile_update(Bit8u *tile, unsigned x0, unsigned y0)
-{
-       UNUSED(tile);
-       UNUSED(x0);
-       UNUSED(y0);
-}
-
-
-
-// ::DIMENSION_UPDATE()
-//
-// Called when the VGA mode changes it's X,Y dimensions.
-// Resize the window to this size, but you need to add on
-// the height of the headerbar to the Y value.
-//
-// x: new VGA x size
-// y: new VGA y size (add headerbar_y parameter from ::specific_init().
-// fheight: new VGA character height in text mode
-// fwidth : new VGA character width in text mode
-// bpp : bits per pixel in graphics mode
-
-       void
-bx_term_gui_c::dimension_update(unsigned x, unsigned y, unsigned fheight, unsigned fwidth, unsigned bpp)
-{
-  if (bpp > 8) {
-    BX_PANIC(("%d bpp graphics mode not supported", bpp));
-  }
-  if (fheight > 0) {
-    text_cols = x / fwidth;
-    text_rows = y / fheight;
-#if BX_HAVE_COLOR_SET
-    color_set(7, NULL);
-#endif
-#if BX_HAVE_MVHLINE
-    if (LINES > (int)text_rows) {
-      mvhline(text_rows, 0, ACS_HLINE, text_cols);
-    }
-#endif
-#if BX_HAVE_MVVLINE
-    if (COLS > (int)text_cols) {
-      mvvline(0, text_cols, ACS_VLINE, text_rows);
-    }
-#endif
-    if ((LINES > (int)text_rows) && (COLS > (int)text_cols)) {
-      mvaddch(text_rows, text_cols, ACS_LRCORNER);
-    }
-  }
-}
-
-
-// ::CREATE_BITMAP()
-//
-// Create a monochrome bitmap of size 'xdim' by 'ydim', which will
-// be drawn in the headerbar.  Return an integer ID to the bitmap,
-// with which the bitmap can be referenced later.
-//
-// bmap: packed 8 pixels-per-byte bitmap.  The pixel order is:
-//       bit0 is the left most pixel, bit7 is the right most pixel.
-// xdim: x dimension of bitmap
-// ydim: y dimension of bitmap
-
-       unsigned
-bx_term_gui_c::create_bitmap(const unsigned char *bmap, unsigned xdim, unsigned ydim)
-{
-       UNUSED(bmap);
-       UNUSED(xdim);
-       UNUSED(ydim);
-       return(0);
-}
-
-
-// ::HEADERBAR_BITMAP()
-//
-// Called to install a bitmap in the bochs headerbar (toolbar).
-//
-// bmap_id: will correspond to an ID returned from
-//     ::create_bitmap().  'alignment' is either BX_GRAVITY_LEFT
-//     or BX_GRAVITY_RIGHT, meaning install the bitmap in the next
-//     available leftmost or rightmost space.
-// alignment: is either BX_GRAVITY_LEFT or BX_GRAVITY_RIGHT,
-//     meaning install the bitmap in the next
-//     available leftmost or rightmost space.
-// f: a 'C' function pointer to callback when the mouse is clicked in
-//     the boundaries of this bitmap.
-
-       unsigned
-bx_term_gui_c::headerbar_bitmap(unsigned bmap_id, unsigned alignment, void (*f)(void))
-{
-       UNUSED(bmap_id);
-       UNUSED(alignment);
-       UNUSED(f);
-       return(0);
-}
-
-
-// ::SHOW_HEADERBAR()
-//
-// Show (redraw) the current headerbar, which is composed of
-// currently installed bitmaps.
-
-       void
-bx_term_gui_c::show_headerbar(void)
-{
-}
-
-
-// ::REPLACE_BITMAP()
-//
-// Replace the bitmap installed in the headerbar ID slot 'hbar_id',
-// with the one specified by 'bmap_id'.  'bmap_id' will have
-// been generated by ::create_bitmap().  The old and new bitmap
-// must be of the same size.  This allows the bitmap the user
-// sees to change, when some action occurs.  For example when
-// the user presses on the floppy icon, it then displays
-// the ejected status.
-//
-// hbar_id: headerbar slot ID
-// bmap_id: bitmap ID
-
-       void
-bx_term_gui_c::replace_bitmap(unsigned hbar_id, unsigned bmap_id)
-{
-       UNUSED(hbar_id);
-       UNUSED(bmap_id);
-}
-
-
-// ::EXIT()
-//
-// Called before bochs terminates, to allow for a graceful
-// exit from the native GUI mechanism.
-
-       void
-bx_term_gui_c::exit(void)
-{
-       if (!initialized) return;
-       clear();
-       flush();
-       endwin();
-       BX_DEBUG(("exiting"));
-}
-
-  void
-bx_term_gui_c::mouse_enabled_changed_specific (bx_bool val)
-{
-}
-#endif /* if BX_WITH_TERM */
diff --git a/tools/ioemu/gui/textconfig.cc b/tools/ioemu/gui/textconfig.cc
deleted file mode 100644 (file)
index 7b5b098..0000000
+++ /dev/null
@@ -1,995 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: textconfig.cc,v 1.18 2003/10/24 15:39:57 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-// This is code for a text-mode configuration interface.  Note that this file
-// does NOT include bochs.h.  Instead, it does all of its contact with
-// the simulator through an object called SIM, defined in siminterface.cc
-// and siminterface.h.  This separation adds an extra layer of method
-// calls before any work can be done, but the benefit is that the compiler
-// enforces the rules.  I can guarantee that textconfig.cc doesn't call any
-// I/O device objects directly, for example, because the bx_devices symbol
-// isn't even defined in this context.
-//
-
-#include "config.h"
-
-extern "C" {
-#include <stdio.h>
-#include <ctype.h>
-#include <string.h>
-#include <assert.h>
-}
-#include "osdep.h"
-#include "textconfig.h"
-#include "siminterface.h"
-#include "extplugin.h"
-#ifdef WIN32
-#include "win32dialog.h"
-#endif
-
-#define CI_PATH_LENGTH 512
-
-#define BX_INSERTED 11
-
-/* functions for changing particular options */
-void bx_config_interface_init ();
-int bx_read_rc (char *rc);
-int bx_write_rc (char *rc);
-void bx_log_options (int individual);
-
-/******************************************************************/
-/* lots of code stolen from bximage.c */
-/* remove leading spaces, newline junk at end.  returns pointer to 
- cleaned string, which is between s0 and the null */
-char *
-clean_string (char *s0)
-{
-  char *s = s0;
-  char *ptr;
-  /* find first nonblank */
-  while (isspace (*s))
-    s++;
-  /* truncate string at first non-alphanumeric */
-  ptr = s;
-  while (isprint (*ptr))
-    ptr++;
-  *ptr = 0;
-  return s;
-}
-
-void
-double_percent (char *s, int max_len)
-{
-  char d[CI_PATH_LENGTH];
-  int  i=0,j=0;
-
-  if (max_len>CI_PATH_LENGTH)
-    max_len=CI_PATH_LENGTH;
-
-  max_len--;
-
-  while((s[i]!=0)&&(j<max_len))
-  {
-    d[j++]=s[i];
-    if((s[i]=='%')&&(j<max_len))
-    {
-      d[j++]=s[i];
-    }
-    i++;
-  }
-  d[j]=0;
-  strcpy(s,d);
-}
-
-/* returns 0 on success, -1 on failure.  The value goes into out. */
-int 
-ask_uint (char *prompt, Bit32u min, Bit32u max, Bit32u the_default, Bit32u *out, int base)
-{
-  Bit32u n = max + 1;
-  char buffer[1024];
-  char *clean;
-  int illegal;
-  assert (base==10 || base==16);
-  while (1) {
-    printf (prompt, the_default);
-    if (!fgets (buffer, sizeof(buffer), stdin))
-      return -1;
-    clean = clean_string (buffer);
-    if (strlen(clean) < 1) {
-      // empty line, use the default
-      *out = the_default;
-      return 0;
-    }
-    const char *format = (base==10) ? "%d" : "%x";
-    illegal = (1 != sscanf (buffer, format, &n));
-    if (illegal || n<min || n>max) {
-      printf ("Your choice (%s) was not an integer between %u and %u.\n\n",
-         clean, min, max);
-    } else {
-      // choice is okay
-      *out = n;
-      return 0;
-    }
-  }
-}
-
-// identical to ask_uint, but uses signed comparisons
-int 
-ask_int (char *prompt, Bit32s min, Bit32s max, Bit32s the_default, Bit32s *out)
-{
-  int n = max + 1;
-  char buffer[1024];
-  char *clean;
-  int illegal;
-  while (1) {
-    printf (prompt, the_default);
-    if (!fgets (buffer, sizeof(buffer), stdin))
-      return -1;
-    clean = clean_string (buffer);
-    if (strlen(clean) < 1) {
-      // empty line, use the default
-      *out = the_default;
-      return 0;
-    }
-    illegal = (1 != sscanf (buffer, "%d", &n));
-    if (illegal || n<min || n>max) {
-      printf ("Your choice (%s) was not an integer between %d and %d.\n\n",
-         clean, min, max);
-    } else {
-      // choice is okay
-      *out = n;
-      return 0;
-    }
-  }
-}
-
-int 
-ask_menu (char *prompt, int n_choices, char *choice[], int the_default, int *out)
-{
-  char buffer[1024];
-  char *clean;
-  int i;
-  *out = -1;
-  while (1) {
-    printf (prompt, choice[the_default]);
-    if (!fgets (buffer, sizeof(buffer), stdin))
-      return -1;
-    clean = clean_string (buffer);
-    if (strlen(clean) < 1) {
-      // empty line, use the default
-      *out = the_default;
-      return 0;
-    }
-    for (i=0; i<n_choices; i++) {
-      if (!strcmp (choice[i], clean)) {
-       // matched, return the choice number
-       *out = i;
-       return 0;
-      }
-    }
-    if (clean[0] != '?')
-      printf ("Your choice (%s) did not match any of the choices:\n", clean);
-    for (i=0; i<n_choices; i++) {
-      if (i>0) printf (", ");
-      printf ("%s", choice[i]);
-    }
-    printf ("\n");
-  }
-}
-
-int 
-ask_yn (char *prompt, Bit32u the_default, Bit32u *out)
-{
-  char buffer[16];
-  char *clean;
-  *out = 1<<31;
-  while (1) {
-    // if there's a %s field, substitute in the default yes/no.
-    printf (prompt, the_default ? "yes" : "no");
-    if (!fgets (buffer, sizeof(buffer), stdin))
-      return -1;
-    clean = clean_string (buffer);
-    if (strlen(clean) < 1) {
-      // empty line, use the default
-      *out = the_default;
-      return 0;
-    }
-    switch (tolower(clean[0])) {
-      case 'y': *out=1; return 0;
-      case 'n': *out=0; return 0;
-    }
-    printf ("Please type either yes or no.\n");
-  }
-}
-
-// returns -1 on error (stream closed or  something)
-// returns 0 if default was taken
-// returns 1 if value changed
-int 
-ask_string (char *prompt, char *the_default, char *out)
-{
-  char buffer[1024];
-  char *clean;
-  assert (the_default != out);
-  out[0] = 0;
-  printf (prompt, the_default);
-  if (fgets (buffer, sizeof(buffer), stdin) == NULL)
-    return -1;
-  clean = clean_string (buffer);
-  if (strlen(clean) < 1) {
-    // empty line, use the default
-    strcpy (out, the_default);
-    return 0;
-  }
-  strcpy (out, clean);
-  return 1;
-}
-
-/******************************************************************/
-
-static char *startup_menu_prompt =
-"------------------------------\n"
-"Bochs Configuration: Main Menu\n"
-"------------------------------\n"
-"\n"
-"This is the Bochs Configuration Interface, where you can describe the\n"
-"machine that you want to simulate.  Bochs has already searched for a\n"
-"configuration file (typically called bochsrc.txt) and loaded it if it\n"
-"could be found.  When you are satisfied with the configuration, go\n"
-"ahead and start the simulation.\n"
-"\n"
-"You can also start bochs with the -q option to skip these menus.\n"
-"\n"
-"1. Restore factory default configuration\n"
-"2. Read options from...\n"
-"3. Edit options\n"
-"4. Save options to...\n"
-"5. Begin simulation\n"
-"6. Quit now\n"
-"\n"
-"Please choose one: [%d] ";
-
-static char *startup_options_prompt =
-"------------------\n"
-"Bochs Options Menu\n"
-"------------------\n"
-"0. Return to previous menu\n"
-"1. Log file: %s\n"
-"2. Log prefix: %s\n"
-"3. Debug log file: %s\n"
-"4. Log options for all devices\n"
-"5. Log options for individual devices\n"
-"6. Memory options\n"
-"7. Interface options\n"
-"8. Disk options\n"
-"9. Serial or Parallel port options\n"
-"10. Sound Blaster 16 options\n"
-"11. NE2000 network card options\n"
-"12. Keyboard options\n"
-"13. Other options\n"
-"\n"
-"Please choose one: [0] ";
-
-static char *runtime_menu_prompt =
-"---------------------\n"
-"Bochs Runtime Options\n"
-"---------------------\n"
-"1. Floppy disk 0: %s\n"
-"2. Floppy disk 1: %s\n"
-"3. 1st CDROM: %s\n"
-"4. 2nd CDROM: %s\n"
-"5. 3rd CDROM: %s\n"
-"6. 4th CDROM: %s\n"
-"7. (not implemented)\n"
-"8. Log options for all devices\n"
-"9. Log options for individual devices\n"
-"10. VGA Update Interval: %d\n"
-"11. Mouse: %s\n"
-"12. Keyboard paste delay: %d\n"
-"13. Userbutton shortcut: %s\n"
-"14. Instruction tracing: off (doesn't exist yet)\n"
-"15. Continue simulation\n"
-"16. Quit now\n"
-"\n"
-"Please choose one:  [15] ";
-
-#define NOT_IMPLEMENTED(choice) \
-  fprintf (stderr, "ERROR: choice %d not implemented\n", choice);
-
-#define BAD_OPTION(menu,choice) \
-  do {fprintf (stderr, "ERROR: menu %d has no choice %d\n", menu, choice); \
-      assert (0); } while (0)
-
-void build_runtime_options_prompt (char *format, char *buf, int size)
-{
-  bx_floppy_options floppyop;
-  bx_atadevice_options cdromop;
-/*  bx_param_num_c *ips = SIM->get_param_num (BXP_IPS); */
-  char buffer[6][128];
-  for (int i=0; i<2; i++) {
-    SIM->get_floppy_options (i, &floppyop);
-    if (floppyop.Odevtype->get () == BX_FLOPPY_NONE)
-      strcpy (buffer[i], "(not present)");
-    else {
-      sprintf (buffer[i], "%s, size=%s, %s", floppyop.Opath->getptr (),
-        SIM->get_floppy_type_name (floppyop.Otype->get ()),
-        (floppyop.Ostatus->get () == BX_INSERTED)? "inserted" : "ejected");
-      if (!floppyop.Opath->getptr ()[0]) strcpy (buffer[i], "none");
-    }
-  }
-
-  // 4 cdroms supported at run time
-  int device;
-  for (Bit8u cdrom=0; cdrom<4; cdrom++) {
-    if (!SIM->get_cdrom_options (cdrom, &cdromop, &device) || !cdromop.Opresent->get ())
-      sprintf (buffer[2+cdrom], "(not present)");
-    else
-      sprintf (buffer[2+cdrom], "(%s on ata%d) %s, %s",
-        device&1?"slave":"master", device/2, cdromop.Opath->getptr (),
-        (cdromop.Ostatus->get () == BX_INSERTED)? "inserted" : "ejected");
-    }
-
-  snprintf (buf, size, format, buffer[0], buffer[1], buffer[2], 
-      buffer[3], buffer[4], buffer[5],
-      /* ips->get (), */
-      SIM->get_param_num (BXP_VGA_UPDATE_INTERVAL)->get (), 
-      SIM->get_param_num (BXP_MOUSE_ENABLED)->get () ? "enabled" : "disabled",
-      SIM->get_param_num (BXP_KBD_PASTE_DELAY)->get (),
-      SIM->get_param_string (BXP_USER_SHORTCUT)->getptr ());
-}
-
-int do_menu (bx_id id) {
-  bx_list_c *menu = (bx_list_c *)SIM->get_param (id);
-  while (1) {
-    menu->get_choice()->set (0);
-    int status = menu->text_ask (stdin, stderr);
-    if (status < 0) return status;
-    bx_param_num_c *choice = menu->get_choice();
-    if (choice->get () < 1)
-      return choice->get ();
-    else {
-      int index = choice->get () - 1;  // choosing 1 means list[0]
-      bx_param_c *chosen = menu->get (index);
-      assert (chosen != NULL);
-      chosen->text_ask (stdin, stderr);
-    }
-  }
-}
-
-void askparam (bx_id id)
-{
-  bx_param_c *param = SIM->get_param (id);
-  param->text_ask (stdin, stderr);
-}
-
-int bx_config_interface (int menu)
-{
- Bit32u choice;
- while (1) {
-  switch (menu)
-  {
-   case BX_CI_INIT:
-     bx_config_interface_init ();
-     return 0;
-   case BX_CI_START_SIMULATION: {
-     SIM->begin_simulation (bx_startup_flags.argc, bx_startup_flags.argv);
-     // we don't expect it to return, but if it does, quit
-     SIM->quit_sim(1);
-     break;
-     }
-   case BX_CI_START_MENU:
-     {
-       Bit32u default_choice;
-       switch (SIM->get_param_enum(BXP_BOCHS_START)->get ()) {
-         case BX_LOAD_START: 
-           default_choice = 2; break;
-         case BX_EDIT_START: 
-           default_choice = 3; break;
-         default: 
-           default_choice = 5; break;
-       }
-
-       if (ask_uint (startup_menu_prompt, 1, 6, default_choice, &choice, 10) < 0) return -1;
-       switch (choice) {
-        case 1:
-          fprintf (stderr, "I reset all options back to their factory defaults.\n\n");
-          SIM->reset_all_param ();
-          SIM->get_param_enum(BXP_BOCHS_START)->set(BX_EDIT_START);
-          break;
-        case 2: 
-          // Before reading a new configuration, reset every option to its
-          // original state.
-          SIM->reset_all_param ();
-          if (bx_read_rc (NULL) >= 0)
-            SIM->get_param_enum(BXP_BOCHS_START)->set(BX_RUN_START);
-          break;
-        case 3: 
-           bx_config_interface (BX_CI_START_OPTS); 
-          SIM->get_param_enum(BXP_BOCHS_START)->set(BX_RUN_START);
-           break;
-        case 4: bx_write_rc (NULL); break;
-        case 5: bx_config_interface (BX_CI_START_SIMULATION); break;
-        case 6: SIM->quit_sim (1); return -1;
-        default: BAD_OPTION(menu, choice);
-       }
-     }
-     break;
-   case BX_CI_START_OPTS:
-     {
-       char prompt[CI_PATH_LENGTH];
-       char oldpath[CI_PATH_LENGTH];
-       char olddebuggerpath[CI_PATH_LENGTH];
-       char oldprefix[CI_PATH_LENGTH];
-       int  retval;
-
-       retval = SIM->get_log_file (oldpath, CI_PATH_LENGTH);
-       assert (retval >= 0);
-       double_percent(oldpath,CI_PATH_LENGTH);
-       retval = SIM->get_log_prefix (oldprefix, CI_PATH_LENGTH);
-       assert (retval >= 0);
-       double_percent(oldprefix,CI_PATH_LENGTH);
-       retval = SIM->get_debugger_log_file (olddebuggerpath, CI_PATH_LENGTH);
-       assert (retval >= 0);
-       double_percent(olddebuggerpath,CI_PATH_LENGTH);
-
-       sprintf (prompt, startup_options_prompt, oldpath, oldprefix, olddebuggerpath);
-       if (ask_uint (prompt, 0, 13, 0, &choice, 10) < 0) return -1;
-       switch (choice) {
-        case 0: return 0;
-        case 1: askparam (BXP_LOG_FILENAME); break;
-        case 2: askparam (BXP_LOG_PREFIX); break;
-        case 3: askparam (BXP_DEBUGGER_LOG_FILENAME); break;
-        case 4: bx_log_options (0); break;
-        case 5: bx_log_options (1); break;
-        case 6: do_menu (BXP_MENU_MEMORY); break;
-        case 7: do_menu (BXP_MENU_INTERFACE); break;
-        case 8: do_menu (BXP_MENU_DISK); break;
-        case 9: do_menu (BXP_MENU_SERIAL_PARALLEL); break;
-        case 10: do_menu (BXP_SB16); break;
-        case 11: do_menu (BXP_NE2K); break;
-        case 12: do_menu (BXP_MENU_KEYBOARD); break;
-        case 13: do_menu (BXP_MENU_MISC); break;
-        default: BAD_OPTION(menu, choice);
-       }
-     }
-     break;
-   case BX_CI_RUNTIME:
-     char prompt[1024];
-     bx_floppy_options floppyop;
-     bx_atadevice_options cdromop;
-     build_runtime_options_prompt (runtime_menu_prompt, prompt, 1024);
-     if (ask_uint (prompt, 1, 16, 15, &choice, 10) < 0) return -1;
-     switch (choice) {
-       case 1: 
-         SIM->get_floppy_options (0, &floppyop);
-        if (floppyop.Odevtype->get () != BX_FLOPPY_NONE) do_menu (BXP_FLOPPYA);
-        break;
-       case 2:
-         SIM->get_floppy_options (1, &floppyop);
-        if (floppyop.Odevtype->get () != BX_FLOPPY_NONE) do_menu (BXP_FLOPPYB);
-        break;
-       case 3:
-       case 4:
-       case 5:
-       case 6:
-        int device;
-         if (SIM->get_cdrom_options (choice - 3, &cdromop, &device) && cdromop.Opresent->get ()) {
-          // disable type selection
-          SIM->get_param((bx_id)(BXP_ATA0_MASTER_TYPE + device))->set_enabled(0);
-          SIM->get_param((bx_id)(BXP_ATA0_MASTER_MODEL + device))->set_enabled(0);
-          SIM->get_param((bx_id)(BXP_ATA0_MASTER_BIOSDETECT + device))->set_enabled(0);
-           do_menu ((bx_id)(BXP_ATA0_MASTER + device));
-           }
-        break;
-       case 7: // not implemented yet because I would have to mess with
-              // resetting timers and pits and everything on the fly.
-               // askparam (BXP_IPS);
-              break;
-       case 8: bx_log_options (0); break;
-       case 9: bx_log_options (1); break;
-       case 10: askparam (BXP_VGA_UPDATE_INTERVAL); break;
-       case 11: askparam (BXP_MOUSE_ENABLED); break;
-       case 12: askparam (BXP_KBD_PASTE_DELAY); break;
-       case 13: askparam (BXP_USER_SHORTCUT); break;
-       case 14: NOT_IMPLEMENTED (choice); break;
-       case 15: fprintf (stderr, "Continuing simulation\n"); return 0;
-       case 16:
-        fprintf (stderr, "You chose quit on the configuration interface.\n");
-        SIM->quit_sim (1);
-        return -1;
-       default: fprintf (stderr, "Menu choice %d not implemented.\n", choice);
-     }
-     break;
-   default:
-     fprintf (stderr, "Unknown config interface menu type.\n");
-     assert (menu >=0 && menu < BX_CI_N_MENUS);
-  }
- }
-}
-
-static void bx_print_log_action_table ()
-{
-  // just try to print all the prefixes first.
-  fprintf (stderr, "Current log settings:\n");
-  fprintf (stderr, "                 Debug      Info       Error       Panic       Pass\n");
-  fprintf (stderr, "ID    Device     Action     Action     Action      Action      Action\n");
-  fprintf (stderr, "----  ---------  ---------  ---------  ----------  ----------  ----------\n");
-  int i, j, imax=SIM->get_n_log_modules ();
-  for (i=0; i<imax; i++) {
-    if (strcmp(SIM->get_prefix(i), "[     ]")) {
-      fprintf (stderr, "%3d.  %s ", i, SIM->get_prefix (i));
-      for (j=0; j<SIM->get_max_log_level (); j++) {
-        fprintf (stderr, "%10s ", SIM->get_action_name (SIM->get_log_action (i, j)));
-      }
-      fprintf (stderr, "\n");
-    }
-  }
-}
-
-static char *log_options_prompt1 = "Enter the ID of the device to edit, or -1 to return: [-1] ";
-static char *log_level_choices[] = { "ignore", "report", "ask", "fatal", "no change" };
-static int log_level_n_choices_normal = 4;
-
-void bx_log_options (int individual)
-{
-  if (individual) {
-    int done = 0;
-    while (!done) {
-      bx_print_log_action_table ();
-      Bit32s id, level, action;
-      Bit32s maxid = SIM->get_n_log_modules ();
-      if (ask_int (log_options_prompt1, -1, maxid-1, -1, &id) < 0)
-       return;
-      if (id < 0) return;
-      fprintf (stderr, "Editing log options for the device %s\n", SIM->get_prefix (id));
-      for (level=0; level<SIM->get_max_log_level (); level++) {
-       char prompt[1024];
-       int default_action = SIM->get_log_action (id, level);
-       sprintf (prompt, "Enter action for %s event: [%s] ", SIM->get_log_level_name (level), SIM->get_action_name(default_action));
-       // don't show the no change choice (choices=3)
-       if (ask_menu (prompt, log_level_n_choices_normal, log_level_choices, default_action, &action)<0)
-         return;
-       SIM->set_log_action (id, level, action);
-      }
-    }
-  } else {
-    // provide an easy way to set log options for all devices at once
-    bx_print_log_action_table ();
-    for (int level=0; level<SIM->get_max_log_level (); level++) {
-      char prompt[1024];
-      int action, default_action = 3;  // default to no change
-      sprintf (prompt, "Enter action for %s event on all devices: [no change] ", SIM->get_log_level_name (level));
-       // do show the no change choice (choices=4)
-      if (ask_menu (prompt, log_level_n_choices_normal+1, log_level_choices, default_action, &action)<0)
-       return;
-      if (action < 3) {
-       SIM->set_default_log_action (level, action);
-       SIM->set_log_action (-1, level, action);
-      }
-    }
-  }
-}
-
-int bx_read_rc (char *rc)
-{
-  if (rc && SIM->read_rc (rc) >= 0) return 0;
-  char oldrc[CI_PATH_LENGTH];
-  if (SIM->get_default_rc (oldrc, CI_PATH_LENGTH) < 0)
-    strcpy (oldrc, "none");
-  char newrc[CI_PATH_LENGTH];
-  while (1) {
-    if (ask_string ("\nWhat is the configuration file name?\nTo cancel, type 'none'. [%s] ", oldrc, newrc) < 0) return -1;
-    if (!strcmp (newrc, "none")) return -1;
-    if (SIM->read_rc (newrc) >= 0) return 0;
-    fprintf (stderr, "The file '%s' could not be found.\n", newrc);
-  }
-}
-
-int bx_write_rc (char *rc)
-{
-  char oldrc[CI_PATH_LENGTH], newrc[CI_PATH_LENGTH];
-  if (rc == NULL) {
-    if (SIM->get_default_rc (oldrc, CI_PATH_LENGTH) < 0)
-      strcpy (oldrc, "none");
-  } else {
-    strncpy (oldrc, rc, CI_PATH_LENGTH);
-  }
-  while (1) {
-    if (ask_string ("Save configuration to what file?  To cancel, type 'none'.\n[%s] ", oldrc, newrc) < 0) return -1;
-    if (!strcmp (newrc, "none")) return 0;
-    // try with overwrite off first
-    int status = SIM->write_rc (newrc, 0);
-    if (status >= 0) {
-      fprintf (stderr, "Wrote configuration to '%s'.\n", newrc);
-      return 0;
-    } else if (status == -2) {
-      // return code -2 indicates the file already exists, and overwrite
-      // confirmation is required.
-      Bit32u overwrite = 0;
-      char prompt[256];
-      sprintf (prompt, "Configuration file '%s' already exists.  Overwrite it? [no] ", newrc);
-      if (ask_yn (prompt, 0, &overwrite) < 0) return -1;
-      if (!overwrite) continue;  // if "no", start loop over, asking for a different file
-      // they confirmed, so try again with overwrite bit set
-      if (SIM->write_rc (newrc, 1) >= 0) {
-       fprintf (stderr, "Overwriting existing configuration '%s'.\n", newrc);
-       return 0;
-      } else {
-       fprintf (stderr, "Write failed to '%s'.\n", newrc);
-      }
-    }
-  }
-}
-
-char *log_action_ask_choices[] = { "cont", "alwayscont", "die", "abort", "debug" };
-int log_action_n_choices = 4 + (BX_DEBUGGER?1:0);
-
-BxEvent *
-config_interface_notify_callback (void *unused, BxEvent *event)
-{
-#ifdef WIN32
-  int opts;
-  bx_param_c *param;
-  bx_param_string_c *sparam;
-#endif
-  event->retcode = -1;
-  switch (event->type)
-  {
-    case BX_SYNC_EVT_TICK:
-      event->retcode = 0;
-      return event;
-    case BX_SYNC_EVT_ASK_PARAM:
-#ifdef WIN32
-      param = event->u.param.param;
-      if (param->get_type() == BXT_PARAM_STRING) {
-        sparam = (bx_param_string_c *)param;
-        opts = sparam->get_options()->get();
-        if (opts & sparam->IS_FILENAME) {
-          if (param->get_id() == BXP_NULL) {
-            event->retcode = AskFilename(GetBochsWindow(), (bx_param_filename_c *)sparam);
-          } else {
-            event->retcode = FloppyDialog((bx_param_filename_c *)sparam);
-          }
-          return event;
-        } else {
-          event->retcode = AskString(sparam);
-          return event;
-        }
-      }
-#endif
-      event->u.param.param->text_ask (stdin, stderr);
-      return event;
-    case BX_SYNC_EVT_LOG_ASK:
-    {
-#ifdef WIN32
-      LogAskDialog(event);
-#else
-      int level = event->u.logmsg.level;
-      fprintf (stderr, "\a========================================================================\n");
-      fprintf (stderr, "Event type: %s\n", SIM->get_log_level_name (level));
-      fprintf (stderr, "Device: %s\n", event->u.logmsg.prefix);
-      fprintf (stderr, "Message: %s\n\n", event->u.logmsg.msg);
-      fprintf (stderr, "A %s has occurred.  Do you want to:\n", SIM->get_log_level_name (level));
-      fprintf (stderr, "  cont       - continue execution\n");
-      fprintf (stderr, "  alwayscont - continue execution, and don't ask again.\n");
-      fprintf (stderr, "               This affects only %s events from device %s\n", SIM->get_log_level_name (level), event->u.logmsg.prefix);
-      fprintf (stderr, "  die        - stop execution now\n");
-      fprintf (stderr, "  abort      - dump core %s\n", 
-         BX_HAVE_ABORT ? "" : "(Disabled)");
-#if BX_DEBUGGER
-      fprintf (stderr, "  debug      - continue and return to bochs debugger\n");
-#endif
-      int choice;
-ask:
-      if (ask_menu ("Choose one of the actions above: [%s] ", 
-           log_action_n_choices, log_action_ask_choices, 2, &choice) < 0) 
-       event->retcode = -1;
-      // return 0 for continue, 1 for alwayscontinue, 2 for die, 3 for debug.
-      if (!BX_HAVE_ABORT && choice==BX_LOG_ASK_CHOICE_DUMP_CORE) goto ask;
-      fflush(stdout);
-      fflush(stderr);
-      event->retcode = choice;
-#endif
-    }
-    return event;
-  case BX_ASYNC_EVT_REFRESH:
-  case BX_ASYNC_EVT_DBG_MSG:
-    // The text mode interface does not use these events, so just ignore
-    // them.
-    return event;
-  default:
-    fprintf (stderr, "Control panel: notify callback called with event type %04x\n", event->type);
-    return event;
-  }
-  assert (0); // switch statement should return
-}
-
-void bx_config_interface_init () {
-  //fprintf (stderr, "bx_config_interface_init()\n");
-  SIM->set_notify_callback (config_interface_notify_callback, NULL);
-}
-
-/////////////////////////////////////////////////////////////////////
-// implement the text_* methods for bx_param types.
-
-void
-bx_param_num_c::text_print (FILE *fp)
-{
-  //fprintf (fp, "number parameter, id=%u, name=%s\n", get_id (), get_name ());
-  //fprintf (fp, "value=%u\n", get ());
-  if (get_format ()) {
-    fprintf (fp, get_format (), get ());
-  } else {
-    char *format = "%s: %d"; 
-    assert (base==10 || base==16);
-    if (base==16) format = "%s: 0x%x";
-    fprintf (fp, format, get_name (), get ());
-  }
-}
-
-void
-bx_param_bool_c::text_print (FILE *fp)
-{
-  if (get_format ()) {
-    fprintf (fp, get_format (), get () ? "yes" : "no");
-  } else {
-    char *format = "%s: %s"; 
-    fprintf (fp, format, get_name (), get () ? "yes" : "no");
-  }
-}
-
-void
-bx_param_enum_c::text_print (FILE *fp)
-{
-  int n = get ();
-  assert (n >= min && n <= max);
-  char *choice = choices[n - min];
-  if (get_format ()) {
-    fprintf (fp, get_format (), choice);
-  } else {
-    char *format = "%s: %s"; 
-    fprintf (fp, format, get_name (), choice);
-  }
-}
-
-void
-bx_param_string_c::text_print (FILE *fp)
-{
-  char *value = getptr ();
-  int opts = options->get ();
-  if (opts & RAW_BYTES) {
-    char buffer[1024];
-    buffer[0] = 0;
-    char sep_string[2];
-    sep_string[0] = separator;
-    sep_string[1] = 0;
-    for (int i=0; i<maxsize; i++) {
-      char eachbyte[16];
-      sprintf (eachbyte, "%s%02x", (i>0)?sep_string : "", (unsigned int)0xff&val[i]);
-      strncat (buffer, eachbyte, sizeof(buffer));
-    }
-    if (strlen (buffer) > sizeof(buffer)-4) {
-      assert (0); // raw byte print buffer is probably overflowing. increase the max or make it dynamic
-    }
-    value = buffer;
-  }
-  if (get_format ()) {
-    fprintf (fp, get_format (), value);
-  } else {
-    fprintf (fp, "%s: %s", get_name (), value);
-  }
-}
-
-void
-bx_list_c::text_print (FILE *fp)
-{
-  //fprintf (fp, "This is a list.\n");
-  //fprintf (fp, "title=%s\n", title->getptr ());
-  fprintf (fp, "%s: ", get_name ());
-  /*
-  fprintf (fp, "options=%s%s%s\n", 
-      (options->get () == 0) ? "none" : "",
-      (options->get () & SHOW_PARENT) ? "SHOW_PARENT " : "",
-      (options->get () & SERIES_ASK) ? "SERIES_ASK " : "");
-      */
-  for (int i=0; i<size; i++) {
-    //fprintf (fp, "param[%d] = %p\n", i, list[i]);
-    assert (list[i] != NULL);
-    if (list[i]->get_enabled ()) {
-      if ((i>0) && (options->get () & SERIES_ASK))
-        fprintf (fp, ", ");
-      list[i]->text_print (fp);
-      if (!(options->get () & SERIES_ASK))
-        fprintf (fp, "\n");
-    }
-  }
-}
-
-int 
-bx_param_num_c::text_ask (FILE *fpin, FILE *fpout)
-{
-  fprintf (fpout, "\n");
-  int status;
-  char *prompt = get_ask_format ();
-  if (prompt == NULL) {
-    // default prompt, if they didn't set an ask format string
-    text_print (fpout);
-    fprintf (fpout, "\n");
-    prompt = "Enter new value: [%d] ";
-    if (base==16)
-      prompt = "Enter new value in hex: [%x] ";
-  }
-  Bit32u n = get ();
-  status = ask_uint (prompt, min, max, n, &n, base);
-  if (status < 0) return status;
-  set (n);
-  return 0;
-}
-
-int 
-bx_param_bool_c::text_ask (FILE *fpin, FILE *fpout)
-{
-  fprintf (fpout, "\n");
-  int status;
-  char *prompt = get_ask_format ();
-  char buffer[512];
-  if (prompt == NULL) {
-    // default prompt, if they didn't set an ask format string
-    sprintf (buffer, "%s? [%%s] ", get_name ());
-    prompt = buffer;
-  }
-  Bit32u n = get ();
-  status = ask_yn (prompt, n, &n);
-  if (status < 0) return status;
-  set (n);
-  return 0;
-}
-
-int 
-bx_param_enum_c::text_ask (FILE *fpin, FILE *fpout)
-{
-  fprintf (fpout, "\n");
-  char *prompt = get_ask_format ();
-  if (prompt == NULL) {
-    // default prompt, if they didn't set an ask format string
-    fprintf (fpout, "%s = ", get_name ());
-    text_print (fpout);
-    fprintf (fpout, "\n");
-    prompt = "Enter new value: [%s] ";
-  }
-  Bit32s n = (Bit32s)(get () - min);
-  int status = ask_menu (prompt, (max-min+1), choices, n, &n);
-  if (status < 0) return status;
-  n += (Bit32s)min;
-  set (n);
-  return 0;
-}
-
-int parse_raw_bytes (char *dest, char *src, int destsize, char separator)
-{
-  //printf ("parsing src='%s'\n", src);
-  int i;
-  unsigned int n;
-  for (i=0; i<destsize; i++) 
-    dest[i] = 0;
-  for (i=0; i<destsize; i++) {
-    while (*src == separator)
-      src++;
-    if (*src == 0) break;
-    // try to read a byte of hex
-    if (sscanf (src, "%02x", &n) == 1) {
-      //printf ("found a byte %02x\n", n);
-      dest[i] = n;
-      src+=2;
-    } else {
-      return -1;
-    }
-  }
-  return 0;
-}
-
-int 
-bx_param_string_c::text_ask (FILE *fpin, FILE *fpout)
-{
-  fprintf (fpout, "\n");
-  int status;
-  char *prompt = get_ask_format ();
-  if (prompt == NULL) {
-    // default prompt, if they didn't set an ask format string
-    text_print (fpout);
-    fprintf (fpout, "\n");
-    prompt = "Enter a new value, or press return for no change.\n";
-  }
-  while (1) {
-    char buffer[1024];
-    status = ask_string (prompt, getptr(), buffer);
-    if (status < 0) return status;
-    int opts = options->get ();
-    char buffer2[1024];
-    strcpy (buffer2, buffer);
-    if (status == 1 && opts & RAW_BYTES) {
-      // copy raw hex into buffer
-      status = parse_raw_bytes (buffer, buffer2, maxsize, separator);
-      if (status < 0) {
-       fprintf (fpout, "Illegal raw byte format.  I expected something like 3A%c03%c12%c...\n", separator, separator, separator);
-       continue;
-      }
-    }
-    if (!equals (buffer)) 
-      set (buffer);
-    return 0;
-  }
-}
-
-int
-bx_list_c::text_ask (FILE *fpin, FILE *fpout)
-{
-  char *my_title = title->getptr ();
-  fprintf (fpout, "\n");
-  int i, imax = strlen (my_title);
-  for (i=0; i<imax; i++) fprintf (fpout, "-");
-  fprintf (fpout, "\n%s\n", my_title);
-  for (i=0; i<imax; i++) fprintf (fpout, "-");
-  fprintf (fpout, "\n"); //fprintf (fp, "options=%s\n", options->get ());
-  if (options->get () & SERIES_ASK) {
-    for (int i=0; i<size; i++) {
-      if (list[i]->get_enabled ())
-        list[i]->text_ask (fpin, fpout);
-    }
-  } else {
-    if (options->get () & SHOW_PARENT)
-      fprintf (fpout, "0. Return to previous menu\n");
-    for (int i=0; i<size; i++) {
-      assert (list[i] != NULL);
-      fprintf (fpout, "%d. ", i+1);
-      if (list[i]->get_enabled ()) {
-        list[i]->text_print (fpout);
-       fprintf (fpout, "\n");
-      } else
-       fprintf (fpout, "(disabled)\n");
-    }
-    fprintf (fpout, "\n");
-    Bit32u n = choice->get ();
-    int min = (options->get () & SHOW_PARENT) ? 0 : 1;
-    int max = size;
-    int status = ask_uint ("Please choose one: [%d] ", min, max, n, &n, 10);
-    if (status < 0) return status;
-    choice->set (n);
-  }
-  return 0;
-}
-
-static int ci_callback (void *userdata, ci_command_t command)
-{
-  switch (command)
-  {
-    case CI_START:
-      //fprintf (stderr, "textconfig.cc: start\n");
-      bx_config_interface_init ();
-      if (SIM->get_param_enum(BXP_BOCHS_START)->get () == BX_QUICK_START)
-       bx_config_interface (BX_CI_START_SIMULATION);
-      else {
-        if (!SIM->test_for_text_console ())
-         return CI_ERR_NO_TEXT_CONSOLE;
-        bx_config_interface (BX_CI_START_MENU);
-      }
-      break;
-    case CI_RUNTIME_CONFIG:
-      bx_config_interface (BX_CI_RUNTIME);
-      break;
-    case CI_SHUTDOWN:
-      //fprintf (stderr, "textconfig.cc: shutdown\n");
-      break;
-  }
-  return 0;
-}
-
-// if I can make things compile without this module linked in, then
-// this file can become a plugin too.
-int init_text_config_interface ()
-{
-  //fprintf (stderr, "plugin_init for textconfig.cc\n");
-  SIM->register_configuration_interface ("textconfig", ci_callback, NULL);
-  return 0;  // success
-}
diff --git a/tools/ioemu/gui/textconfig.h b/tools/ioemu/gui/textconfig.h
deleted file mode 100644 (file)
index 01687ca..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: textconfig.h,v 1.1 2002/10/29 20:16:04 bdenney Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-enum {
-  BX_CI_INIT,
-  BX_CI_START_MENU,
-  BX_CI_START_OPTS,
-  BX_CI_START_OPTS_MEM,
-  BX_CI_START_OPTS_INTERFACE,
-  BX_CI_START_OPTS_DISK,
-  BX_CI_START_OPTS_SOUND,
-  BX_CI_START_OPTS_MISC,
-  BX_CI_START_SIMULATION,
-  BX_CI_RUNTIME,
-  BX_CI_N_MENUS
-};
-
-int init_text_config_interface ();
diff --git a/tools/ioemu/gui/x.cc b/tools/ioemu/gui/x.cc
deleted file mode 100644 (file)
index 5d1cae9..0000000
+++ /dev/null
@@ -1,1848 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: x.cc,v 1.76 2003/08/11 19:27:57 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-#define XK_PUBLISHING
-#define XK_TECHNICAL
-
-// Define BX_PLUGGABLE in files that can be compiled into plugins.  For
-// platforms that require a special tag on exported symbols, BX_PLUGGABLE 
-// is used to know when we are exporting symbols and when we are importing.
-#define BX_PLUGGABLE
-
-#include "bochs.h"
-#if BX_WITH_X11
-
-extern "C" {
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/Xos.h>
-#include <X11/Xatom.h>
-#include <X11/keysym.h>
-#if BX_HAVE_XPM_H
-#include <X11/xpm.h>
-#endif
-}
-
-#if BX_HAVE_XPM_H
-#include "icon_bochs.xpm"
-#else
-#include "icon_bochs.h"
-#endif
-
-#include "font/vga.bitmap.h"
-
-class bx_x_gui_c : public bx_gui_c {
-public:
-  bx_x_gui_c (void);
-  DECLARE_GUI_VIRTUAL_METHODS()
-#if BX_USE_IDLE_HACK
-  virtual void sim_is_idle(void);
-#endif
-};
-
-// declare one instance of the gui object and call macro to insert the
-// plugin code
-static bx_x_gui_c *theGui = NULL;
-IMPLEMENT_GUI_PLUGIN_CODE(x)
-
-#define LOG_THIS theGui->
-
-#define MAX_MAPPED_STRING_LENGTH 10
-
-/* These are used as arguments to nearly every Xlib routine, so it saves
- * routine arguments to declare them global.  If there were
- * additional source files, they would be declared extern there. */
-Display *bx_x_display;
-int bx_x_screen_num;
-static Colormap default_cmap;
-static unsigned long white_pixel=0, black_pixel=0;
-
-static char *progname; /* name this program was invoked by */
-
-static unsigned int text_rows=25, text_cols=80;
-static Bit8u h_panning = 0, v_panning = 0;
-
-static Window win;
-static GC gc, gc_inv, gc_headerbar, gc_headerbar_inv;
-static unsigned font_width, font_height;
-static unsigned dimension_x=0, dimension_y=0;
-static unsigned vga_bpp=8;
-
-static XImage *ximage = NULL;
-static unsigned imDepth, imWide, imBPP;
-
-// current cursor coordinates
-static int prev_x=-1, prev_y=-1;
-static int current_x=-1, current_y=-1;
-static unsigned mouse_button_state = 0;
-
-static unsigned prev_cursor_x=0;
-static unsigned prev_cursor_y=0;
-
-static int warp_home_x = 200;
-static int warp_home_y = 200;
-static int mouse_enable_x = 0;
-static int mouse_enable_y = 0;
-static int warp_dx = 0;
-static int warp_dy = 0;
-
-static void warp_cursor(int dx, int dy);
-static void disable_cursor();
-static void enable_cursor();
-
-static Bit32u convertStringToXKeysym (const char *string);
-
-static bx_bool x_init_done = false;
-
-static Pixmap vgafont[256];
-
-struct {
-  Pixmap bmap;
-  unsigned xdim;
-  unsigned ydim;
-  } bx_bitmaps[BX_MAX_PIXMAPS];
-unsigned bx_bitmap_entries = 0;
-
-static struct {
-  Pixmap   bitmap;
-  unsigned xdim;
-  unsigned ydim;
-  unsigned xorigin;
-  unsigned yorigin;
-  unsigned alignment;
-  void (*f)(void);
-  } bx_headerbar_entry[BX_MAX_HEADERBAR_ENTRIES];
-static unsigned bx_headerbar_y = 0;
-static unsigned bx_headerbar_entries = 0;
-static unsigned bx_bitmap_left_xorigin = 0;  // pixels from left
-static unsigned bx_bitmap_right_xorigin = 0; // pixels from right
-
-static void headerbar_click(int x, int y);
-static void send_keyboard_mouse_status(void);
-
-
-
-
-Bit32u ascii_to_key_event[0x5f] = {
-  //  !"#$%&'
-  BX_KEY_SPACE,
-  BX_KEY_1,
-  BX_KEY_SINGLE_QUOTE,
-  BX_KEY_3,
-  BX_KEY_4,
-  BX_KEY_5,
-  BX_KEY_7,
-  BX_KEY_SINGLE_QUOTE,
-
-  // ()*+,-./
-  BX_KEY_9,
-  BX_KEY_0,
-  BX_KEY_8,
-  BX_KEY_EQUALS,
-  BX_KEY_COMMA,
-  BX_KEY_MINUS,
-  BX_KEY_PERIOD,
-  BX_KEY_SLASH,
-
-  // 01234567
-  BX_KEY_0,
-  BX_KEY_1,
-  BX_KEY_2,
-  BX_KEY_3,
-  BX_KEY_4,
-  BX_KEY_5,
-  BX_KEY_6,
-  BX_KEY_7,
-
-  // 89:;<=>?
-  BX_KEY_8,
-  BX_KEY_9,
-  BX_KEY_SEMICOLON,
-  BX_KEY_SEMICOLON,
-  BX_KEY_COMMA,
-  BX_KEY_EQUALS,
-  BX_KEY_PERIOD,
-  BX_KEY_SLASH,
-
-  // @ABCDEFG
-  BX_KEY_2,
-  BX_KEY_A,
-  BX_KEY_B,
-  BX_KEY_C,
-  BX_KEY_D,
-  BX_KEY_E,
-  BX_KEY_F,
-  BX_KEY_G,
-
-
-  // HIJKLMNO
-  BX_KEY_H,
-  BX_KEY_I,
-  BX_KEY_J,
-  BX_KEY_K,
-  BX_KEY_L,
-  BX_KEY_M,
-  BX_KEY_N,
-  BX_KEY_O,
-
-
-  // PQRSTUVW
-  BX_KEY_P,
-  BX_KEY_Q,
-  BX_KEY_R,
-  BX_KEY_S,
-  BX_KEY_T,
-  BX_KEY_U,
-  BX_KEY_V,
-  BX_KEY_W,
-
-  // XYZ[\]^_
-  BX_KEY_X,
-  BX_KEY_Y,
-  BX_KEY_Z,
-  BX_KEY_LEFT_BRACKET,
-  BX_KEY_BACKSLASH,
-  BX_KEY_RIGHT_BRACKET,
-  BX_KEY_6,
-  BX_KEY_MINUS,
-
-  // `abcdefg
-  BX_KEY_GRAVE,
-  BX_KEY_A,
-  BX_KEY_B,
-  BX_KEY_C,
-  BX_KEY_D,
-  BX_KEY_E,
-  BX_KEY_F,
-  BX_KEY_G,
-
-  // hijklmno
-  BX_KEY_H,
-  BX_KEY_I,
-  BX_KEY_J,
-  BX_KEY_K,
-  BX_KEY_L,
-  BX_KEY_M,
-  BX_KEY_N,
-  BX_KEY_O,
-
-  // pqrstuvw
-  BX_KEY_P,
-  BX_KEY_Q,
-  BX_KEY_R,
-  BX_KEY_S,
-  BX_KEY_T,
-  BX_KEY_U,
-  BX_KEY_V,
-  BX_KEY_W,
-
-  // xyz{|}~
-  BX_KEY_X,
-  BX_KEY_Y,
-  BX_KEY_Z,
-  BX_KEY_LEFT_BRACKET,
-  BX_KEY_BACKSLASH,
-  BX_KEY_RIGHT_BRACKET,
-  BX_KEY_GRAVE
-  };
-
-extern Bit8u graphics_snapshot[32 * 1024];
-
-
-static void create_internal_vga_font(void);
-static void xkeypress(KeySym keysym, int press_release);
-// extern "C" void select_visual(void);
-
-#define ROUNDUP(nbytes, pad) ((((nbytes) + ((pad)-1)) / (pad)) * ((pad)>>3))
-
-
-#define MAX_VGA_COLORS 256
-
-unsigned long col_vals[MAX_VGA_COLORS]; // 256 VGA colors
-unsigned curr_foreground, curr_background;
-
-static unsigned x_tilesize, y_tilesize;
-
-
-// Try to allocate NCOLORS at once in the colormap provided.  If it can
-// be done, return true.  If not, return false.  (In either case, free
-// up the color cells so that we don't add to the problem!)  This is used
-// to determine whether Bochs should use a private colormap even when the
-// user did not specify it.
-static bx_bool
-test_alloc_colors (Colormap cmap, Bit32u n_tries) {
-  XColor color;
-  unsigned long pixel[MAX_VGA_COLORS];
-  bx_bool pixel_valid[MAX_VGA_COLORS];
-  Bit32u n_allocated = 0;
-  Bit32u i;
-  color.flags = DoRed | DoGreen | DoBlue;
-  for (i=0; i<n_tries; i++) {
-    // choose wierd color values that are unlikely to already be in the 
-    // colormap.
-    color.red   = ((i+41)%MAX_VGA_COLORS) << 8;
-    color.green = ((i+42)%MAX_VGA_COLORS) << 8;
-    color.blue  = ((i+43)%MAX_VGA_COLORS) << 8;
-    pixel_valid[i] = false;
-    if (XAllocColor (bx_x_display, cmap, &color)) {
-      pixel[i] = color.pixel;
-      pixel_valid[i] = true;
-      n_allocated++;
-    }
-  }
-  BX_INFO (("test_alloc_colors: %d colors available out of %d colors tried", n_allocated, n_tries));
-  // now free them all
-  for (i=0; i<n_tries; i++) {
-    if (pixel_valid[i]) XFreeColors (bx_x_display, cmap, &pixel[i], 1, 0);
-  }
-  return (n_allocated == n_tries);
-}
-
-bx_x_gui_c::bx_x_gui_c () {
-}
-
-  void
-bx_x_gui_c::specific_init(int argc, char **argv, unsigned tilewidth, unsigned tileheight,
-                     unsigned headerbar_y)
-{
-  unsigned i;
-  int x, y;   /* window position */
-  unsigned int border_width = 4;  /* four pixels */
-#if BX_CPU_LEVEL < 2
-  char *window_name = "Bochs 8086 emulator, http://bochs.sourceforge.net/";
-#elif BX_CPU_LEVEL == 2
-  char *window_name = "Bochs 80286 emulator, http://bochs.sourceforge.net/";
-#elif BX_CPU_LEVEL == 3
-  char *window_name = "Bochs 80386 emulator, http://bochs.sourceforge.net/";
-#elif BX_CPU_LEVEL == 4
-  char *window_name = "Bochs 80486 emulator, http://bochs.sourceforge.net/";
-#else
-  char *window_name = "VTXen";
-#endif
-  char *icon_name = "Bochs";
-  Pixmap icon_pixmap;
-#if BX_HAVE_XPM_H
-  Pixmap icon_mask;
-#endif
-  XSizeHints size_hints;
-  char *display_name = NULL;
-  /* create GC for text and drawing */
-  unsigned long valuemask = 0; /* ignore XGCvalues and use defaults */
-  XGCValues values;
-  Visual  *default_visual;
-  int      default_depth;
-  XEvent report;
-  XSetWindowAttributes win_attr;
-  unsigned long plane_masks_return[1];
-  XColor color;
-
-  put("XGUI");
-
-  x_tilesize = tilewidth;
-  y_tilesize = tileheight;
-  bx_headerbar_y = headerbar_y;
-
-  progname = argv[0];
-
-  /* connect to X server */
-  if ( (bx_x_display=XOpenDisplay(display_name)) == NULL )
-  {
-    BX_PANIC(("%s: cannot connect to X server %s",
-        progname, XDisplayName(display_name)));
-  }
-
-  /* get screen size from display structure macro */
-  bx_x_screen_num = DefaultScreen(bx_x_display);
-
-  /* Note that in a real application, x and y would default to 0
-   * but would be settable from the command line or resource database.
-   */
-  x = y = 0;
-
-
-  // Temporary values so we can create the window
-  font_width = 8;
-  font_height = 16;
-
-  dimension_x = text_cols * font_width;
-  dimension_y = text_rows * font_height + headerbar_y;
-
-  /* create opaque window */
-  win = XCreateSimpleWindow(bx_x_display, RootWindow(bx_x_display,bx_x_screen_num),
-    x, y,
-    dimension_x,
-    dimension_y,
-    border_width,
-    BlackPixel(bx_x_display, bx_x_screen_num),
-    BlackPixel(bx_x_display, bx_x_screen_num));
-
-  // (attempt to) enable backing store
-  win_attr.save_under=1;
-  win_attr.backing_store=Always;
-  XChangeWindowAttributes(bx_x_display,win,CWSaveUnder|CWBackingStore,&win_attr);
-
-  default_depth  = DefaultDepth(bx_x_display, bx_x_screen_num);
-  default_visual = DefaultVisual(bx_x_display, bx_x_screen_num);
-
-  if (!bx_options.Oprivate_colormap->get ()) {
-    default_cmap = DefaultColormap(bx_x_display, bx_x_screen_num);
-    // try to use default colormap.  If not enough colors are available,
-    // then switch to private colormap despite the user setting.  There
-    // are too many cases when no colors are available and Bochs simply
-    // draws everything in black on black.
-    if (!test_alloc_colors (default_cmap, 16)) {
-      BX_ERROR (("I can't even allocate 16 colors!  Switching to a private colormap"));
-      bx_options.Oprivate_colormap->set (1);
-    }
-    col_vals[0]  = BlackPixel(bx_x_display, bx_x_screen_num);
-    col_vals[15] = WhitePixel(bx_x_display, bx_x_screen_num);
-    for (i = 1; i < MAX_VGA_COLORS; i++) {
-      if (i==15) continue;
-      col_vals[i] = col_vals[0];
-    }
-  }
-
-  if (bx_options.Oprivate_colormap->get ()) {
-    default_cmap = XCreateColormap(bx_x_display, DefaultRootWindow(bx_x_display),
-                                   default_visual, AllocNone);
-    if (XAllocColorCells(bx_x_display, default_cmap, False,
-                         plane_masks_return, 0, col_vals, MAX_VGA_COLORS) == 0) {
-      BX_PANIC(("XAllocColorCells returns error. Maybe your screen does not support a private colormap?"));
-      }
-
-    win_attr.colormap = default_cmap;
-    XChangeWindowAttributes(bx_x_display, win, CWColormap, &win_attr);
-
-    color.flags = DoRed | DoGreen | DoBlue;
-
-    for (i=0; i < MAX_VGA_COLORS; i++) {
-      color.pixel = i;
-      if (i==15) {
-        color.red   = 0xffff;
-        color.green = 0xffff;
-        color.blue  = 0xffff;
-        }
-      else {
-        color.red   = 0;
-        color.green = 0;
-        color.blue  = 0;
-        }
-      XStoreColor(bx_x_display, default_cmap, &color);
-      }
-    }
-
-  // convenience variables which hold the black & white color indeces
-  black_pixel = col_vals[0];
-  white_pixel = col_vals[15];
-
-  BX_INFO(("font %u wide x %u high, display depth = %d",
-               (unsigned) font_width, (unsigned) font_height, default_depth));
-
-  //select_visual();
-
-
-  /* Get available icon sizes from Window manager */
-
-#if BX_HAVE_XPM_H
-  /* Create pixmap from XPM for icon */
-  XCreatePixmapFromData(bx_x_display, win, icon_bochs_xpm, &icon_pixmap, &icon_mask, NULL);
-#else
-  /* Create pixmap of depth 1 (bitmap) for icon */
-  icon_pixmap = XCreateBitmapFromData(bx_x_display, win,
-    (char *) bochs_icon_bits, bochs_icon_width, bochs_icon_height);
-#endif
-
-  /* Set size hints for window manager.  The window manager may
-   * override these settings.  Note that in a real
-   * application if size or position were set by the user
-   * the flags would be UPosition and USize, and these would
-   * override the window manager's preferences for this window. */
-  /* x, y, width, and height hints are now taken from
-   * the actual settings of the window when mapped. Note
-   * that PPosition and PSize must be specified anyway. */
-
-  size_hints.flags = PPosition | PSize | PMinSize | PMaxSize;
-  size_hints.max_width = size_hints.min_width = dimension_x;
-  size_hints.max_height = size_hints.min_height = dimension_y;
-
-  {
-  XWMHints wm_hints;
-  XClassHint class_hints;
-
-  /* format of the window name and icon name
-   * arguments has changed in R4 */
-  XTextProperty windowName, iconName;
-
-  /* These calls store window_name and icon_name into
-   * XTextProperty structures and set their other
-   * fields properly. */
-  if (XStringListToTextProperty(&window_name, 1, &windowName) == 0) {
-    BX_PANIC(("%s: structure allocation for windowName failed.",
-        progname));
-  }
-
-  if (XStringListToTextProperty(&icon_name, 1, &iconName) == 0) {
-    BX_PANIC(("%s: structure allocation for iconName failed.",
-        progname));
-  }
-
-  wm_hints.initial_state = NormalState;
-  wm_hints.input = True;
-  wm_hints.icon_pixmap = icon_pixmap;
-#if BX_HAVE_XPM_H
-  wm_hints.icon_mask = icon_mask;
-  wm_hints.flags = StateHint | IconPixmapHint | IconMaskHint | InputHint;
-#else
-  wm_hints.flags = StateHint | IconPixmapHint | InputHint;
-#endif
-  class_hints.res_name = progname;
-  class_hints.res_class = "Bochs";
-
-  XSetWMProperties(bx_x_display, win, &windowName, &iconName,
-      argv, argc, &size_hints, &wm_hints,
-      &class_hints);
-  }
-
-  /* Select event types wanted */
-  XSelectInput(bx_x_display, win, ExposureMask | KeyPressMask | KeyReleaseMask |
-      ButtonPressMask | ButtonReleaseMask | StructureNotifyMask | PointerMotionMask |
-      EnterWindowMask | LeaveWindowMask );
-
-
-  /* Create default Graphics Context */
-  gc               = XCreateGC(bx_x_display, win, valuemask, &values);
-  gc_inv           = XCreateGC(bx_x_display, win, valuemask, &values);
-  gc_headerbar     = XCreateGC(bx_x_display, win, valuemask, &values);
-  gc_headerbar_inv = XCreateGC(bx_x_display, win, valuemask, &values);
-
-  XSetState(bx_x_display, gc, white_pixel, black_pixel, GXcopy,AllPlanes);
-
-  XSetState(bx_x_display, gc_inv, black_pixel, white_pixel, GXinvert,AllPlanes);
-
-  XSetState(bx_x_display, gc_headerbar, black_pixel, white_pixel, GXcopy,AllPlanes);
-
-  XSetState(bx_x_display, gc_headerbar_inv, white_pixel, black_pixel, GXcopy,AllPlanes);
-
-
-  /* Display window */
-  XMapWindow(bx_x_display, win);
-  XSync(bx_x_display, /* no discard */ 0);
-
-  BX_DEBUG(("waiting for MapNotify"));
-  while (1) {
-    XNextEvent(bx_x_display, &report);
-    if (report.type == MapNotify) break;
-    }
-  BX_DEBUG(("MapNotify found."));
-
-  // Create the VGA font
-  create_internal_vga_font();
-
-
-{
-  char *imagedata;
-
-  ximage = XCreateImage(bx_x_display, default_visual,
-             default_depth,          // depth of image (bitplanes)
-             ZPixmap,
-             0,                      // offset
-             NULL,                   // malloc() space after
-             x_tilesize, y_tilesize, // x & y size of image
-             32,                     // # bits of padding
-             0 );                    // bytes_per_line, let X11 calculate
-  if (!ximage)
-    BX_PANIC(("vga: couldn't XCreateImage()"));
-
-  imDepth = default_depth;
-  imWide  = ximage->bytes_per_line;
-  imBPP   = ximage->bits_per_pixel;
-
-  imagedata = (char *) malloc( (size_t) (ximage->bytes_per_line * y_tilesize) );
-  if (!imagedata) BX_PANIC(("imagedata: malloc returned error"));
-
-  ximage->data = imagedata;
-
-  if (imBPP < imDepth) {
-    BX_PANIC(("vga_x: bits_per_pixel < depth ?"));
-    }
-
-  x_init_done = true;
-
-}
-
-  curr_background = 0;
-  XSetBackground(bx_x_display, gc, col_vals[curr_background]);
-  curr_foreground = 1;
-  XSetForeground(bx_x_display, gc, col_vals[curr_foreground]);
-  //XGrabPointer( bx_x_display, win, True, 0, GrabModeAsync, GrabModeAsync,
-  //  win, None, CurrentTime );
-
-
-  XFlush(bx_x_display);
-
-  // loads keymap for x11
-  if(bx_options.keyboard.OuseMapping->get()) {
-    bx_keymap.loadKeymap(convertStringToXKeysym);
-    }
-}
-
-
-// This is called whenever the mouse_enabled parameter changes.  It
-// can change because of a gui event such as clicking on the mouse-enable
-// bitmap or pressing the middle button, or from the configuration interface.
-// In all those cases, setting the parameter value will get you here.
-  void
-bx_x_gui_c::mouse_enabled_changed_specific (bx_bool val)
-{
-  BX_DEBUG (("mouse_enabled=%d, x11 specific code", val?1:0));
-  if (val) {
-    BX_INFO(("[x] Mouse on"));
-    mouse_enable_x = current_x;
-    mouse_enable_y = current_y;
-    disable_cursor();
-    // Move the cursor to a 'safe' place
-    warp_cursor(warp_home_x-current_x, warp_home_y-current_y);
-  } else {
-    BX_INFO(("[x] Mouse off"));
-    enable_cursor();
-    warp_cursor(mouse_enable_x-current_x, mouse_enable_y-current_y);
-  }
-}
-
-  void
-create_internal_vga_font(void)
-{
-  // Default values
-  font_width=8;
-  font_height=16;
-
-  for(int i=0; i<256; i++) {
-    vgafont[i]=XCreateBitmapFromData(bx_x_display, win, (const char*)bx_vgafont[i].data,
-                                     font_width, font_height);
-    if(vgafont[i] == None)
-      BX_PANIC(("Can't create vga font [%d]", i));
-  }
-}
-
-  void
-bx_x_gui_c::handle_events(void)
-{
-  XEvent report;
-  XKeyEvent *key_event;
-  KeySym keysym;
-  XComposeStatus compose;
-  char buffer[MAX_MAPPED_STRING_LENGTH];
-  int bufsize = MAX_MAPPED_STRING_LENGTH;
-  int charcount;
-  bx_bool mouse_update;
-  int y, height;
-
-
-  XPointerMovedEvent *pointer_event;
-  XEnterWindowEvent *enter_event;
-  XLeaveWindowEvent *leave_event;
-  XButtonEvent *button_event;
-  XExposeEvent *expose_event;
-
-
-  //current_x = -1;
-  //current_y = -1;
-  mouse_update = 0;
-
-  while (XPending(bx_x_display) > 0)  {
-    XNextEvent(bx_x_display, &report);
-    switch  (report.type) {
-
-    case Expose:
-      expose_event = &report.xexpose;
-      /* Adjust y, and reduce height if it overlaps headerbar. */
-      y = expose_event->y - BX_HEADER_BAR_Y;
-      height = expose_event->height;
-      if (y < 0) {
-       height += y;
-       y = 0;
-      }
-
-      DEV_vga_redraw_area(
-        (unsigned) expose_event->x,
-        y,
-        (unsigned) expose_event->width,
-        height);
-
-      /* Always draw headerbar, even if not touched by expose event.
-       * As a small optimization, only do it on last contigous expose.
-       */
-      if (expose_event->count == 0) {
-      show_headerbar();
-      }
-      break;
-
-    case ConfigureNotify:
-      BX_DEBUG(("ConfigureNotify Xevent"));
-      /* FIXME: It's not clear why we have to show the headerbar here.
-       * This should be forced by the following expose events.
-       */
-      show_headerbar();
-      break;
-
-    case ButtonPress:
-      button_event = (XButtonEvent *) &report;
-               BX_DEBUG(("xxx: buttonpress"));
-      if (button_event->y < BX_HEADER_BAR_Y) {
-               BX_DEBUG(("xxx:   in headerbar"));
-        if (mouse_update) {
-                 BX_DEBUG(("xxx:   mouse_update=1"));
-          send_keyboard_mouse_status();
-          mouse_update = 0;
-          }
-        prev_x = current_x = -1;
-        prev_y = current_y = -1;
-        headerbar_click(button_event->x, button_event->y);
-        break;
-        }
-      current_x = button_event->x;
-      current_y = button_event->y;
-      mouse_update = 1;
-         BX_DEBUG(("xxx:   x,y=(%d,%d)", current_x, current_y));
-      switch (button_event->button) {
-        case Button1:
-                 BX_DEBUG(("xxx:   button1"));
-          mouse_button_state |= 0x01;
-          send_keyboard_mouse_status();
-          mouse_update = 0;
-          break;
-        case Button2:
-             BX_DEBUG(("XXX:   button2"));
-
-             // (mch) Hack for easier mouse handling (toggle mouse enable)
-             toggle_mouse_enable();
-
-          //mouse_button_state |= ;
-          //send_keyboard_mouse_status();
-          //mouse_update = 0;
-          break;
-        case Button3:
-                 BX_DEBUG(("xxx:   button3"));
-          mouse_button_state |= 0x02;
-          send_keyboard_mouse_status();
-          mouse_update = 0;
-          break;
-        }
-      break;
-
-    case ButtonRelease:
-      button_event = (XButtonEvent *) &report;
-//BX_INFO(("xxx: buttonrelease"));
-      if (button_event->y < BX_HEADER_BAR_Y) {
-//BX_INFO(("xxx:   in headerbar"));
-        if (mouse_update) {
-//BX_INFO(("xxx:   mouse_update=1"));
-          send_keyboard_mouse_status();
-          mouse_update = 0;
-          }
-        prev_x = current_x = -1;
-        prev_y = current_y = -1;
-        // ignore, in headerbar area
-        break;
-        }
-      current_x = button_event->x;
-      current_y = button_event->y;
-      mouse_update = 1;
-//BX_INFO(("xxx:   x,y=(%d,%d)", current_x, current_y));
-      switch (button_event->button) {
-        case Button1:
-//BX_INFO(("xxx:   button1"));
-          mouse_button_state &= ~0x01;
-          send_keyboard_mouse_status();
-          mouse_update = 0;
-          break;
-        case Button2:
-//BX_INFO(("xxx:   button2"));
-          //mouse_button_state &= ~;
-          //send_keyboard_mouse_status();
-          //mouse_update = 0;
-          break;
-        case Button3:
-//BX_INFO(("xxx:   button3"));
-          mouse_button_state &= ~0x02;
-          send_keyboard_mouse_status();
-          mouse_update = 0;
-          break;
-        }
-      break;
-
-    case KeyPress:
-      key_event = (XKeyEvent *) &report;
-      charcount = XLookupString(key_event, buffer, bufsize, &keysym, &compose);
-      xkeypress(keysym, 0);
-      break;
-
-    case KeyRelease:
-      key_event = (XKeyEvent *) &report;
-      charcount = XLookupString(key_event, buffer, bufsize, &keysym, &compose);
-      xkeypress(keysym, 1);
-      break;
-
-    case MotionNotify:
-      pointer_event = (XPointerMovedEvent *) &report;
-      current_x = pointer_event->x;
-      current_y = pointer_event->y;
-      mouse_update = 1;
-//BX_INFO(("xxx: motionNotify x,y=(%d,%d)", current_x, current_y));
-      break;
-
-    case EnterNotify:
-      enter_event = (XEnterWindowEvent *) &report;
-      prev_x = current_x = enter_event->x;
-      prev_y = current_y = enter_event->y;
-//BX_INFO(("xxx: enterNotify x,y=(%d,%d)", current_x, current_y));
-      break;
-
-    case LeaveNotify:
-      leave_event = (XLeaveWindowEvent *) &report;
-      prev_x = current_x = -1;
-      prev_y = current_y = -1;
-//BX_INFO(("xxx: LeaveNotify x,y set to -1"));
-      break;
-
-    case MapNotify:
-      /* screen needs redraw, since X would have tossed previous
-       * requests before window mapped
-       */
-//BX_INFO(("xxx: mapnotify: found"));
-      //retval = 1;
-      break;
-
-    default:
-         // (mch) Ignore...
-         BX_DEBUG(("XXX: default Xevent type"));
-      /* all events selected by StructureNotifyMask are thrown away here,
-       * since nothing is done with them */
-      break;
-    } /* end switch */
-  } /* end while */
-
-  if (mouse_update) {
-    BX_DEBUG(("XXX: bottom, send status"));
-    send_keyboard_mouse_status();
-    }
-}
-
-
-  void
-send_keyboard_mouse_status(void)
-{
-       BX_DEBUG(("XXX: prev=(%d,%d) curr=(%d,%d)",
-                       prev_x, prev_y, current_x, current_y));
-
-  if ( (prev_x!=-1) && (current_x!=-1) && (prev_y!=-1) && (current_y!=-1)) {
-    int dx, dy;
-
-    // (mch) consider warping here
-    dx = current_x - prev_x - warp_dx;
-    dy = -(current_y - prev_y - warp_dy);
-    warp_cursor(warp_home_x-current_x, warp_home_y-current_y);
-
-//BX_INFO(("xxx: MOUSE_MOTION: dx=%d, dy=%d", (int) dx, (int) dy));
-    DEV_mouse_motion (dx, dy, mouse_button_state);
-    //if (warped) {
-    //  prev_x = current_x = -1;
-    //  prev_y = current_y = -1;
-    //  }
-    //else {
-      prev_x = current_x;
-      prev_y = current_y;
-    //  }
-    }
-  else {
-    if ( (current_x!=-1) && (current_y!=-1)) {
-      prev_x = current_x;
-      prev_y = current_y;
-      }
-    else {
-      prev_x = current_x = -1;
-      prev_y = current_y = -1;
-      }
-    }
-}
-
-  void
-bx_x_gui_c::flush(void)
-{
-  if (bx_x_display)
-    XFlush(bx_x_display);
-}
-
-
-  void
-xkeypress(KeySym keysym, int press_release)
-{
-  Bit32u key_event;
-
-  /* Old (no mapping) behavior */
-  if(!bx_options.keyboard.OuseMapping->get()){
-
-    // this depends on the fact that the X11 keysyms which
-    // correspond to the ascii characters space .. tilde
-    // are in consequtive order.
-    if ((keysym >= XK_space) && (keysym <= XK_asciitilde)) {
-      key_event = ascii_to_key_event[keysym - XK_space];
-      }
-    else switch (keysym) {
-      case XK_KP_1:
-#ifdef XK_KP_End
-      case XK_KP_End:
-#endif
-        key_event = BX_KEY_KP_END; break;
-
-      case XK_KP_2:
-#ifdef XK_KP_Down
-      case XK_KP_Down:
-#endif
-        key_event = BX_KEY_KP_DOWN; break;
-
-      case XK_KP_3:
-#ifdef XK_KP_Page_Down
-      case XK_KP_Page_Down:
-#endif
-        key_event = BX_KEY_KP_PAGE_DOWN; break;
-
-      case XK_KP_4:
-#ifdef XK_KP_Left
-      case XK_KP_Left:
-#endif
-        key_event = BX_KEY_KP_LEFT; break;
-
-      case XK_KP_5:
-#ifdef XK_KP_Begin
-      case XK_KP_Begin:
-#endif
-        key_event = BX_KEY_KP_5; break;
-
-      case XK_KP_6:
-#ifdef XK_KP_Right
-      case XK_KP_Right:
-#endif
-        key_event = BX_KEY_KP_RIGHT; break;
-
-      case XK_KP_7:
-#ifdef XK_KP_Home
-      case XK_KP_Home:
-#endif
-        key_event = BX_KEY_KP_HOME; break;
-
-      case XK_KP_8:
-#ifdef XK_KP_Up
-      case XK_KP_Up:
-#endif
-        key_event = BX_KEY_KP_UP; break;
-
-      case XK_KP_9:
-#ifdef XK_KP_Page_Up
-      case XK_KP_Page_Up:
-#endif
-        key_event = BX_KEY_KP_PAGE_UP; break;
-
-      case XK_KP_0:
-#ifdef XK_KP_Insert
-      case XK_KP_Insert:
-#endif
-        key_event = BX_KEY_KP_INSERT; break;
-
-      case XK_KP_Decimal:
-#ifdef XK_KP_Delete
-      case XK_KP_Delete:
-#endif
-        key_event = BX_KEY_KP_DELETE; break;
-
-#ifdef XK_KP_Enter
-      case XK_KP_Enter:    key_event = BX_KEY_KP_ENTER; break;
-#endif
-
-      case XK_KP_Subtract: key_event = BX_KEY_KP_SUBTRACT; break;
-      case XK_KP_Add:      key_event = BX_KEY_KP_ADD; break;
-
-      case XK_KP_Multiply: key_event = BX_KEY_KP_MULTIPLY; break;
-      case XK_KP_Divide:   key_event = BX_KEY_KP_DIVIDE; break;
-
-
-      case XK_Up:          key_event = BX_KEY_UP; break;
-      case XK_Down:        key_event = BX_KEY_DOWN; break;
-      case XK_Left:        key_event = BX_KEY_LEFT; break;
-      case XK_Right:       key_event = BX_KEY_RIGHT; break;
-
-
-      case XK_Delete:      key_event = BX_KEY_DELETE; break;
-      case XK_BackSpace:   key_event = BX_KEY_BACKSPACE; break;
-      case XK_Tab:         key_event = BX_KEY_TAB; break;
-#ifdef XK_ISO_Left_Tab
-      case XK_ISO_Left_Tab: key_event = BX_KEY_TAB; break;
-#endif
-      case XK_Return:      key_event = BX_KEY_ENTER; break;
-      case XK_Escape:      key_event = BX_KEY_ESC; break;
-      case XK_F1:          key_event = BX_KEY_F1; break;
-      case XK_F2:          key_event = BX_KEY_F2; break;
-      case XK_F3:          key_event = BX_KEY_F3; break;
-      case XK_F4:          key_event = BX_KEY_F4; break;
-      case XK_F5:          key_event = BX_KEY_F5; break;
-      case XK_F6:          key_event = BX_KEY_F6; break;
-      case XK_F7:          key_event = BX_KEY_F7; break;
-      case XK_F8:          key_event = BX_KEY_F8; break;
-      case XK_F9:          key_event = BX_KEY_F9; break;
-      case XK_F10:         key_event = BX_KEY_F10; break;
-      case XK_F11:         key_event = BX_KEY_F11; break;
-      case XK_F12:         key_event = BX_KEY_F12; break;
-      case XK_Control_L:   key_event = BX_KEY_CTRL_L; break;
-#ifdef XK_Control_R
-      case XK_Control_R:   key_event = BX_KEY_CTRL_R; break;
-#endif
-      case XK_Shift_L:     key_event = BX_KEY_SHIFT_L; break;
-      case XK_Shift_R:     key_event = BX_KEY_SHIFT_R; break;
-      case XK_Alt_L:       key_event = BX_KEY_ALT_L; break;
-#ifdef XK_Alt_R
-      case XK_Alt_R:       key_event = BX_KEY_ALT_R; break;
-#endif
-      case XK_Caps_Lock:   key_event = BX_KEY_CAPS_LOCK; break;
-      case XK_Num_Lock:    key_event = BX_KEY_NUM_LOCK; break;
-#ifdef XK_Scroll_Lock
-      case XK_Scroll_Lock: key_event = BX_KEY_SCRL_LOCK; break;
-#endif
-#ifdef XK_Print
-      case XK_Print:       key_event = BX_KEY_PRINT; break;
-#endif
-#ifdef XK_Pause
-      case XK_Pause:       key_event = BX_KEY_PAUSE; break;
-#endif
-
-      case XK_Insert:      key_event = BX_KEY_INSERT; break;
-      case XK_Home:        key_event = BX_KEY_HOME; break;
-      case XK_End:         key_event = BX_KEY_END; break;
-      case XK_Page_Up:     key_event = BX_KEY_PAGE_UP; break;
-      case XK_Page_Down:   key_event = BX_KEY_PAGE_DOWN; break;
-
-      default:
-        BX_ERROR(( "xkeypress(): keysym %x unhandled!", (unsigned) keysym ));
-        return;
-      break;
-      }
-    }
-  else {
-   /* use mapping */
-   BXKeyEntry *entry = bx_keymap.findHostKey (keysym);
-   if (!entry) {
-     BX_ERROR(( "xkeypress(): keysym %x unhandled!", (unsigned) keysym ));
-     return;
-   }
-   key_event = entry->baseKey;
- }
-
-  if (press_release)
-    key_event |= BX_KEY_RELEASED;
-
-  DEV_kbd_gen_scancode(key_event);
-}
-
-
-  void
-bx_x_gui_c::clear_screen(void)
-{
-  XClearArea(bx_x_display, win, 0, bx_headerbar_y, dimension_x, dimension_y-bx_headerbar_y, 0);
-}
-
-
-
-
-  void
-bx_x_gui_c::text_update(Bit8u *old_text, Bit8u *new_text,
-                      unsigned long cursor_x, unsigned long cursor_y,
-                      bx_vga_tminfo_t tm_info, unsigned nrows)
-{
-  unsigned char *old_line, *new_line;
-  unsigned char cChar;
-  unsigned int curs, hchars, i, j, offset, rows, x, y, xc, yc, yc2;
-  unsigned new_foreground, new_background;
-  Bit8u cfwidth, cfheight, cfheight2, font_col, font_row, font_row2;
-  bx_bool force_update=0;
-  unsigned char cell[64];
-
-  UNUSED(nrows);
-  if (charmap_updated) {
-    BX_INFO(("charmap update. Font Height is %d",font_height));
-    for (unsigned c = 0; c<256; c++) {
-      if (char_changed[c]) {
-        XFreePixmap(bx_x_display, vgafont[c]);
-        bx_bool gfxchar = tm_info.line_graphics && ((c & 0xE0) == 0xC0);
-        j = 0;
-        memset(cell, 0, sizeof(cell));
-        for(i=0; i<font_height*2; i+=2) {
-          cell[i] |= ((vga_charmap[(c<<5)+j] & 0x01)<<7);
-          cell[i] |= ((vga_charmap[(c<<5)+j] & 0x02)<<5);
-          cell[i] |= ((vga_charmap[(c<<5)+j] & 0x04)<<3);
-          cell[i] |= ((vga_charmap[(c<<5)+j] & 0x08)<<1);
-          cell[i] |= ((vga_charmap[(c<<5)+j] & 0x10)>>1);
-          cell[i] |= ((vga_charmap[(c<<5)+j] & 0x20)>>3);
-          cell[i] |= ((vga_charmap[(c<<5)+j] & 0x40)>>5);
-          cell[i] |= ((vga_charmap[(c<<5)+j] & 0x80)>>7);
-          if (gfxchar) {
-            cell[i+1] = (vga_charmap[(c<<5)+j] & 0x01);
-          }
-          j++;
-        }
-
-        vgafont[c]=XCreateBitmapFromData(bx_x_display, win, 
-                        (const char*)cell,
-                        font_width, font_height);
-            if(vgafont[c] == None)
-              BX_PANIC(("Can't create vga font [%d]", c));
-        char_changed[c] = 0;
-      }
-    }
-    force_update = 1;
-    charmap_updated = 0;
-  }
-
-  if((tm_info.h_panning != h_panning) || (tm_info.v_panning != v_panning)) {
-    force_update = 1;
-    h_panning = tm_info.h_panning;
-    v_panning = tm_info.v_panning;
-  }
-
-  // first invalidate character at previous and new cursor location
-  if ( (prev_cursor_y < text_rows) && (prev_cursor_x < text_cols) ) {
-    curs = prev_cursor_y * tm_info.line_offset + prev_cursor_x * 2;
-    old_text[curs] = ~new_text[curs];
-  }
-  if((tm_info.cs_start <= tm_info.cs_end) && (tm_info.cs_start < font_height) &&
-     (cursor_y < text_rows) && (cursor_x < text_cols)) {
-    curs = cursor_y * tm_info.line_offset + cursor_x * 2;
-    old_text[curs] = ~new_text[curs];
-  } else {
-    curs = 0xffff;
-  }
-
-  rows = text_rows;
-  if (v_panning) rows++;
-  y = 0;
-  do {
-    hchars = text_cols;
-    if (h_panning) hchars++;
-    if (v_panning) {
-      if (y == 0) {
-        yc = bx_headerbar_y;
-        font_row = v_panning;
-        cfheight = font_height - v_panning;
-      } else {
-        yc = y * font_height + bx_headerbar_y - v_panning;
-        font_row = 0;
-        if (rows == 1) {
-          cfheight = v_panning;
-        } else {
-          cfheight = font_height;
-        }
-      }
-    } else {
-      yc = y * font_height + bx_headerbar_y;
-      font_row = 0;
-      cfheight = font_height;
-    }
-    new_line = new_text;
-    old_line = old_text;
-    x = 0;
-    offset = y * tm_info.line_offset;
-    do {
-      if (h_panning) {
-        if (hchars > text_cols) {
-          xc = 0;
-          font_col = h_panning;
-          cfwidth = font_width - h_panning;
-        } else {
-          xc = x * font_width - h_panning;
-          font_col = 0;
-          if (hchars == 1) {
-            cfwidth = h_panning;
-          } else {
-            cfwidth = font_width;
-          }
-        }
-      } else {
-        xc = x * font_width;
-        font_col = 0;
-        cfwidth = font_width;
-      }
-      if ( force_update || (old_text[0] != new_text[0])
-          || (old_text[1] != new_text[1]) ) {
-
-        cChar = new_text[0];
-        new_foreground = new_text[1] & 0x0f;
-        new_background = (new_text[1] & 0xf0) >> 4;
-
-        XSetForeground(bx_x_display, gc, col_vals[DEV_vga_get_actl_pal_idx(new_foreground)]);
-        XSetBackground(bx_x_display, gc, col_vals[DEV_vga_get_actl_pal_idx(new_background)]);
-
-        XCopyPlane(bx_x_display, vgafont[cChar], win, gc, font_col, font_row, cfwidth, cfheight,
-                   xc, yc, 1);
-        if (offset == curs) {
-          XSetForeground(bx_x_display, gc, col_vals[DEV_vga_get_actl_pal_idx(new_background)]);
-          XSetBackground(bx_x_display, gc, col_vals[DEV_vga_get_actl_pal_idx(new_foreground)]);
-          if (font_row == 0) {
-            yc2 = yc + tm_info.cs_start;
-            font_row2 = tm_info.cs_start;
-            cfheight2 = tm_info.cs_end - tm_info.cs_start + 1;
-          } else {
-            if (v_panning > tm_info.cs_start) {
-              yc2 = yc;
-              font_row2 = font_row;
-              cfheight2 = tm_info.cs_end - v_panning + 1;
-            } else {
-              yc2 = yc + tm_info.cs_start - v_panning;
-              font_row2 = tm_info.cs_start;
-              cfheight2 = tm_info.cs_end - tm_info.cs_start + 1;
-            }
-          }
-          XCopyPlane(bx_x_display, vgafont[cChar], win, gc, font_col, font_row2, cfwidth,
-                     cfheight2, xc, yc2, 1);
-        }
-      }
-      x++;
-      new_text+=2;
-      old_text+=2;
-      offset+=2;
-    } while (--hchars);
-    y++;
-    new_text = new_line + tm_info.line_offset;
-    old_text = old_line + tm_info.line_offset;
-  } while (--rows);
-
-  prev_cursor_x = cursor_x;
-  prev_cursor_y = cursor_y;
-
-  XFlush(bx_x_display);
-}
-
-  int
-bx_x_gui_c::get_clipboard_text(Bit8u **bytes, Bit32s *nbytes)
-{
-  int len;
-  Bit8u *tmp = (Bit8u *)XFetchBytes (bx_x_display, &len);
-  // according to man XFetchBytes, tmp must be freed by XFree().  So allocate
-  // a new buffer with "new".  The keyboard code will free it with delete []
-  // when the paste is done.
-  Bit8u *buf = new Bit8u[len];
-  memcpy (buf, tmp, len);
-  *bytes = buf;
-  *nbytes = len;
-  XFree (tmp);
-  return 1;
-}
-
-  int
-bx_x_gui_c::set_clipboard_text(char *text_snapshot, Bit32u len)
-{
-  // this writes data to the clipboard.
-  BX_INFO (("storing %d bytes to X windows clipboard", len));
-  XSetSelectionOwner(bx_x_display, XA_PRIMARY, None, CurrentTime);
-  XStoreBytes (bx_x_display, (char *)text_snapshot, len);
-  return 1;
-}
-
-
-  void
-bx_x_gui_c::graphics_tile_update(Bit8u *tile, unsigned x0, unsigned y0)
-{
-  unsigned x, y;
-  unsigned color, offset;
-  Bit8u b0, b1, b2, b3;
-
-  Bit16u *tile16 = (Bit16u *)tile;
-  switch (vga_bpp) {
-    case 32:  // 32 bits per pixel
-      if (ximage->byte_order == LSBFirst) {
-        memcpy(&ximage->data[0], tile, x_tilesize*y_tilesize*4);
-        }
-      else { // MSBFirst
-        for (y=0; y<y_tilesize; y++) {
-          for (x=0; x<x_tilesize; x++) {
-            offset = imWide*y + 4*x;
-            ximage->data[offset + 0] = tile[(y*x_tilesize + x)*4 + 3];
-            ximage->data[offset + 1] = tile[(y*x_tilesize + x)*4 + 2];
-            ximage->data[offset + 2] = tile[(y*x_tilesize + x)*4 + 1];
-            ximage->data[offset + 3] = tile[(y*x_tilesize + x)*4];
-            }
-          }
-        }
-      break;
-    case 24:  // 24 bits per pixel
-      for (y=0; y<y_tilesize; y++) {
-        for (x=0; x<x_tilesize; x++) {
-          switch (imBPP) {
-            case 24:  // 24 bits per pixel
-              offset = imWide*y + 3*x;
-              if (ximage->byte_order == LSBFirst) {
-                ximage->data[offset + 0] = tile[(y*x_tilesize + x)*3];
-                ximage->data[offset + 1] = tile[(y*x_tilesize + x)*3 + 1];
-                ximage->data[offset + 2] = tile[(y*x_tilesize + x)*3 + 2];
-                }
-              else { // MSBFirst
-                ximage->data[offset + 0] = tile[(y*x_tilesize + x)*3 + 2];
-                ximage->data[offset + 1] = tile[(y*x_tilesize + x)*3 + 1];
-                ximage->data[offset + 2] = tile[(y*x_tilesize + x)*3];
-                }
-              break;
-            case 32:  // 32 bits per pixel
-              offset = imWide*y + 4*x;
-              if (ximage->byte_order == LSBFirst) {
-                ximage->data[offset + 0] = tile[(y*x_tilesize + x)*3];
-                ximage->data[offset + 1] = tile[(y*x_tilesize + x)*3 + 1];
-                ximage->data[offset + 2] = tile[(y*x_tilesize + x)*3 + 2];
-                ximage->data[offset + 3] = 0;
-                }
-              else { // MSBFirst
-                ximage->data[offset + 0] = 0;
-                ximage->data[offset + 1] = tile[(y*x_tilesize + x)*3 + 2];
-                ximage->data[offset + 2] = tile[(y*x_tilesize + x)*3 + 1];
-                ximage->data[offset + 3] = tile[(y*x_tilesize + x)*3];
-                }
-              break;
-            }
-          }
-        }
-      break;
-    case 16:  // 16 bits per pixel
-      for (y=0; y<y_tilesize; y++) {
-        for (x=0; x<x_tilesize; x++) {
-          switch (imBPP) {
-            case 16:  // 16 bits per pixel
-              offset = imWide*y + 2*x;
-              if (ximage->byte_order == LSBFirst) {
-                ximage->data[offset + 0] = tile[(y*x_tilesize + x)*2];
-                ximage->data[offset + 1] = tile[(y*x_tilesize + x)*2 + 1];
-                }
-              else { // MSBFirst
-                ximage->data[offset + 0] = tile[(y*x_tilesize + x)*2 + 1];
-                ximage->data[offset + 1] = tile[(y*x_tilesize + x)*2];
-                }
-              break;
-            case 24:  // 24 bits per pixel
-              offset = imWide*y + 3*x;
-              b0 = (tile16[y*x_tilesize + x] & 0x001f) << 3;
-              b1 = (tile16[y*x_tilesize + x] & 0x07e0) >> 3;
-              b2 = (tile16[y*x_tilesize + x] & 0xF800) >> 8;
-              if (ximage->byte_order == LSBFirst) {
-                ximage->data[offset + 0] = b0;
-                ximage->data[offset + 1] = b1;
-                ximage->data[offset + 2] = b2;
-                }
-              else { // MSBFirst
-                ximage->data[offset + 0] = b2;
-                ximage->data[offset + 1] = b1;
-                ximage->data[offset + 2] = b0;
-                }
-              break;
-            case 32:  // 32 bits per pixel
-              offset = imWide*y + 4*x;
-              b0 = (tile16[y*x_tilesize + x] & 0x001f) << 3;
-              b1 = (tile16[y*x_tilesize + x] & 0x07e0) >> 3;
-              b2 = (tile16[y*x_tilesize + x] & 0xF800) >> 8;
-              if (ximage->byte_order == LSBFirst) {
-                ximage->data[offset + 0] = b0;
-                ximage->data[offset + 1] = b1;
-                ximage->data[offset + 2] = b2;
-                ximage->data[offset + 3] = 0;
-                }
-              else { // MSBFirst
-                ximage->data[offset + 0] = 0;
-                ximage->data[offset + 1] = b2;
-                ximage->data[offset + 2] = b1;
-                ximage->data[offset + 3] = b0;
-                }
-              break;
-            }
-          }
-        }
-      break;
-    case 15:  // 15 bits per pixel
-      for (y=0; y<y_tilesize; y++) {
-        for (x=0; x<x_tilesize; x++) {
-          switch (imBPP) {
-            case 16:  // 16 bits per pixel
-              offset = imWide*y + 2*x;
-              b0 = (tile16[y*x_tilesize + x] & 0x001f);
-              b0 |= (tile16[y*x_tilesize + x] & 0x0060) << 1;
-              b1 = (tile16[y*x_tilesize + x] & 0x7f80) >> 7;
-              if (ximage->byte_order == LSBFirst) {
-                ximage->data[offset + 0] = b0;
-                ximage->data[offset + 1] = b1;
-                }
-              else { // MSBFirst
-                ximage->data[offset + 0] = b1;
-                ximage->data[offset + 1] = b0;
-                }
-              break;
-            case 24:  // 24 bits per pixel
-              offset = imWide*y + 3*x;
-              b0 = (tile16[y*x_tilesize + x] & 0x001f) << 3;
-              b1 = (tile16[y*x_tilesize + x] & 0x03e0) >> 2;
-              b2 = (tile16[y*x_tilesize + x] & 0x7c00) >> 7;
-              if (ximage->byte_order == LSBFirst) {
-                ximage->data[offset + 0] = b0;
-                ximage->data[offset + 1] = b1;
-                ximage->data[offset + 2] = b2;
-                }
-              else { // MSBFirst
-                ximage->data[offset + 0] = b2;
-                ximage->data[offset + 1] = b1;
-                ximage->data[offset + 2] = b0;
-                }
-              break;
-            case 32:  // 32 bits per pixel
-              offset = imWide*y + 4*x;
-              b0 = (tile16[y*x_tilesize + x] & 0x001f) << 3;
-              b1 = (tile16[y*x_tilesize + x] & 0x03e0) >> 2;
-              b2 = (tile16[y*x_tilesize + x] & 0x7c00) >> 7;
-              if (ximage->byte_order == LSBFirst) {
-                ximage->data[offset + 0] = b0;
-                ximage->data[offset + 1] = b1;
-                ximage->data[offset + 2] = b2;
-                ximage->data[offset + 3] = 0;
-                }
-              else { // MSBFirst
-                ximage->data[offset + 0] = 0;
-                ximage->data[offset + 1] = b2;
-                ximage->data[offset + 2] = b1;
-                ximage->data[offset + 3] = b0;
-                }
-              break;
-            }
-          }
-        }
-      break;
-    default:  // 8 bits per pixel
-      for (y=0; y<y_tilesize; y++) {
-        for (x=0; x<x_tilesize; x++) {
-          color = col_vals[tile[y*x_tilesize + x]];
-          switch (imBPP) {
-            case 8:  // 8 bits per pixel
-              ximage->data[imWide*y + x] = color;
-              break;
-            case 16: // 16 bits per pixel
-              offset = imWide*y + 2*x;
-              b0 = color >> 0;
-              b1 = color >> 8;
-              if (ximage->byte_order == LSBFirst) {
-                ximage->data[offset + 0] = b0;
-                ximage->data[offset + 1] = b1;
-                }
-              else { // MSBFirst
-                ximage->data[offset + 0] = b1;
-                ximage->data[offset + 1] = b0;
-                }
-              break;
-            case 24: // 24 bits per pixel
-              offset = imWide*y + 3*x;
-              b0 = color >> 0;
-              b1 = color >> 8;
-              b2 = color >> 16;
-              if (ximage->byte_order == LSBFirst) {
-                ximage->data[offset + 0] = b0;
-                ximage->data[offset + 1] = b1;
-                ximage->data[offset + 2] = b2;
-                }
-              else { // MSBFirst
-                ximage->data[offset + 0] = b2;
-                ximage->data[offset + 1] = b1;
-                ximage->data[offset + 2] = b0;
-                }
-              break;
-            case 32: // 32 bits per pixel
-              offset = imWide*y + 4*x;
-              b0 = color >> 0;
-              b1 = color >> 8;
-              b2 = color >> 16;
-              b3 = color >> 24;
-              if (ximage->byte_order == LSBFirst) {
-                ximage->data[offset + 0] = b0;
-                ximage->data[offset + 1] = b1;
-                ximage->data[offset + 2] = b2;
-                ximage->data[offset + 3] = b3;
-                }
-              else { // MSBFirst
-                ximage->data[offset + 0] = b3;
-                ximage->data[offset + 1] = b2;
-                ximage->data[offset + 2] = b1;
-                ximage->data[offset + 3] = b0;
-                }
-              break;
-            default:
-              BX_PANIC(("X_graphics_tile_update: bits_per_pixel %u not implemented",
-                (unsigned) imBPP));
-              break;
-            }
-          }
-        }
-    }
-  XPutImage(bx_x_display, win, gc, ximage, 0, 0, x0, y0+bx_headerbar_y,
-            x_tilesize, y_tilesize);
-}
-
-
-  bx_bool
-bx_x_gui_c::palette_change(unsigned index, unsigned red, unsigned green, unsigned blue)
-{
-  // returns: 0=no screen update needed (color map change has direct effect)
-  //          1=screen updated needed (redraw using current colormap)
-  XColor color;
-
-  color.flags = DoRed | DoGreen | DoBlue;
-  color.red   = red << 8;
-  color.green = green << 8;
-  color.blue  = blue << 8;
-
-  if (bx_options.Oprivate_colormap->get ()) {
-    color.pixel = index;
-    XStoreColor(bx_x_display, default_cmap, &color);
-    return(0); // no screen update needed
-    }
-  else {
-    XAllocColor(bx_x_display, DefaultColormap(bx_x_display, bx_x_screen_num),
-                &color);
-    col_vals[index] = color.pixel;
-    return(1); // screen update needed
-    }
-}
-
-
-  void
-bx_x_gui_c::dimension_update(unsigned x, unsigned y, unsigned fheight, unsigned fwidth, unsigned bpp)
-{
-  if ((bpp <= imBPP) && ((bpp == 8) || (bpp == 15) || (bpp == 16) || (bpp == 24) || (bpp == 32))) {
-    vga_bpp = bpp;
-  } else {
-    BX_PANIC(("%d bpp graphics mode not supported", bpp));
-  }
-  if (fheight > 0) {
-    font_height = fheight;
-    font_width = fwidth;
-    text_cols = x / font_width;
-    text_rows = y / font_height;
-  }
-  if ( (x != dimension_x) || (y != (dimension_y-bx_headerbar_y)) ) {
-    XSizeHints hints;
-    long supplied_return;
-
-    if ( XGetWMNormalHints(bx_x_display, win, &hints, &supplied_return) &&
-         supplied_return & PMaxSize ) {
-      hints.max_width = hints.min_width = x;
-      hints.max_height = hints.min_height = y+bx_headerbar_y;
-      XSetWMNormalHints(bx_x_display, win, &hints);
-      }
-    XResizeWindow(bx_x_display, win, x, y+bx_headerbar_y);
-    dimension_x = x;
-    dimension_y = y + bx_headerbar_y;
-    }
-}
-
-
-  void
-bx_x_gui_c::show_headerbar(void)
-{
-  unsigned xorigin;
-  int xleft, xright;
-
-  // clear header bar area to white
-  XFillRectangle(bx_x_display, win, gc_headerbar_inv, 0,0, dimension_x, bx_headerbar_y);
-
-  xleft = 0;
-  xright = dimension_x;
-  for (unsigned i=0; i<bx_headerbar_entries; i++) {
-    if (bx_headerbar_entry[i].alignment == BX_GRAVITY_LEFT) {
-      xorigin = bx_headerbar_entry[i].xorigin;
-      xleft += bx_headerbar_entry[i].xdim;
-      }
-    else {
-      xorigin = dimension_x - bx_headerbar_entry[i].xorigin;
-      xright = xorigin;
-      }
-    if (xright < xleft) break;
-    XCopyPlane(bx_x_display, bx_headerbar_entry[i].bitmap, win, gc_headerbar,
-      0,0, bx_headerbar_entry[i].xdim, bx_headerbar_entry[i].ydim,
-              xorigin, 0, 1);
-    }
-}
-
-
-  unsigned
-bx_x_gui_c::create_bitmap(const unsigned char *bmap, unsigned xdim, unsigned ydim)
-{
-  if (bx_bitmap_entries >= BX_MAX_PIXMAPS) {
-    BX_PANIC(("x: too many pixmaps, increase BX_MAX_PIXMAPS"));
-    }
-
-  bx_bitmaps[bx_bitmap_entries].bmap =
-    XCreateBitmapFromData(bx_x_display, win, (const char *) bmap, xdim, ydim);
-  bx_bitmaps[bx_bitmap_entries].xdim = xdim;
-  bx_bitmaps[bx_bitmap_entries].ydim = ydim;
-  if (!bx_bitmaps[bx_bitmap_entries].bmap) {
-    BX_PANIC(("x: could not create bitmap"));
-    }
-  bx_bitmap_entries++;
-  return(bx_bitmap_entries-1); // return index as handle
-}
-
-
-  unsigned
-bx_x_gui_c::headerbar_bitmap(unsigned bmap_id, unsigned alignment, void (*f)(void))
-{
-  unsigned hb_index;
-
-  if ( (bx_headerbar_entries+1) > BX_MAX_HEADERBAR_ENTRIES )
-    BX_PANIC(("x: too many headerbar entries, increase BX_MAX_HEADERBAR_ENTRIES"));
-
-  bx_headerbar_entries++;
-  hb_index = bx_headerbar_entries - 1;
-
-  bx_headerbar_entry[hb_index].bitmap = bx_bitmaps[bmap_id].bmap;
-  bx_headerbar_entry[hb_index].xdim   = bx_bitmaps[bmap_id].xdim;
-  bx_headerbar_entry[hb_index].ydim   = bx_bitmaps[bmap_id].ydim;
-  bx_headerbar_entry[hb_index].alignment = alignment;
-  bx_headerbar_entry[hb_index].f = f;
-  if (alignment == BX_GRAVITY_LEFT) {
-    bx_headerbar_entry[hb_index].xorigin = bx_bitmap_left_xorigin;
-    bx_headerbar_entry[hb_index].yorigin = 0;
-    bx_bitmap_left_xorigin += bx_bitmaps[bmap_id].xdim;
-    }
-  else { // BX_GRAVITY_RIGHT
-    bx_bitmap_right_xorigin += bx_bitmaps[bmap_id].xdim;
-    bx_headerbar_entry[hb_index].xorigin = bx_bitmap_right_xorigin;
-    bx_headerbar_entry[hb_index].yorigin = 0;
-    }
-  return(hb_index);
-}
-
-  void
-bx_x_gui_c::replace_bitmap(unsigned hbar_id, unsigned bmap_id)
-{
-  unsigned xorigin;
-
-  bx_headerbar_entry[hbar_id].bitmap = bx_bitmaps[bmap_id].bmap;
-
-  if (bx_headerbar_entry[hbar_id].alignment == BX_GRAVITY_LEFT)
-    xorigin = bx_headerbar_entry[hbar_id].xorigin;
-  else
-    xorigin = dimension_x - bx_headerbar_entry[hbar_id].xorigin;
-  XCopyPlane(bx_x_display, bx_headerbar_entry[hbar_id].bitmap, win, gc_headerbar,
-    0,0, bx_headerbar_entry[hbar_id].xdim, bx_headerbar_entry[hbar_id].ydim,
-            xorigin, 0, 1);
-}
-
-
-  void
-headerbar_click(int x, int y)
-{
-  int xorigin;
-
-  // assuming y is in bounds
-  UNUSED(y);
-  for (unsigned i=0; i<bx_headerbar_entries; i++) {
-    if (bx_headerbar_entry[i].alignment == BX_GRAVITY_LEFT)
-      xorigin = bx_headerbar_entry[i].xorigin;
-    else
-      xorigin = dimension_x - bx_headerbar_entry[i].xorigin;
-    if ( (x>=xorigin) && (x<(xorigin+int(bx_headerbar_entry[i].xdim))) ) {
-      bx_headerbar_entry[i].f();
-      return;
-      }
-    }
-}
-
-  void
-bx_x_gui_c::exit(void)
-{
-  if (!x_init_done) return;
-
-  // Delete the font bitmaps
-  for (int i=0; i<256; i++) {
-    //if (vgafont[i] != NULL) 
-      XFreePixmap(bx_x_display,vgafont[i]);
-  }
-
-  if (bx_x_display)
-    XCloseDisplay (bx_x_display);
-  BX_INFO(("Exit."));
-}
-
-static void warp_cursor (int dx, int dy)
-{
-      if (bx_options.Omouse_enabled->get () &&
-         (warp_dx || warp_dy || dx || dy)
-         ) {
-           warp_dx = dx;
-           warp_dy = dy;
-           XWarpPointer(bx_x_display, None, None, 0, 0, 0, 0, dx, dy);
-      }
-}
-
-static void disable_cursor ()
-{
-      static Cursor cursor;
-      static unsigned cursor_created = 0;
-
-      static int shape_width = 16,
-            shape_height = 16,
-            mask_width = 16,
-            mask_height = 16;
-
-      static uint32 shape_bits[(16*16)/32] = {
-           0x00000000, 0x00000000, 0x00000000, 0x00000000,
-           0x00000000, 0x00000000, 0x00000000, 0x00000000,
-      };
-      static uint32 mask_bits[(16*16)/32] = {
-           0x00000000, 0x00000000, 0x00000000, 0x00000000,
-           0x00000000, 0x00000000, 0x00000000, 0x00000000,
-      };
-
-      if (!cursor_created) {
-           Pixmap shape, mask;
-           XColor white, black;
-           shape = XCreatePixmapFromBitmapData(bx_x_display,
-                                               RootWindow(bx_x_display,bx_x_screen_num),
-                                               (char*)shape_bits,
-                                               shape_width,
-                                               shape_height,
-                                               1, 0, 1);
-           mask =  XCreatePixmapFromBitmapData(bx_x_display,
-                                               RootWindow(bx_x_display,bx_x_screen_num),
-                                               (char*)mask_bits,
-                                               mask_width,
-                                               mask_height,
-                                               1, 0, 1);
-           XParseColor(bx_x_display, default_cmap, "black", &black);
-           XParseColor(bx_x_display, default_cmap, "white", &white);
-           cursor = XCreatePixmapCursor(bx_x_display, shape, mask,
-                                        &white, &black, 1, 1);
-           cursor_created = 1;
-      }
-
-      XDefineCursor(bx_x_display, win, cursor);
-}
-
-static void enable_cursor ()
-{
-      XUndefineCursor(bx_x_display, win);
-}
-
-/* convertStringToXKeysym is a keymap callback
- * used when reading the keymap file.
- * It converts a Symblic String to a GUI Constant
- *
- * It returns a Bit32u constant or BX_KEYMAP_UNKNOWN if it fails
- */
-static Bit32u convertStringToXKeysym (const char *string)
-{
-    if (strncmp ("XK_", string, 3) != 0)
-      return BX_KEYMAP_UNKNOWN;
-    KeySym keysym=XStringToKeysym(string+3);
-
-    // failure, return unknown
-    if(keysym==NoSymbol) return BX_KEYMAP_UNKNOWN;
-
-    return((Bit32u)keysym);
-}
-
-#if BX_USE_IDLE_HACK
-
-/* BX_USE_IDLE_HACK: a small idle hack by
- * Roland.Mainz@informatik.med.uni-giessen.de to prevent bochs
- * from consuming 100% CPU time even when it is not required (for
- * example, the OS in the emulator calls HLT to wait for an interupt)
- * pro:
- * - no more 100% CPU usage
- * contra:
- * - we're sleeping too long
- * - bochs still consumes ~10%-20% CPU time while executing an idle 
- *   linux kernel
- * - this is an hack
- */
-
-/* XPeekEvent() with timeout 
- * (adopted from mozilla/gfx/src/xprint/xprintutil_printtofile.c#XNextEventTimeout())
- */
-static
-Bool XPeekEventTimeout( Display *display, XEvent *event_return, struct timeval *timeout ) 
-{
-    int      res;
-    fd_set   readfds;
-    int      display_fd = XConnectionNumber(display);
-
-    /* small shortcut... */
-    if( timeout == NULL )
-    {
-      XPeekEvent(display, event_return);
-      return(True);
-    }
-    
-    FD_ZERO(&readfds);
-    FD_SET(display_fd, &readfds);
-
-    /* Note/bug: In the case of internal X events (like used to trigger callbacks 
-     * registered by XpGetDocumentData()&co.) select() will return with "new info" 
-     * - but XNextEvent() below processes these _internal_ events silently - and 
-     * will block if there are no other non-internal events.
-     * The workaround here is to check with XEventsQueued() if there are non-internal 
-     * events queued - if not select() will be called again - unfortunately we use 
-     * the old timeout here instead of the "remaining" time... (this only would hurt 
-     * if the timeout would be really long - but for current use with values below
-     * 1/2 secs it does not hurt... =:-)
-     */
-    while( XEventsQueued(display, QueuedAfterFlush) == 0 )
-    {
-      res = select(display_fd+1, &readfds, NULL, NULL, timeout);
-    
-      switch(res)
-      {
-        case -1: /* select() error - should not happen */ 
-            perror("XPeekEventTimeout: select() failure"); 
-            return(False);
-        case  0: /* timeout */
-          return(False);
-      }
-    }
-    
-    XPeekEvent(display, event_return); 
-    return(True);
-}
-
-#if BX_USE_IDLE_HACK
-void bx_x_gui_c::sim_is_idle () {
-  XEvent dummy;
-  struct timeval   timeout;   
-  timeout.tv_sec  = 0;
-  timeout.tv_usec = 1000; /* 1/1000 s */  
-  XPeekEventTimeout(bx_x_display, &dummy, &timeout);
-}
-#endif
-#endif /* BX_USE_IDLE_HACK */  
-
-#endif /* if BX_WITH_X11 */
diff --git a/tools/ioemu/hw/adb.c b/tools/ioemu/hw/adb.c
new file mode 100644 (file)
index 0000000..36c4aec
--- /dev/null
@@ -0,0 +1,386 @@
+/*
+ * QEMU ADB support
+ * 
+ * Copyright (c) 2004 Fabrice Bellard
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+
+/* ADB commands */
+#define ADB_BUSRESET           0x00
+#define ADB_FLUSH               0x01
+#define ADB_WRITEREG           0x08
+#define ADB_READREG            0x0c
+
+/* ADB device commands */
+#define ADB_CMD_SELF_TEST              0xff
+#define ADB_CMD_CHANGE_ID              0xfe
+#define ADB_CMD_CHANGE_ID_AND_ACT      0xfd
+#define ADB_CMD_CHANGE_ID_AND_ENABLE   0x00
+
+/* ADB default device IDs (upper 4 bits of ADB command byte) */
+#define ADB_DONGLE     1
+#define ADB_KEYBOARD   2
+#define ADB_MOUSE      3
+#define ADB_TABLET     4
+#define ADB_MODEM      5
+#define ADB_MISC       7
+
+/* error codes */
+#define ADB_RET_NOTPRESENT (-2)
+
+int adb_request(ADBBusState *s, uint8_t *obuf, const uint8_t *buf, int len)
+{
+    ADBDevice *d;
+    int devaddr, cmd, i;
+
+    cmd = buf[0] & 0xf;
+    if (cmd == ADB_BUSRESET) {
+        for(i = 0; i < s->nb_devices; i++) {
+            d = &s->devices[i];
+            if (d->devreset) {
+                d->devreset(d);
+            }
+        }
+        return 0;
+    }
+    devaddr = buf[0] >> 4;
+    for(i = 0; i < s->nb_devices; i++) {
+        d = &s->devices[i];
+        if (d->devaddr == devaddr) {
+            return d->devreq(d, obuf, buf, len);
+        }
+    }
+    return ADB_RET_NOTPRESENT;
+}
+
+/* XXX: move that to cuda ? */
+int adb_poll(ADBBusState *s, uint8_t *obuf)
+{
+    ADBDevice *d;
+    int olen, i;
+    uint8_t buf[1];
+
+    olen = 0;
+    for(i = 0; i < s->nb_devices; i++) {
+        if (s->poll_index >= s->nb_devices)
+            s->poll_index = 0;
+        d = &s->devices[s->poll_index];
+        buf[0] = ADB_READREG | (d->devaddr << 4);
+        olen = adb_request(s, obuf + 1, buf, 1);
+        /* if there is data, we poll again the same device */
+        if (olen > 0) {
+            obuf[0] = buf[0];
+            olen++;
+            break;
+        }
+        s->poll_index++;
+    }
+    return olen;
+}
+
+ADBDevice *adb_register_device(ADBBusState *s, int devaddr, 
+                               ADBDeviceRequest *devreq, 
+                               ADBDeviceReset *devreset, 
+                               void *opaque)
+{
+    ADBDevice *d;
+    if (s->nb_devices >= MAX_ADB_DEVICES)
+        return NULL;
+    d = &s->devices[s->nb_devices++];
+    d->bus = s;
+    d->devaddr = devaddr;
+    d->devreq = devreq;
+    d->devreset = devreset;
+    d->opaque = opaque;
+    return d;
+}
+
+/***************************************************************/
+/* Keyboard ADB device */
+
+typedef struct KBDState {
+    uint8_t data[128];
+    int rptr, wptr, count;
+} KBDState;
+
+static const uint8_t pc_to_adb_keycode[256] = {
+  0, 53, 18, 19, 20, 21, 23, 22, 26, 28, 25, 29, 27, 24, 51, 48,
+ 12, 13, 14, 15, 17, 16, 32, 34, 31, 35, 33, 30, 36, 54,  0,  1,
+  2,  3,  5,  4, 38, 40, 37, 41, 39, 50, 56, 42,  6,  7,  8,  9,
+ 11, 45, 46, 43, 47, 44,123, 67, 58, 49, 57,122,120, 99,118, 96,
+ 97, 98,100,101,109, 71,107, 89, 91, 92, 78, 86, 87, 88, 69, 83,
+ 84, 85, 82, 65,  0,  0, 10,103,111,  0,  0,110, 81,  0,  0,  0,
+  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+  0,  0,  0, 94,  0, 93,  0,  0,  0,  0,  0,  0,104,102,  0,  0,
+  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 76,125,  0,  0,
+  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,105,  0,  0,  0,  0,  0,
+  0,  0,  0,  0,  0, 75,  0,  0,124,  0,  0,  0,  0,  0,  0,  0,
+  0,  0,  0,  0,  0,  0,  0,115, 62,116,  0, 59,  0, 60,  0,119,
+ 61,121,114,117,  0,  0,  0,  0,  0,  0,  0, 55,126,  0,127,  0,
+  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+  0,  0,  0,  0,  0, 95,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+};
+
+static void adb_kbd_put_keycode(void *opaque, int keycode)
+{
+    ADBDevice *d = opaque;
+    KBDState *s = d->opaque;
+
+    if (s->count < sizeof(s->data)) {
+        s->data[s->wptr] = keycode;
+        if (++s->wptr == sizeof(s->data))
+            s->wptr = 0;
+        s->count++;
+    }
+}
+
+static int adb_kbd_poll(ADBDevice *d, uint8_t *obuf)
+{
+    static int ext_keycode;
+    KBDState *s = d->opaque;
+    int adb_keycode, keycode;
+    int olen;
+
+    olen = 0;
+    for(;;) {
+        if (s->count == 0)
+            break;
+        keycode = s->data[s->rptr];
+        if (++s->rptr == sizeof(s->data))
+            s->rptr = 0;
+        s->count--;
+
+        if (keycode == 0xe0) {
+            ext_keycode = 1;
+        } else {
+            if (ext_keycode)
+                adb_keycode =  pc_to_adb_keycode[keycode | 0x80];
+            else
+                adb_keycode =  pc_to_adb_keycode[keycode & 0x7f];
+            obuf[0] = adb_keycode | (keycode & 0x80);
+            /* NOTE: could put a second keycode if needed */
+            obuf[1] = 0xff;
+            olen = 2;
+            ext_keycode = 0;
+            break;
+        }
+    }
+    return olen;
+}
+
+static int adb_kbd_request(ADBDevice *d, uint8_t *obuf,
+                           const uint8_t *buf, int len)
+{
+    KBDState *s = d->opaque;
+    int cmd, reg, olen;
+
+    if ((buf[0] & 0x0f) == ADB_FLUSH) {
+        /* flush keyboard fifo */
+        s->wptr = s->rptr = s->count = 0;
+        return 0;
+    }
+
+    cmd = buf[0] & 0xc;
+    reg = buf[0] & 0x3;
+    olen = 0;
+    switch(cmd) {
+    case ADB_WRITEREG:
+        switch(reg) {
+        case 2:
+            /* LED status */
+            break;
+        case 3:
+            switch(buf[2]) {
+            case ADB_CMD_SELF_TEST:
+                break;
+            case ADB_CMD_CHANGE_ID:
+            case ADB_CMD_CHANGE_ID_AND_ACT:
+            case ADB_CMD_CHANGE_ID_AND_ENABLE:
+                d->devaddr = buf[1] & 0xf;
+                break;
+            default:
+                /* XXX: check this */
+                d->devaddr = buf[1] & 0xf;
+                d->handler = buf[2];
+                break;
+            }
+        }
+        break;
+    case ADB_READREG:
+        switch(reg) {
+        case 0:
+            olen = adb_kbd_poll(d, obuf);
+            break;
+        case 1:
+            break;
+        case 2:
+            obuf[0] = 0x00; /* XXX: check this */
+            obuf[1] = 0x07; /* led status */
+            olen = 2;
+            break;
+        case 3:
+            obuf[0] = d->handler;
+            obuf[1] = d->devaddr;
+            olen = 2;
+            break;
+        }
+        break;
+    }
+    return olen;
+}
+
+void adb_kbd_init(ADBBusState *bus)
+{
+    ADBDevice *d;
+    KBDState *s;
+    s = qemu_mallocz(sizeof(KBDState));
+    d = adb_register_device(bus, ADB_KEYBOARD, adb_kbd_request, NULL, s);
+    d->handler = 1;
+    qemu_add_kbd_event_handler(adb_kbd_put_keycode, d);
+}
+
+/***************************************************************/
+/* Mouse ADB device */
+
+typedef struct MouseState {
+    int buttons_state, last_buttons_state;
+    int dx, dy, dz;
+} MouseState;
+
+static void adb_mouse_event(void *opaque,
+                            int dx1, int dy1, int dz1, int buttons_state)
+{
+    ADBDevice *d = opaque;
+    MouseState *s = d->opaque;
+
+    s->dx += dx1;
+    s->dy += dy1;
+    s->dz += dz1;
+    s->buttons_state = buttons_state;
+}
+
+
+static int adb_mouse_poll(ADBDevice *d, uint8_t *obuf)
+{
+    MouseState *s = d->opaque;
+    int dx, dy;
+
+    if (s->last_buttons_state == s->buttons_state &&
+        s->dx == 0 && s->dy == 0)
+        return 0;
+        
+    dx = s->dx;
+    if (dx < -63)
+        dx = -63;
+    else if (dx > 63)
+        dx = 63;
+    
+    dy = s->dy;
+    if (dy < -63)
+        dy = -63;
+    else if (dy > 63)
+        dy = 63;
+    
+    s->dx -= dx;
+    s->dy -= dy;
+    s->last_buttons_state = s->buttons_state;
+    
+    dx &= 0x7f;
+    dy &= 0x7f;
+    
+    if (!(s->buttons_state & MOUSE_EVENT_LBUTTON))
+        dy |= 0x80;
+    if (!(s->buttons_state & MOUSE_EVENT_RBUTTON))
+        dx |= 0x80;
+    
+    obuf[0] = dy;
+    obuf[1] = dx;
+    return 2;
+}
+
+static int adb_mouse_request(ADBDevice *d, uint8_t *obuf,
+                             const uint8_t *buf, int len)
+{
+    MouseState *s = d->opaque;
+    int cmd, reg, olen;
+    
+    if ((buf[0] & 0x0f) == ADB_FLUSH) {
+        /* flush mouse fifo */
+        s->buttons_state = s->last_buttons_state;
+        s->dx = 0;
+        s->dy = 0;
+        s->dz = 0;
+        return 0;
+    }
+
+    cmd = buf[0] & 0xc;
+    reg = buf[0] & 0x3;
+    olen = 0;
+    switch(cmd) {
+    case ADB_WRITEREG:
+        switch(reg) {
+        case 2:
+            break;
+        case 3:
+            switch(buf[2]) {
+            case ADB_CMD_SELF_TEST:
+                break;
+            case ADB_CMD_CHANGE_ID:
+            case ADB_CMD_CHANGE_ID_AND_ACT:
+            case ADB_CMD_CHANGE_ID_AND_ENABLE:
+                d->devaddr = buf[1] & 0xf;
+                break;
+            default:
+                /* XXX: check this */
+                d->devaddr = buf[1] & 0xf;
+                break;
+            }
+        }
+        break;
+    case ADB_READREG:
+        switch(reg) {
+        case 0:
+            olen = adb_mouse_poll(d, obuf);
+            break;
+        case 1:
+            break;
+        case 3:
+            obuf[0] = d->handler;
+            obuf[1] = d->devaddr;
+            olen = 2;
+            break;
+        }
+        break;
+    }
+    return olen;
+}
+
+void adb_mouse_init(ADBBusState *bus)
+{
+    ADBDevice *d;
+    MouseState *s;
+
+    s = qemu_mallocz(sizeof(MouseState));
+    d = adb_register_device(bus, ADB_MOUSE, adb_mouse_request, NULL, s);
+    d->handler = 2;
+    qemu_add_mouse_event_handler(adb_mouse_event, d);
+}
diff --git a/tools/ioemu/hw/adlib.c b/tools/ioemu/hw/adlib.c
new file mode 100644 (file)
index 0000000..939a7ed
--- /dev/null
@@ -0,0 +1,313 @@
+/*
+ * QEMU Adlib emulation
+ * 
+ * Copyright (c) 2004 Vassili Karpov (malc)
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+
+#define dolog(...) AUD_log ("adlib", __VA_ARGS__)
+#ifdef DEBUG
+#define ldebug(...) dolog (__VA_ARGS__)
+#else
+#define ldebug(...)
+#endif
+
+#ifdef USE_YMF262
+#define HAS_YMF262 1
+#include "ymf262.h"
+void YMF262UpdateOneQEMU(int which, INT16 *dst, int length);
+#define SHIFT 2
+#else
+#include "fmopl.h"
+#define SHIFT 1
+#endif
+
+#ifdef _WIN32
+#include <windows.h>
+#define small_delay() Sleep (1)
+#else
+#define small_delay() usleep (1)
+#endif
+
+#define IO_READ_PROTO(name) \
+    uint32_t name (void *opaque, uint32_t nport)
+#define IO_WRITE_PROTO(name) \
+    void name (void *opaque, uint32_t nport, uint32_t val)
+
+static struct {
+    int port;
+    int freq;
+} conf = {0x220, 44100};
+
+typedef struct {
+    int enabled;
+    int active;
+    int cparam;
+    int64_t ticks;
+    int bufpos;
+    int16_t *mixbuf;
+    double interval;
+    QEMUTimer *ts, *opl_ts;
+    SWVoice *voice;
+    int left, pos, samples, bytes_per_second, old_free;
+    int refcount;
+#ifndef USE_YMF262
+    FM_OPL *opl;
+#endif
+} AdlibState;
+
+static AdlibState adlib;
+
+static IO_WRITE_PROTO(adlib_write)
+{
+    AdlibState *s = opaque;
+    int a = nport & 3;
+    int status;
+
+    s->ticks = qemu_get_clock (vm_clock);
+    s->active = 1;
+    AUD_enable (s->voice, 1);
+
+#ifdef USE_YMF262
+    status = YMF262Write (0, a, val);
+#else
+    status = OPLWrite (s->opl, a, val);
+#endif
+}
+
+static IO_READ_PROTO(adlib_read)
+{
+    AdlibState *s = opaque;
+    uint8_t data;
+    int a = nport & 3;
+
+#ifdef USE_YMF262
+    (void) s;
+    data = YMF262Read (0, a);
+#else
+    data = OPLRead (s->opl, a);
+#endif
+    return data;
+}
+
+static void OPL_timer (void *opaque)
+{
+    AdlibState *s = opaque;
+#ifdef USE_YMF262
+    YMF262TimerOver (s->cparam >> 1, s->cparam & 1);
+#else
+    OPLTimerOver (s->opl, s->cparam);
+#endif
+    qemu_mod_timer (s->opl_ts, qemu_get_clock (vm_clock) + s->interval);
+}
+
+static void YMF262TimerHandler (int c, double interval_Sec)
+{
+    AdlibState *s = &adlib;
+    if (interval_Sec == 0.0) {
+        qemu_del_timer (s->opl_ts);
+        return;
+    }
+    s->cparam = c;
+    s->interval = ticks_per_sec * interval_Sec;
+    qemu_mod_timer (s->opl_ts, qemu_get_clock (vm_clock) + s->interval);
+    small_delay ();
+}
+
+static int write_audio (AdlibState *s, int samples)
+{
+    int net = 0;
+    int ss = samples;
+    while (samples) {
+        int nbytes = samples << SHIFT;
+        int wbytes = AUD_write (s->voice,
+                                s->mixbuf + (s->pos << (SHIFT - 1)),
+                                nbytes);
+        int wsampl = wbytes >> SHIFT;
+        samples -= wsampl;
+        s->pos = (s->pos + wsampl) % s->samples;
+        net += wsampl;
+        if (!wbytes)
+            break;
+    }
+    if (net > ss) {
+        dolog ("WARNING: net > ss\n");
+    }
+    return net;
+}
+
+static void timer (void *opaque)
+{
+    AdlibState *s = opaque;
+    int elapsed, samples, net = 0;
+
+    if (s->refcount)
+        dolog ("refcount=%d\n", s->refcount);
+
+    s->refcount += 1;
+    if (!(s->active && s->enabled))
+        goto reset;
+
+    AUD_run ();
+
+    while (s->left) {
+        int written = write_audio (s, s->left);
+        net += written;
+        if (!written)
+            goto reset2;
+        s->left -= written;
+    }
+    s->pos = 0;
+
+    elapsed = AUD_calc_elapsed (s->voice);
+    if (!elapsed)
+        goto reset2;
+
+    /* elapsed = AUD_get_free (s->voice); */
+    samples = elapsed >> SHIFT;
+    if (!samples)
+        goto reset2;
+
+    samples = audio_MIN (samples, s->samples - s->pos);
+    if (s->left)
+        dolog ("left=%d samples=%d elapsed=%d free=%d\n",
+               s->left, samples, elapsed, AUD_get_free (s->voice));
+
+    if (!samples)
+        goto reset2;
+
+#ifdef USE_YMF262
+    YMF262UpdateOneQEMU (0, s->mixbuf + s->pos * 2, samples);
+#else
+    YM3812UpdateOne (s->opl, s->mixbuf + s->pos, samples);
+#endif
+
+    while (samples) {
+        int written = write_audio (s, samples);
+        net += written;
+        if (!written)
+            break;
+        samples -= written;
+    }
+    if (!samples)
+        s->pos = 0;
+    s->left = samples;
+
+reset2:
+    AUD_adjust (s->voice, net << SHIFT);
+reset:
+    qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + ticks_per_sec / 1024);
+    s->refcount -= 1;
+}
+
+static void Adlib_fini (AdlibState *s)
+{
+#ifdef USE_YMF262
+    YMF262Shutdown ();
+#else
+    if (s->opl) {
+        OPLDestroy (s->opl);
+        s->opl = NULL;
+    }
+#endif
+
+    if (s->opl_ts)
+        qemu_free_timer (s->opl_ts);
+
+    if (s->ts)
+        qemu_free_timer (s->ts);
+
+#define maybe_free(p) if (p) qemu_free (p)
+    maybe_free (s->mixbuf);
+#undef maybe_free
+
+    s->active = 0;
+    s->enabled = 0;
+}
+
+void Adlib_init (void)
+{
+    AdlibState *s = &adlib;
+
+    memset (s, 0, sizeof (*s));
+
+#ifdef USE_YMF262
+    if (YMF262Init (1, 14318180, conf.freq)) {
+        dolog ("YMF262Init %d failed\n", conf.freq);
+        return;
+    }
+    else {
+        YMF262SetTimerHandler (0, YMF262TimerHandler, 0);
+        s->enabled = 1;
+    }
+#else
+    s->opl = OPLCreate (OPL_TYPE_YM3812, 3579545, conf.freq);
+    if (!s->opl) {
+        dolog ("OPLCreate %d failed\n", conf.freq);
+        return;
+    }
+    else {
+        OPLSetTimerHandler (s->opl, YMF262TimerHandler, 0);
+        s->enabled = 1;
+    }
+#endif
+
+    s->opl_ts = qemu_new_timer (vm_clock, OPL_timer, s);
+    if (!s->opl_ts) {
+        dolog ("Can not get timer for adlib emulation\n");
+        Adlib_fini (s);
+        return;
+    }
+
+    s->ts = qemu_new_timer (vm_clock, timer, s);
+    if (!s->opl_ts) {
+        dolog ("Can not get timer for adlib emulation\n");
+        Adlib_fini (s);
+        return;
+    }
+
+    s->voice = AUD_open (s->voice, "adlib", conf.freq, SHIFT, AUD_FMT_S16);
+    if (!s->voice) {
+        Adlib_fini (s);
+        return;
+    }
+
+    s->bytes_per_second = conf.freq << SHIFT;
+    s->samples = AUD_get_buffer_size (s->voice) >> SHIFT;
+    s->mixbuf = qemu_mallocz (s->samples << SHIFT);
+
+    if (!s->mixbuf) {
+        dolog ("not enough memory for adlib mixing buffer (%d)\n",
+               s->samples << SHIFT);
+        Adlib_fini (s);
+        return;
+    }
+    register_ioport_read (0x388, 4, 1, adlib_read, s);
+    register_ioport_write (0x388, 4, 1, adlib_write, s);
+
+    register_ioport_read (conf.port, 4, 1, adlib_read, s);
+    register_ioport_write (conf.port, 4, 1, adlib_write, s);
+
+    register_ioport_read (conf.port + 8, 2, 1, adlib_read, s);
+    register_ioport_write (conf.port + 8, 2, 1, adlib_write, s);
+
+    qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + 1);
+}
diff --git a/tools/ioemu/hw/cirrus_vga.c b/tools/ioemu/hw/cirrus_vga.c
new file mode 100644 (file)
index 0000000..7c34c57
--- /dev/null
@@ -0,0 +1,3115 @@
+/*
+ * QEMU Cirrus CLGD 54xx VGA Emulator.
+ * 
+ * Copyright (c) 2004 Fabrice Bellard
+ * Copyright (c) 2004 Makoto Suzuki (suzu)
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+/*
+ * Reference: Finn Thogersons' VGADOC4b
+ *   available at http://home.worldonline.dk/~finth/
+ */
+#include "vl.h"
+#include "vga_int.h"
+
+/*
+ * TODO:
+ *    - add support for WRITEMASK (GR2F)
+ *    - optimize linear mappings
+ *    - optimize bitblt functions
+ */
+
+//#define DEBUG_CIRRUS
+//#define DEBUG_BITBLT
+
+/***************************************
+ *
+ *  definitions
+ *
+ ***************************************/
+
+#define qemu_MIN(a,b) ((a) < (b) ? (a) : (b))
+
+// ID
+#define CIRRUS_ID_CLGD5422  (0x23<<2)
+#define CIRRUS_ID_CLGD5426  (0x24<<2)
+#define CIRRUS_ID_CLGD5424  (0x25<<2)
+#define CIRRUS_ID_CLGD5428  (0x26<<2)
+#define CIRRUS_ID_CLGD5430  (0x28<<2)
+#define CIRRUS_ID_CLGD5434  (0x2A<<2)
+#define CIRRUS_ID_CLGD5436  (0x2B<<2)
+#define CIRRUS_ID_CLGD5446  (0x2E<<2)
+
+// sequencer 0x07
+#define CIRRUS_SR7_BPP_VGA            0x00
+#define CIRRUS_SR7_BPP_SVGA           0x01
+#define CIRRUS_SR7_BPP_MASK           0x0e
+#define CIRRUS_SR7_BPP_8              0x00
+#define CIRRUS_SR7_BPP_16_DOUBLEVCLK  0x02
+#define CIRRUS_SR7_BPP_24             0x04
+#define CIRRUS_SR7_BPP_16             0x06
+#define CIRRUS_SR7_BPP_32             0x08
+#define CIRRUS_SR7_ISAADDR_MASK       0xe0
+
+// sequencer 0x0f
+#define CIRRUS_MEMSIZE_512k        0x08
+#define CIRRUS_MEMSIZE_1M          0x10
+#define CIRRUS_MEMSIZE_2M          0x18
+#define CIRRUS_MEMFLAGS_BANKSWITCH 0x80        // bank switching is enabled.
+
+// sequencer 0x12
+#define CIRRUS_CURSOR_SHOW         0x01
+#define CIRRUS_CURSOR_HIDDENPEL    0x02
+#define CIRRUS_CURSOR_LARGE        0x04        // 64x64 if set, 32x32 if clear
+
+// sequencer 0x17
+#define CIRRUS_BUSTYPE_VLBFAST   0x10
+#define CIRRUS_BUSTYPE_PCI       0x20
+#define CIRRUS_BUSTYPE_VLBSLOW   0x30
+#define CIRRUS_BUSTYPE_ISA       0x38
+#define CIRRUS_MMIO_ENABLE       0x04
+#define CIRRUS_MMIO_USE_PCIADDR  0x40  // 0xb8000 if cleared.
+#define CIRRUS_MEMSIZEEXT_DOUBLE 0x80
+
+// control 0x0b
+#define CIRRUS_BANKING_DUAL             0x01
+#define CIRRUS_BANKING_GRANULARITY_16K  0x20   // set:16k, clear:4k
+
+// control 0x30
+#define CIRRUS_BLTMODE_BACKWARDS        0x01
+#define CIRRUS_BLTMODE_MEMSYSDEST       0x02
+#define CIRRUS_BLTMODE_MEMSYSSRC        0x04
+#define CIRRUS_BLTMODE_TRANSPARENTCOMP  0x08
+#define CIRRUS_BLTMODE_PATTERNCOPY      0x40
+#define CIRRUS_BLTMODE_COLOREXPAND      0x80
+#define CIRRUS_BLTMODE_PIXELWIDTHMASK   0x30
+#define CIRRUS_BLTMODE_PIXELWIDTH8      0x00
+#define CIRRUS_BLTMODE_PIXELWIDTH16     0x10
+#define CIRRUS_BLTMODE_PIXELWIDTH24     0x20
+#define CIRRUS_BLTMODE_PIXELWIDTH32     0x30
+
+// control 0x31
+#define CIRRUS_BLT_BUSY                 0x01
+#define CIRRUS_BLT_START                0x02
+#define CIRRUS_BLT_RESET                0x04
+#define CIRRUS_BLT_FIFOUSED             0x10
+#define CIRRUS_BLT_AUTOSTART            0x80
+
+// control 0x32
+#define CIRRUS_ROP_0                    0x00
+#define CIRRUS_ROP_SRC_AND_DST          0x05
+#define CIRRUS_ROP_NOP                  0x06
+#define CIRRUS_ROP_SRC_AND_NOTDST       0x09
+#define CIRRUS_ROP_NOTDST               0x0b
+#define CIRRUS_ROP_SRC                  0x0d
+#define CIRRUS_ROP_1                    0x0e
+#define CIRRUS_ROP_NOTSRC_AND_DST       0x50
+#define CIRRUS_ROP_SRC_XOR_DST          0x59
+#define CIRRUS_ROP_SRC_OR_DST           0x6d
+#define CIRRUS_ROP_NOTSRC_OR_NOTDST     0x90
+#define CIRRUS_ROP_SRC_NOTXOR_DST       0x95
+#define CIRRUS_ROP_SRC_OR_NOTDST        0xad
+#define CIRRUS_ROP_NOTSRC               0xd0
+#define CIRRUS_ROP_NOTSRC_OR_DST        0xd6
+#define CIRRUS_ROP_NOTSRC_AND_NOTDST    0xda
+
+#define CIRRUS_ROP_NOP_INDEX 2
+#define CIRRUS_ROP_SRC_INDEX 5
+
+// control 0x33
+#define CIRRUS_BLTMODEEXT_SOLIDFILL        0x04
+#define CIRRUS_BLTMODEEXT_COLOREXPINV      0x02
+#define CIRRUS_BLTMODEEXT_DWORDGRANULARITY 0x01
+
+// memory-mapped IO
+#define CIRRUS_MMIO_BLTBGCOLOR        0x00     // dword
+#define CIRRUS_MMIO_BLTFGCOLOR        0x04     // dword
+#define CIRRUS_MMIO_BLTWIDTH          0x08     // word
+#define CIRRUS_MMIO_BLTHEIGHT         0x0a     // word
+#define CIRRUS_MMIO_BLTDESTPITCH      0x0c     // word
+#define CIRRUS_MMIO_BLTSRCPITCH       0x0e     // word
+#define CIRRUS_MMIO_BLTDESTADDR       0x10     // dword
+#define CIRRUS_MMIO_BLTSRCADDR        0x14     // dword
+#define CIRRUS_MMIO_BLTWRITEMASK      0x17     // byte
+#define CIRRUS_MMIO_BLTMODE           0x18     // byte
+#define CIRRUS_MMIO_BLTROP            0x1a     // byte
+#define CIRRUS_MMIO_BLTMODEEXT        0x1b     // byte
+#define CIRRUS_MMIO_BLTTRANSPARENTCOLOR 0x1c   // word?
+#define CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK 0x20       // word?
+#define CIRRUS_MMIO_LINEARDRAW_START_X 0x24    // word
+#define CIRRUS_MMIO_LINEARDRAW_START_Y 0x26    // word
+#define CIRRUS_MMIO_LINEARDRAW_END_X  0x28     // word
+#define CIRRUS_MMIO_LINEARDRAW_END_Y  0x2a     // word
+#define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_INC 0x2c      // byte
+#define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_ROLLOVER 0x2d // byte
+#define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_MASK 0x2e     // byte
+#define CIRRUS_MMIO_LINEARDRAW_LINESTYLE_ACCUM 0x2f    // byte
+#define CIRRUS_MMIO_BRESENHAM_K1      0x30     // word
+#define CIRRUS_MMIO_BRESENHAM_K3      0x32     // word
+#define CIRRUS_MMIO_BRESENHAM_ERROR   0x34     // word
+#define CIRRUS_MMIO_BRESENHAM_DELTA_MAJOR 0x36 // word
+#define CIRRUS_MMIO_BRESENHAM_DIRECTION 0x38   // byte
+#define CIRRUS_MMIO_LINEDRAW_MODE     0x39     // byte
+#define CIRRUS_MMIO_BLTSTATUS         0x40     // byte
+
+// PCI 0x00: vendor, 0x02: device
+#define PCI_VENDOR_CIRRUS             0x1013
+#define PCI_DEVICE_CLGD5462           0x00d0
+#define PCI_DEVICE_CLGD5465           0x00d6
+
+// PCI 0x04: command(word), 0x06(word): status
+#define PCI_COMMAND_IOACCESS                0x0001
+#define PCI_COMMAND_MEMACCESS               0x0002
+#define PCI_COMMAND_BUSMASTER               0x0004
+#define PCI_COMMAND_SPECIALCYCLE            0x0008
+#define PCI_COMMAND_MEMWRITEINVALID         0x0010
+#define PCI_COMMAND_PALETTESNOOPING         0x0020
+#define PCI_COMMAND_PARITYDETECTION         0x0040
+#define PCI_COMMAND_ADDRESSDATASTEPPING     0x0080
+#define PCI_COMMAND_SERR                    0x0100
+#define PCI_COMMAND_BACKTOBACKTRANS         0x0200
+// PCI 0x08, 0xff000000 (0x09-0x0b:class,0x08:rev)
+#define PCI_CLASS_BASE_DISPLAY        0x03
+// PCI 0x08, 0x00ff0000
+#define PCI_CLASS_SUB_VGA             0x00
+// PCI 0x0c, 0x00ff0000 (0x0c:cacheline,0x0d:latency,0x0e:headertype,0x0f:Built-in self test)
+#define PCI_CLASS_HEADERTYPE_00h  0x00
+// 0x10-0x3f (headertype 00h)
+// PCI 0x10,0x14,0x18,0x1c,0x20,0x24: base address mapping registers
+//   0x10: MEMBASE, 0x14: IOBASE(hard-coded in XFree86 3.x)
+#define PCI_MAP_MEM                 0x0
+#define PCI_MAP_IO                  0x1
+#define PCI_MAP_MEM_ADDR_MASK       (~0xf)
+#define PCI_MAP_IO_ADDR_MASK        (~0x3)
+#define PCI_MAP_MEMFLAGS_32BIT      0x0
+#define PCI_MAP_MEMFLAGS_32BIT_1M   0x1
+#define PCI_MAP_MEMFLAGS_64BIT      0x4
+#define PCI_MAP_MEMFLAGS_CACHEABLE  0x8
+// PCI 0x28: cardbus CIS pointer
+// PCI 0x2c: subsystem vendor id, 0x2e: subsystem id
+// PCI 0x30: expansion ROM base address
+#define PCI_ROMBIOS_ENABLED         0x1
+// PCI 0x34: 0xffffff00=reserved, 0x000000ff=capabilities pointer
+// PCI 0x38: reserved
+// PCI 0x3c: 0x3c=int-line, 0x3d=int-pin, 0x3e=min-gnt, 0x3f=maax-lat
+
+#define CIRRUS_PNPMMIO_SIZE         0x1000
+
+
+/* I/O and memory hook */
+#define CIRRUS_HOOK_NOT_HANDLED 0
+#define CIRRUS_HOOK_HANDLED 1
+
+struct CirrusVGAState;
+typedef void (*cirrus_bitblt_rop_t) (struct CirrusVGAState *s,
+                                     uint8_t * dst, const uint8_t * src,
+                                    int dstpitch, int srcpitch,
+                                    int bltwidth, int bltheight);
+typedef void (*cirrus_fill_t)(struct CirrusVGAState *s,
+                              uint8_t *dst, int dst_pitch, int width, int height);
+
+typedef struct CirrusVGAState {
+    VGA_STATE_COMMON
+
+    int cirrus_linear_io_addr;
+    int cirrus_linear_bitblt_io_addr;
+    int cirrus_mmio_io_addr;
+    uint32_t cirrus_addr_mask;
+    uint32_t linear_mmio_mask;
+    uint8_t cirrus_shadow_gr0;
+    uint8_t cirrus_shadow_gr1;
+    uint8_t cirrus_hidden_dac_lockindex;
+    uint8_t cirrus_hidden_dac_data;
+    uint32_t cirrus_bank_base[2];
+    uint32_t cirrus_bank_limit[2];
+    uint8_t cirrus_hidden_palette[48];
+    uint32_t hw_cursor_x;
+    uint32_t hw_cursor_y;
+    int cirrus_blt_pixelwidth;
+    int cirrus_blt_width;
+    int cirrus_blt_height;
+    int cirrus_blt_dstpitch;
+    int cirrus_blt_srcpitch;
+    uint32_t cirrus_blt_fgcol;
+    uint32_t cirrus_blt_bgcol;
+    uint32_t cirrus_blt_dstaddr;
+    uint32_t cirrus_blt_srcaddr;
+    uint8_t cirrus_blt_mode;
+    uint8_t cirrus_blt_modeext;
+    cirrus_bitblt_rop_t cirrus_rop;
+#define CIRRUS_BLTBUFSIZE (2048 * 4) /* one line width */
+    uint8_t cirrus_bltbuf[CIRRUS_BLTBUFSIZE];
+    uint8_t *cirrus_srcptr;
+    uint8_t *cirrus_srcptr_end;
+    uint32_t cirrus_srccounter;
+    /* hwcursor display state */
+    int last_hw_cursor_size;
+    int last_hw_cursor_x;
+    int last_hw_cursor_y;
+    int last_hw_cursor_y_start;
+    int last_hw_cursor_y_end;
+    int real_vram_size; /* XXX: suppress that */
+    CPUWriteMemoryFunc **cirrus_linear_write;
+} CirrusVGAState;
+
+typedef struct PCICirrusVGAState {
+    PCIDevice dev;
+    CirrusVGAState cirrus_vga;
+} PCICirrusVGAState;
+
+static uint8_t rop_to_index[256];
+    
+/***************************************
+ *
+ *  prototypes.
+ *
+ ***************************************/
+
+
+static void cirrus_bitblt_reset(CirrusVGAState *s);
+static void cirrus_update_memory_access(CirrusVGAState *s);
+
+/***************************************
+ *
+ *  raster operations
+ *
+ ***************************************/
+
+static void cirrus_bitblt_rop_nop(CirrusVGAState *s,
+                                  uint8_t *dst,const uint8_t *src,
+                                  int dstpitch,int srcpitch,
+                                  int bltwidth,int bltheight)
+{
+}
+
+static void cirrus_bitblt_fill_nop(CirrusVGAState *s,
+                                   uint8_t *dst,
+                                   int dstpitch, int bltwidth,int bltheight)
+{
+}
+
+#define ROP_NAME 0
+#define ROP_OP(d, s) d = 0
+#include "cirrus_vga_rop.h"
+
+#define ROP_NAME src_and_dst
+#define ROP_OP(d, s) d = (s) & (d)
+#include "cirrus_vga_rop.h"
+
+#define ROP_NAME src_and_notdst
+#define ROP_OP(d, s) d = (s) & (~(d))
+#include "cirrus_vga_rop.h"
+
+#define ROP_NAME notdst
+#define ROP_OP(d, s) d = ~(d)
+#include "cirrus_vga_rop.h"
+
+#define ROP_NAME src
+#define ROP_OP(d, s) d = s
+#include "cirrus_vga_rop.h"
+
+#define ROP_NAME 1
+#define ROP_OP(d, s) d = ~0
+#include "cirrus_vga_rop.h"
+
+#define ROP_NAME notsrc_and_dst
+#define ROP_OP(d, s) d = (~(s)) & (d)
+#include "cirrus_vga_rop.h"
+
+#define ROP_NAME src_xor_dst
+#define ROP_OP(d, s) d = (s) ^ (d)
+#include "cirrus_vga_rop.h"
+
+#define ROP_NAME src_or_dst
+#define ROP_OP(d, s) d = (s) | (d)
+#include "cirrus_vga_rop.h"
+
+#define ROP_NAME notsrc_or_notdst
+#define ROP_OP(d, s) d = (~(s)) | (~(d))
+#include "cirrus_vga_rop.h"
+
+#define ROP_NAME src_notxor_dst
+#define ROP_OP(d, s) d = ~((s) ^ (d))
+#include "cirrus_vga_rop.h"
+
+#define ROP_NAME src_or_notdst
+#define ROP_OP(d, s) d = (s) | (~(d))
+#include "cirrus_vga_rop.h"
+
+#define ROP_NAME notsrc
+#define ROP_OP(d, s) d = (~(s))
+#include "cirrus_vga_rop.h"
+
+#define ROP_NAME notsrc_or_dst
+#define ROP_OP(d, s) d = (~(s)) | (d)
+#include "cirrus_vga_rop.h"
+
+#define ROP_NAME notsrc_and_notdst
+#define ROP_OP(d, s) d = (~(s)) & (~(d))
+#include "cirrus_vga_rop.h"
+
+static const cirrus_bitblt_rop_t cirrus_fwd_rop[16] = {
+    cirrus_bitblt_rop_fwd_0,
+    cirrus_bitblt_rop_fwd_src_and_dst,
+    cirrus_bitblt_rop_nop,
+    cirrus_bitblt_rop_fwd_src_and_notdst,
+    cirrus_bitblt_rop_fwd_notdst,
+    cirrus_bitblt_rop_fwd_src,
+    cirrus_bitblt_rop_fwd_1,
+    cirrus_bitblt_rop_fwd_notsrc_and_dst,
+    cirrus_bitblt_rop_fwd_src_xor_dst,
+    cirrus_bitblt_rop_fwd_src_or_dst,
+    cirrus_bitblt_rop_fwd_notsrc_or_notdst,
+    cirrus_bitblt_rop_fwd_src_notxor_dst,
+    cirrus_bitblt_rop_fwd_src_or_notdst,
+    cirrus_bitblt_rop_fwd_notsrc,
+    cirrus_bitblt_rop_fwd_notsrc_or_dst,
+    cirrus_bitblt_rop_fwd_notsrc_and_notdst,
+};
+
+static const cirrus_bitblt_rop_t cirrus_bkwd_rop[16] = {
+    cirrus_bitblt_rop_bkwd_0,
+    cirrus_bitblt_rop_bkwd_src_and_dst,
+    cirrus_bitblt_rop_nop,
+    cirrus_bitblt_rop_bkwd_src_and_notdst,
+    cirrus_bitblt_rop_bkwd_notdst,
+    cirrus_bitblt_rop_bkwd_src,
+    cirrus_bitblt_rop_bkwd_1,
+    cirrus_bitblt_rop_bkwd_notsrc_and_dst,
+    cirrus_bitblt_rop_bkwd_src_xor_dst,
+    cirrus_bitblt_rop_bkwd_src_or_dst,
+    cirrus_bitblt_rop_bkwd_notsrc_or_notdst,
+    cirrus_bitblt_rop_bkwd_src_notxor_dst,
+    cirrus_bitblt_rop_bkwd_src_or_notdst,
+    cirrus_bitblt_rop_bkwd_notsrc,
+    cirrus_bitblt_rop_bkwd_notsrc_or_dst,
+    cirrus_bitblt_rop_bkwd_notsrc_and_notdst,
+};
+    
+#define ROP2(name) {\
+    name ## _8,\
+    name ## _16,\
+    name ## _24,\
+    name ## _32,\
+        }
+
+#define ROP_NOP2(func) {\
+    func,\
+    func,\
+    func,\
+    func,\
+        }
+
+static const cirrus_bitblt_rop_t cirrus_patternfill[16][4] = {
+    ROP2(cirrus_patternfill_0),
+    ROP2(cirrus_patternfill_src_and_dst),
+    ROP_NOP2(cirrus_bitblt_rop_nop),
+    ROP2(cirrus_patternfill_src_and_notdst),
+    ROP2(cirrus_patternfill_notdst),
+    ROP2(cirrus_patternfill_src),
+    ROP2(cirrus_patternfill_1),
+    ROP2(cirrus_patternfill_notsrc_and_dst),
+    ROP2(cirrus_patternfill_src_xor_dst),
+    ROP2(cirrus_patternfill_src_or_dst),
+    ROP2(cirrus_patternfill_notsrc_or_notdst),
+    ROP2(cirrus_patternfill_src_notxor_dst),
+    ROP2(cirrus_patternfill_src_or_notdst),
+    ROP2(cirrus_patternfill_notsrc),
+    ROP2(cirrus_patternfill_notsrc_or_dst),
+    ROP2(cirrus_patternfill_notsrc_and_notdst),
+};
+
+static const cirrus_bitblt_rop_t cirrus_colorexpand_transp[16][4] = {
+    ROP2(cirrus_colorexpand_transp_0),
+    ROP2(cirrus_colorexpand_transp_src_and_dst),
+    ROP_NOP2(cirrus_bitblt_rop_nop),
+    ROP2(cirrus_colorexpand_transp_src_and_notdst),
+    ROP2(cirrus_colorexpand_transp_notdst),
+    ROP2(cirrus_colorexpand_transp_src),
+    ROP2(cirrus_colorexpand_transp_1),
+    ROP2(cirrus_colorexpand_transp_notsrc_and_dst),
+    ROP2(cirrus_colorexpand_transp_src_xor_dst),
+    ROP2(cirrus_colorexpand_transp_src_or_dst),
+    ROP2(cirrus_colorexpand_transp_notsrc_or_notdst),
+    ROP2(cirrus_colorexpand_transp_src_notxor_dst),
+    ROP2(cirrus_colorexpand_transp_src_or_notdst),
+    ROP2(cirrus_colorexpand_transp_notsrc),
+    ROP2(cirrus_colorexpand_transp_notsrc_or_dst),
+    ROP2(cirrus_colorexpand_transp_notsrc_and_notdst),
+};
+
+static const cirrus_bitblt_rop_t cirrus_colorexpand[16][4] = {
+    ROP2(cirrus_colorexpand_0),
+    ROP2(cirrus_colorexpand_src_and_dst),
+    ROP_NOP2(cirrus_bitblt_rop_nop),
+    ROP2(cirrus_colorexpand_src_and_notdst),
+    ROP2(cirrus_colorexpand_notdst),
+    ROP2(cirrus_colorexpand_src),
+    ROP2(cirrus_colorexpand_1),
+    ROP2(cirrus_colorexpand_notsrc_and_dst),
+    ROP2(cirrus_colorexpand_src_xor_dst),
+    ROP2(cirrus_colorexpand_src_or_dst),
+    ROP2(cirrus_colorexpand_notsrc_or_notdst),
+    ROP2(cirrus_colorexpand_src_notxor_dst),
+    ROP2(cirrus_colorexpand_src_or_notdst),
+    ROP2(cirrus_colorexpand_notsrc),
+    ROP2(cirrus_colorexpand_notsrc_or_dst),
+    ROP2(cirrus_colorexpand_notsrc_and_notdst),
+};
+
+static const cirrus_bitblt_rop_t cirrus_colorexpand_pattern_transp[16][4] = {
+    ROP2(cirrus_colorexpand_pattern_transp_0),
+    ROP2(cirrus_colorexpand_pattern_transp_src_and_dst),
+    ROP_NOP2(cirrus_bitblt_rop_nop),
+    ROP2(cirrus_colorexpand_pattern_transp_src_and_notdst),
+    ROP2(cirrus_colorexpand_pattern_transp_notdst),
+    ROP2(cirrus_colorexpand_pattern_transp_src),
+    ROP2(cirrus_colorexpand_pattern_transp_1),
+    ROP2(cirrus_colorexpand_pattern_transp_notsrc_and_dst),
+    ROP2(cirrus_colorexpand_pattern_transp_src_xor_dst),
+    ROP2(cirrus_colorexpand_pattern_transp_src_or_dst),
+    ROP2(cirrus_colorexpand_pattern_transp_notsrc_or_notdst),
+    ROP2(cirrus_colorexpand_pattern_transp_src_notxor_dst),
+    ROP2(cirrus_colorexpand_pattern_transp_src_or_notdst),
+    ROP2(cirrus_colorexpand_pattern_transp_notsrc),
+    ROP2(cirrus_colorexpand_pattern_transp_notsrc_or_dst),
+    ROP2(cirrus_colorexpand_pattern_transp_notsrc_and_notdst),
+};
+
+static const cirrus_bitblt_rop_t cirrus_colorexpand_pattern[16][4] = {
+    ROP2(cirrus_colorexpand_pattern_0),
+    ROP2(cirrus_colorexpand_pattern_src_and_dst),
+    ROP_NOP2(cirrus_bitblt_rop_nop),
+    ROP2(cirrus_colorexpand_pattern_src_and_notdst),
+    ROP2(cirrus_colorexpand_pattern_notdst),
+    ROP2(cirrus_colorexpand_pattern_src),
+    ROP2(cirrus_colorexpand_pattern_1),
+    ROP2(cirrus_colorexpand_pattern_notsrc_and_dst),
+    ROP2(cirrus_colorexpand_pattern_src_xor_dst),
+    ROP2(cirrus_colorexpand_pattern_src_or_dst),
+    ROP2(cirrus_colorexpand_pattern_notsrc_or_notdst),
+    ROP2(cirrus_colorexpand_pattern_src_notxor_dst),
+    ROP2(cirrus_colorexpand_pattern_src_or_notdst),
+    ROP2(cirrus_colorexpand_pattern_notsrc),
+    ROP2(cirrus_colorexpand_pattern_notsrc_or_dst),
+    ROP2(cirrus_colorexpand_pattern_notsrc_and_notdst),
+};
+
+static const cirrus_fill_t cirrus_fill[16][4] = {
+    ROP2(cirrus_fill_0),
+    ROP2(cirrus_fill_src_and_dst),
+    ROP_NOP2(cirrus_bitblt_fill_nop),
+    ROP2(cirrus_fill_src_and_notdst),
+    ROP2(cirrus_fill_notdst),
+    ROP2(cirrus_fill_src),
+    ROP2(cirrus_fill_1),
+    ROP2(cirrus_fill_notsrc_and_dst),
+    ROP2(cirrus_fill_src_xor_dst),
+    ROP2(cirrus_fill_src_or_dst),
+    ROP2(cirrus_fill_notsrc_or_notdst),
+    ROP2(cirrus_fill_src_notxor_dst),
+    ROP2(cirrus_fill_src_or_notdst),
+    ROP2(cirrus_fill_notsrc),
+    ROP2(cirrus_fill_notsrc_or_dst),
+    ROP2(cirrus_fill_notsrc_and_notdst),
+};
+
+static inline void cirrus_bitblt_fgcol(CirrusVGAState *s)
+{
+    unsigned int color;
+    switch (s->cirrus_blt_pixelwidth) {
+    case 1:
+        s->cirrus_blt_fgcol = s->cirrus_shadow_gr1;
+        break;
+    case 2:
+        color = s->cirrus_shadow_gr1 | (s->gr[0x11] << 8);
+        s->cirrus_blt_fgcol = le16_to_cpu(color);
+        break;
+    case 3:
+        s->cirrus_blt_fgcol = s->cirrus_shadow_gr1 | 
+            (s->gr[0x11] << 8) | (s->gr[0x13] << 16);
+        break;
+    default:
+    case 4:
+        color = s->cirrus_shadow_gr1 | (s->gr[0x11] << 8) |
+            (s->gr[0x13] << 16) | (s->gr[0x15] << 24);
+        s->cirrus_blt_fgcol = le32_to_cpu(color);
+        break;
+    }
+}
+
+static inline void cirrus_bitblt_bgcol(CirrusVGAState *s)
+{
+    unsigned int color;
+    switch (s->cirrus_blt_pixelwidth) {
+    case 1:
+        s->cirrus_blt_bgcol = s->cirrus_shadow_gr0;
+        break;
+    case 2:
+        color = s->cirrus_shadow_gr0 | (s->gr[0x10] << 8);
+        s->cirrus_blt_bgcol = le16_to_cpu(color);
+        break;
+    case 3:
+        s->cirrus_blt_bgcol = s->cirrus_shadow_gr0 | 
+            (s->gr[0x10] << 8) | (s->gr[0x12] << 16);
+        break;
+    default:
+    case 4:
+        color = s->cirrus_shadow_gr0 | (s->gr[0x10] << 8) |
+            (s->gr[0x12] << 16) | (s->gr[0x14] << 24);
+        s->cirrus_blt_bgcol = le32_to_cpu(color);
+        break;
+    }
+}
+
+static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin,
+                                    int off_pitch, int bytesperline,
+                                    int lines)
+{
+    int y;
+    int off_cur;
+    int off_cur_end;
+
+    for (y = 0; y < lines; y++) {
+       off_cur = off_begin;
+       off_cur_end = off_cur + bytesperline;
+       off_cur &= TARGET_PAGE_MASK;
+       while (off_cur < off_cur_end) {
+           cpu_physical_memory_set_dirty(s->vram_offset + off_cur);
+           off_cur += TARGET_PAGE_SIZE;
+       }
+       off_begin += off_pitch;
+    }
+}
+
+static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s,
+                                           const uint8_t * src)
+{
+    uint8_t *dst;
+
+    dst = s->vram_ptr + s->cirrus_blt_dstaddr;
+    (*s->cirrus_rop) (s, dst, src,
+                      s->cirrus_blt_dstpitch, 0, 
+                      s->cirrus_blt_width, s->cirrus_blt_height);
+    cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
+                             s->cirrus_blt_dstpitch, s->cirrus_blt_width,
+                             s->cirrus_blt_height);
+    return 1;
+}
+
+/* fill */
+
+static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop)
+{
+    cirrus_fill_t rop_func;
+
+    rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
+    rop_func(s, s->vram_ptr + s->cirrus_blt_dstaddr, 
+             s->cirrus_blt_dstpitch,
+             s->cirrus_blt_width, s->cirrus_blt_height);
+    cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
+                            s->cirrus_blt_dstpitch, s->cirrus_blt_width,
+                            s->cirrus_blt_height);
+    cirrus_bitblt_reset(s);
+    return 1;
+}
+
+/***************************************
+ *
+ *  bitblt (video-to-video)
+ *
+ ***************************************/
+
+static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s)
+{
+    return cirrus_bitblt_common_patterncopy(s,
+                                           s->vram_ptr + 
+                                            (s->cirrus_blt_srcaddr & ~7));
+}
+
+static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s)
+{
+    (*s->cirrus_rop) (s, s->vram_ptr + s->cirrus_blt_dstaddr,
+                     s->vram_ptr + s->cirrus_blt_srcaddr,
+                     s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch,
+                     s->cirrus_blt_width, s->cirrus_blt_height);
+    cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
+                            s->cirrus_blt_dstpitch, s->cirrus_blt_width,
+                            s->cirrus_blt_height);
+    return 1;
+}
+
+/***************************************
+ *
+ *  bitblt (cpu-to-video)
+ *
+ ***************************************/
+
+static void cirrus_bitblt_cputovideo_next(CirrusVGAState * s)
+{
+    int copy_count;
+    uint8_t *end_ptr;
+    
+    if (s->cirrus_srccounter > 0) {
+        if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
+            cirrus_bitblt_common_patterncopy(s, s->cirrus_bltbuf);
+        the_end:
+            s->cirrus_srccounter = 0;
+            cirrus_bitblt_reset(s);
+        } else {
+            /* at least one scan line */
+            do {
+                (*s->cirrus_rop)(s, s->vram_ptr + s->cirrus_blt_dstaddr,
+                                 s->cirrus_bltbuf, 0, 0, s->cirrus_blt_width, 1);
+                cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, 0,
+                                         s->cirrus_blt_width, 1);
+                s->cirrus_blt_dstaddr += s->cirrus_blt_dstpitch;
+                s->cirrus_srccounter -= s->cirrus_blt_srcpitch;
+                if (s->cirrus_srccounter <= 0)
+                    goto the_end;
+                /* more bytes than needed can be transfered because of
+                   word alignment, so we keep them for the next line */
+                /* XXX: keep alignment to speed up transfer */
+                end_ptr = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
+                copy_count = s->cirrus_srcptr_end - end_ptr;
+                memmove(s->cirrus_bltbuf, end_ptr, copy_count);
+                s->cirrus_srcptr = s->cirrus_bltbuf + copy_count;
+                s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
+            } while (s->cirrus_srcptr >= s->cirrus_srcptr_end);
+        }
+    }
+}
+
+/***************************************
+ *
+ *  bitblt wrapper
+ *
+ ***************************************/
+
+static void cirrus_bitblt_reset(CirrusVGAState * s)
+{
+    s->gr[0x31] &=
+       ~(CIRRUS_BLT_START | CIRRUS_BLT_BUSY | CIRRUS_BLT_FIFOUSED);
+    s->cirrus_srcptr = &s->cirrus_bltbuf[0];
+    s->cirrus_srcptr_end = &s->cirrus_bltbuf[0];
+    s->cirrus_srccounter = 0;
+    cirrus_update_memory_access(s);
+}
+
+static int cirrus_bitblt_cputovideo(CirrusVGAState * s)
+{
+    int w;
+
+    s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_MEMSYSSRC;
+    s->cirrus_srcptr = &s->cirrus_bltbuf[0];
+    s->cirrus_srcptr_end = &s->cirrus_bltbuf[0];
+
+    if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
+       if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
+           s->cirrus_blt_srcpitch = 8;
+       } else {
+            /* XXX: check for 24 bpp */
+           s->cirrus_blt_srcpitch = 8 * 8 * s->cirrus_blt_pixelwidth;
+       }
+       s->cirrus_srccounter = s->cirrus_blt_srcpitch;
+    } else {
+       if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
+            w = s->cirrus_blt_width / s->cirrus_blt_pixelwidth;
+            if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY) 
+                s->cirrus_blt_srcpitch = ((w + 31) >> 5);
+            else
+                s->cirrus_blt_srcpitch = ((w + 7) >> 3);
+       } else {
+           s->cirrus_blt_srcpitch = s->cirrus_blt_width;
+       }
+        s->cirrus_srccounter = s->cirrus_blt_srcpitch * s->cirrus_blt_height;
+    }
+    s->cirrus_srcptr = s->cirrus_bltbuf;
+    s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
+    cirrus_update_memory_access(s);
+    return 1;
+}
+
+static int cirrus_bitblt_videotocpu(CirrusVGAState * s)
+{
+    /* XXX */
+#ifdef DEBUG_BITBLT
+    printf("cirrus: bitblt (video to cpu) is not implemented yet\n");
+#endif
+    return 0;
+}
+
+static int cirrus_bitblt_videotovideo(CirrusVGAState * s)
+{
+    int ret;
+
+    if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
+       ret = cirrus_bitblt_videotovideo_patterncopy(s);
+    } else {
+       ret = cirrus_bitblt_videotovideo_copy(s);
+    }
+    if (ret)
+       cirrus_bitblt_reset(s);
+    return ret;
+}
+
+static void cirrus_bitblt_start(CirrusVGAState * s)
+{
+    uint8_t blt_rop;
+
+    s->gr[0x31] |= CIRRUS_BLT_BUSY;
+
+    s->cirrus_blt_width = (s->gr[0x20] | (s->gr[0x21] << 8)) + 1;
+    s->cirrus_blt_height = (s->gr[0x22] | (s->gr[0x23] << 8)) + 1;
+    s->cirrus_blt_dstpitch = (s->gr[0x24] | (s->gr[0x25] << 8));
+    s->cirrus_blt_srcpitch = (s->gr[0x26] | (s->gr[0x27] << 8));
+    s->cirrus_blt_dstaddr =
+       (s->gr[0x28] | (s->gr[0x29] << 8) | (s->gr[0x2a] << 16));
+    s->cirrus_blt_srcaddr =
+       (s->gr[0x2c] | (s->gr[0x2d] << 8) | (s->gr[0x2e] << 16));
+    s->cirrus_blt_mode = s->gr[0x30];
+    s->cirrus_blt_modeext = s->gr[0x33];
+    blt_rop = s->gr[0x32];
+
+#ifdef DEBUG_BITBLT
+    printf("rop=0x%02x mode=0x%02x modeext=0x%02x w=%d h=%d dpitch=%d spicth=%d daddr=0x%08x saddr=0x%08x writemask=0x%02x\n",
+           blt_rop, 
+           s->cirrus_blt_mode,
+           s->cirrus_blt_modeext,
+           s->cirrus_blt_width,
+           s->cirrus_blt_height,
+           s->cirrus_blt_dstpitch,
+           s->cirrus_blt_srcpitch,
+           s->cirrus_blt_dstaddr,
+           s->cirrus_blt_srcaddr,
+           s->sr[0x2f]);
+#endif
+
+    switch (s->cirrus_blt_mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) {
+    case CIRRUS_BLTMODE_PIXELWIDTH8:
+       s->cirrus_blt_pixelwidth = 1;
+       break;
+    case CIRRUS_BLTMODE_PIXELWIDTH16:
+       s->cirrus_blt_pixelwidth = 2;
+       break;
+    case CIRRUS_BLTMODE_PIXELWIDTH24:
+       s->cirrus_blt_pixelwidth = 3;
+       break;
+    case CIRRUS_BLTMODE_PIXELWIDTH32:
+       s->cirrus_blt_pixelwidth = 4;
+       break;
+    default:
+#ifdef DEBUG_BITBLT
+       printf("cirrus: bitblt - pixel width is unknown\n");
+#endif
+       goto bitblt_ignore;
+    }
+    s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_PIXELWIDTHMASK;
+
+    if ((s->
+        cirrus_blt_mode & (CIRRUS_BLTMODE_MEMSYSSRC |
+                           CIRRUS_BLTMODE_MEMSYSDEST))
+       == (CIRRUS_BLTMODE_MEMSYSSRC | CIRRUS_BLTMODE_MEMSYSDEST)) {
+#ifdef DEBUG_BITBLT
+       printf("cirrus: bitblt - memory-to-memory copy is requested\n");
+#endif
+       goto bitblt_ignore;
+    }
+
+    if ((s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_SOLIDFILL) &&
+        (s->cirrus_blt_mode & (CIRRUS_BLTMODE_MEMSYSDEST | 
+                               CIRRUS_BLTMODE_TRANSPARENTCOMP |
+                               CIRRUS_BLTMODE_PATTERNCOPY | 
+                               CIRRUS_BLTMODE_COLOREXPAND)) == 
+         (CIRRUS_BLTMODE_PATTERNCOPY | CIRRUS_BLTMODE_COLOREXPAND)) {
+        cirrus_bitblt_fgcol(s);
+        cirrus_bitblt_solidfill(s, blt_rop);
+    } else {
+        if ((s->cirrus_blt_mode & (CIRRUS_BLTMODE_COLOREXPAND | 
+                                   CIRRUS_BLTMODE_PATTERNCOPY)) == 
+            CIRRUS_BLTMODE_COLOREXPAND) {
+
+            if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) {
+                if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV)
+                    cirrus_bitblt_bgcol(s);
+                else
+                    cirrus_bitblt_fgcol(s);
+                s->cirrus_rop = cirrus_colorexpand_transp[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
+            } else {
+                cirrus_bitblt_fgcol(s);
+                cirrus_bitblt_bgcol(s);
+                s->cirrus_rop = cirrus_colorexpand[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
+            }
+        } else if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
+            if (s->cirrus_blt_mode & CIRRUS_BLTMODE_COLOREXPAND) {
+                if (s->cirrus_blt_mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) {
+                    if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV)
+                        cirrus_bitblt_bgcol(s);
+                    else
+                        cirrus_bitblt_fgcol(s);
+                    s->cirrus_rop = cirrus_colorexpand_pattern_transp[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
+                } else {
+                    cirrus_bitblt_fgcol(s);
+                    cirrus_bitblt_bgcol(s);
+                    s->cirrus_rop = cirrus_colorexpand_pattern[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
+                }
+            } else {
+                s->cirrus_rop = cirrus_patternfill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
+            }
+        } else {
+            if (s->cirrus_blt_mode & CIRRUS_BLTMODE_BACKWARDS) {
+                s->cirrus_blt_dstpitch = -s->cirrus_blt_dstpitch;
+                s->cirrus_blt_srcpitch = -s->cirrus_blt_srcpitch;
+                s->cirrus_rop = cirrus_bkwd_rop[rop_to_index[blt_rop]];
+            } else {
+                s->cirrus_rop = cirrus_fwd_rop[rop_to_index[blt_rop]];
+            }
+        }
+        
+        // setup bitblt engine.
+        if (s->cirrus_blt_mode & CIRRUS_BLTMODE_MEMSYSSRC) {
+            if (!cirrus_bitblt_cputovideo(s))
+                goto bitblt_ignore;
+        } else if (s->cirrus_blt_mode & CIRRUS_BLTMODE_MEMSYSDEST) {
+            if (!cirrus_bitblt_videotocpu(s))
+                goto bitblt_ignore;
+        } else {
+            if (!cirrus_bitblt_videotovideo(s))
+                goto bitblt_ignore;
+        }
+    }
+    return;
+  bitblt_ignore:;
+    cirrus_bitblt_reset(s);
+}
+
+static void cirrus_write_bitblt(CirrusVGAState * s, unsigned reg_value)
+{
+    unsigned old_value;
+
+    old_value = s->gr[0x31];
+    s->gr[0x31] = reg_value;
+
+    if (((old_value & CIRRUS_BLT_RESET) != 0) &&
+       ((reg_value & CIRRUS_BLT_RESET) == 0)) {
+       cirrus_bitblt_reset(s);
+    } else if (((old_value & CIRRUS_BLT_START) == 0) &&
+              ((reg_value & CIRRUS_BLT_START) != 0)) {
+       cirrus_bitblt_start(s);
+    }
+}
+
+
+/***************************************
+ *
+ *  basic parameters
+ *
+ ***************************************/
+
+static void cirrus_get_offsets(VGAState *s1, 
+                                   uint32_t *pline_offset,
+                                   uint32_t *pstart_addr)
+{
+    CirrusVGAState * s = (CirrusVGAState *)s1;
+    uint32_t start_addr;
+    uint32_t line_offset;
+
+    line_offset = s->cr[0x13]
+       | ((s->cr[0x1b] & 0x10) << 4);
+    line_offset <<= 3;
+    *pline_offset = line_offset;
+
+    start_addr = (s->cr[0x0c] << 8)
+       | s->cr[0x0d]
+       | ((s->cr[0x1b] & 0x01) << 16)
+       | ((s->cr[0x1b] & 0x0c) << 15)
+       | ((s->cr[0x1d] & 0x80) << 12);
+    *pstart_addr = start_addr;
+}
+
+static uint32_t cirrus_get_bpp16_depth(CirrusVGAState * s)
+{
+    uint32_t ret = 16;
+
+    switch (s->cirrus_hidden_dac_data & 0xf) {
+    case 0:
+       ret = 15;
+       break;                  /* Sierra HiColor */
+    case 1:
+       ret = 16;
+       break;                  /* XGA HiColor */
+    default:
+#ifdef DEBUG_CIRRUS
+       printf("cirrus: invalid DAC value %x in 16bpp\n",
+              (s->cirrus_hidden_dac_data & 0xf));
+#endif
+       ret = 15;               /* XXX */
+       break;
+    }
+    return ret;
+}
+
+static int cirrus_get_bpp(VGAState *s1)
+{
+    CirrusVGAState * s = (CirrusVGAState *)s1;
+    uint32_t ret = 8;
+
+    if ((s->sr[0x07] & 0x01) != 0) {
+       /* Cirrus SVGA */
+       switch (s->sr[0x07] & CIRRUS_SR7_BPP_MASK) {
+       case CIRRUS_SR7_BPP_8:
+           ret = 8;
+           break;
+       case CIRRUS_SR7_BPP_16_DOUBLEVCLK:
+           ret = cirrus_get_bpp16_depth(s);
+           break;
+       case CIRRUS_SR7_BPP_24:
+           ret = 24;
+           break;
+       case CIRRUS_SR7_BPP_16:
+           ret = cirrus_get_bpp16_depth(s);
+           break;
+       case CIRRUS_SR7_BPP_32:
+           ret = 32;
+           break;
+       default:
+#ifdef DEBUG_CIRRUS
+           printf("cirrus: unknown bpp - sr7=%x\n", s->sr[0x7]);
+#endif
+           ret = 8;
+           break;
+       }
+    } else {
+       /* VGA */
+       ret = 0;
+    }
+
+    return ret;
+}
+
+static void cirrus_get_resolution(VGAState *s, int *pwidth, int *pheight)
+{
+    int width, height;
+    
+    width = (s->cr[0x01] + 1) * 8;
+    height = s->cr[0x12] | 
+        ((s->cr[0x07] & 0x02) << 7) | 
+        ((s->cr[0x07] & 0x40) << 3);
+    height = (height + 1);
+    /* interlace support */
+    if (s->cr[0x1a] & 0x01)
+        height = height * 2;
+    *pwidth = width;
+    *pheight = height;
+}
+
+/***************************************
+ *
+ * bank memory
+ *
+ ***************************************/
+
+static void cirrus_update_bank_ptr(CirrusVGAState * s, unsigned bank_index)
+{
+    unsigned offset;
+    unsigned limit;
+
+    if ((s->gr[0x0b] & 0x01) != 0)     /* dual bank */
+       offset = s->gr[0x09 + bank_index];
+    else                       /* single bank */
+       offset = s->gr[0x09];
+
+    if ((s->gr[0x0b] & 0x20) != 0)
+       offset <<= 14;
+    else
+       offset <<= 12;
+
+    if (s->vram_size <= offset)
+       limit = 0;
+    else
+       limit = s->vram_size - offset;
+
+    if (((s->gr[0x0b] & 0x01) == 0) && (bank_index != 0)) {
+       if (limit > 0x8000) {
+           offset += 0x8000;
+           limit -= 0x8000;
+       } else {
+           limit = 0;
+       }
+    }
+
+    if (limit > 0) {
+       s->cirrus_bank_base[bank_index] = offset;
+       s->cirrus_bank_limit[bank_index] = limit;
+    } else {
+       s->cirrus_bank_base[bank_index] = 0;
+       s->cirrus_bank_limit[bank_index] = 0;
+    }
+}
+
+/***************************************
+ *
+ *  I/O access between 0x3c4-0x3c5
+ *
+ ***************************************/
+
+static int
+cirrus_hook_read_sr(CirrusVGAState * s, unsigned reg_index, int *reg_value)
+{
+    switch (reg_index) {
+    case 0x00:                 // Standard VGA
+    case 0x01:                 // Standard VGA
+    case 0x02:                 // Standard VGA
+    case 0x03:                 // Standard VGA
+    case 0x04:                 // Standard VGA
+       return CIRRUS_HOOK_NOT_HANDLED;
+    case 0x06:                 // Unlock Cirrus extensions
+       *reg_value = s->sr[reg_index];
+       break;
+    case 0x10:
+    case 0x30:
+    case 0x50:
+    case 0x70:                 // Graphics Cursor X
+    case 0x90:
+    case 0xb0:
+    case 0xd0:
+    case 0xf0:                 // Graphics Cursor X
+       *reg_value = s->sr[0x10];
+       break;
+    case 0x11:
+    case 0x31:
+    case 0x51:
+    case 0x71:                 // Graphics Cursor Y
+    case 0x91:
+    case 0xb1:
+    case 0xd1:
+    case 0xf1:                 // Graphics Cursor Y
+       *reg_value = s->sr[0x11];
+       break;
+    case 0x05:                 // ???
+    case 0x07:                 // Extended Sequencer Mode
+    case 0x08:                 // EEPROM Control
+    case 0x09:                 // Scratch Register 0
+    case 0x0a:                 // Scratch Register 1
+    case 0x0b:                 // VCLK 0
+    case 0x0c:                 // VCLK 1
+    case 0x0d:                 // VCLK 2
+    case 0x0e:                 // VCLK 3
+    case 0x0f:                 // DRAM Control
+    case 0x12:                 // Graphics Cursor Attribute
+    case 0x13:                 // Graphics Cursor Pattern Address
+    case 0x14:                 // Scratch Register 2
+    case 0x15:                 // Scratch Register 3
+    case 0x16:                 // Performance Tuning Register
+    case 0x17:                 // Configuration Readback and Extended Control
+    case 0x18:                 // Signature Generator Control
+    case 0x19:                 // Signal Generator Result
+    case 0x1a:                 // Signal Generator Result
+    case 0x1b:                 // VCLK 0 Denominator & Post
+    case 0x1c:                 // VCLK 1 Denominator & Post
+    case 0x1d:                 // VCLK 2 Denominator & Post
+    case 0x1e:                 // VCLK 3 Denominator & Post
+    case 0x1f:                 // BIOS Write Enable and MCLK select
+#ifdef DEBUG_CIRRUS
+       printf("cirrus: handled inport sr_index %02x\n", reg_index);
+#endif
+       *reg_value = s->sr[reg_index];
+       break;
+    default:
+#ifdef DEBUG_CIRRUS
+       printf("cirrus: inport sr_index %02x\n", reg_index);
+#endif
+       *reg_value = 0xff;
+       break;
+    }
+
+    return CIRRUS_HOOK_HANDLED;
+}
+
+static int
+cirrus_hook_write_sr(CirrusVGAState * s, unsigned reg_index, int reg_value)
+{
+    switch (reg_index) {
+    case 0x00:                 // Standard VGA
+    case 0x01:                 // Standard VGA
+    case 0x02:                 // Standard VGA
+    case 0x03:                 // Standard VGA
+    case 0x04:                 // Standard VGA
+       return CIRRUS_HOOK_NOT_HANDLED;
+    case 0x06:                 // Unlock Cirrus extensions
+       reg_value &= 0x17;
+       if (reg_value == 0x12) {
+           s->sr[reg_index] = 0x12;
+       } else {
+           s->sr[reg_index] = 0x0f;
+       }
+       break;
+    case 0x10:
+    case 0x30:
+    case 0x50:
+    case 0x70:                 // Graphics Cursor X
+    case 0x90:
+    case 0xb0:
+    case 0xd0:
+    case 0xf0:                 // Graphics Cursor X
+       s->sr[0x10] = reg_value;
+       s->hw_cursor_x = (reg_value << 3) | (reg_index >> 5);
+       break;
+    case 0x11:
+    case 0x31:
+    case 0x51:
+    case 0x71:                 // Graphics Cursor Y
+    case 0x91:
+    case 0xb1:
+    case 0xd1:
+    case 0xf1:                 // Graphics Cursor Y
+       s->sr[0x11] = reg_value;
+       s->hw_cursor_y = (reg_value << 3) | (reg_index >> 5);
+       break;
+    case 0x07:                 // Extended Sequencer Mode
+    case 0x08:                 // EEPROM Control
+    case 0x09:                 // Scratch Register 0
+    case 0x0a:                 // Scratch Register 1
+    case 0x0b:                 // VCLK 0
+    case 0x0c:                 // VCLK 1
+    case 0x0d:                 // VCLK 2
+    case 0x0e:                 // VCLK 3
+    case 0x0f:                 // DRAM Control
+    case 0x12:                 // Graphics Cursor Attribute
+    case 0x13:                 // Graphics Cursor Pattern Address
+    case 0x14:                 // Scratch Register 2
+    case 0x15:                 // Scratch Register 3
+    case 0x16:                 // Performance Tuning Register
+    case 0x18:                 // Signature Generator Control
+    case 0x19:                 // Signature Generator Result
+    case 0x1a:                 // Signature Generator Result
+    case 0x1b:                 // VCLK 0 Denominator & Post
+    case 0x1c:                 // VCLK 1 Denominator & Post
+    case 0x1d:                 // VCLK 2 Denominator & Post
+    case 0x1e:                 // VCLK 3 Denominator & Post
+    case 0x1f:                 // BIOS Write Enable and MCLK select
+       s->sr[reg_index] = reg_value;
+#ifdef DEBUG_CIRRUS
+       printf("cirrus: handled outport sr_index %02x, sr_value %02x\n",
+              reg_index, reg_value);
+#endif
+       break;
+    case 0x17:                 // Configuration Readback and Extended Control
+       s->sr[reg_index] = reg_value;
+        cirrus_update_memory_access(s);
+        break;
+    default:
+#ifdef DEBUG_CIRRUS
+       printf("cirrus: outport sr_index %02x, sr_value %02x\n", reg_index,
+              reg_value);
+#endif
+       break;
+    }
+
+    return CIRRUS_HOOK_HANDLED;
+}
+
+/***************************************
+ *
+ *  I/O access at 0x3c6
+ *
+ ***************************************/
+
+static void cirrus_read_hidden_dac(CirrusVGAState * s, int *reg_value)
+{
+    *reg_value = 0xff;
+    if (++s->cirrus_hidden_dac_lockindex == 5) {
+        *reg_value = s->cirrus_hidden_dac_data;
+       s->cirrus_hidden_dac_lockindex = 0;
+    }
+}
+
+static void cirrus_write_hidden_dac(CirrusVGAState * s, int reg_value)
+{
+    if (s->cirrus_hidden_dac_lockindex == 4) {
+       s->cirrus_hidden_dac_data = reg_value;
+#if defined(DEBUG_CIRRUS)
+       printf("cirrus: outport hidden DAC, value %02x\n", reg_value);
+#endif
+    }
+    s->cirrus_hidden_dac_lockindex = 0;
+}
+
+/***************************************
+ *
+ *  I/O access at 0x3c9
+ *
+ ***************************************/
+
+static int cirrus_hook_read_palette(CirrusVGAState * s, int *reg_value)
+{
+    if (!(s->sr[0x12] & CIRRUS_CURSOR_HIDDENPEL))
+       return CIRRUS_HOOK_NOT_HANDLED;
+    *reg_value =
+        s->cirrus_hidden_palette[(s->dac_read_index & 0x0f) * 3 +
+                                 s->dac_sub_index];
+    if (++s->dac_sub_index == 3) {
+       s->dac_sub_index = 0;
+       s->dac_read_index++;
+    }
+    return CIRRUS_HOOK_HANDLED;
+}
+
+static int cirrus_hook_write_palette(CirrusVGAState * s, int reg_value)
+{
+    if (!(s->sr[0x12] & CIRRUS_CURSOR_HIDDENPEL))
+       return CIRRUS_HOOK_NOT_HANDLED;
+    s->dac_cache[s->dac_sub_index] = reg_value;
+    if (++s->dac_sub_index == 3) {
+        memcpy(&s->cirrus_hidden_palette[(s->dac_write_index & 0x0f) * 3],
+               s->dac_cache, 3);
+        /* XXX update cursor */
+       s->dac_sub_index = 0;
+       s->dac_write_index++;
+    }
+    return CIRRUS_HOOK_HANDLED;
+}
+
+/***************************************
+ *
+ *  I/O access between 0x3ce-0x3cf
+ *
+ ***************************************/
+
+static int
+cirrus_hook_read_gr(CirrusVGAState * s, unsigned reg_index, int *reg_value)
+{
+    switch (reg_index) {
+    case 0x00: // Standard VGA, BGCOLOR 0x000000ff
+      *reg_value = s->cirrus_shadow_gr0;
+      return CIRRUS_HOOK_HANDLED;
+    case 0x01: // Standard VGA, FGCOLOR 0x000000ff
+      *reg_value = s->cirrus_shadow_gr1;
+      return CIRRUS_HOOK_HANDLED;
+    case 0x02:                 // Standard VGA
+    case 0x03:                 // Standard VGA
+    case 0x04:                 // Standard VGA
+    case 0x06:                 // Standard VGA
+    case 0x07:                 // Standard VGA
+    case 0x08:                 // Standard VGA
+       return CIRRUS_HOOK_NOT_HANDLED;
+    case 0x05:                 // Standard VGA, Cirrus extended mode
+    default:
+       break;
+    }
+
+    if (reg_index < 0x3a) {
+       *reg_value = s->gr[reg_index];
+    } else {
+#ifdef DEBUG_CIRRUS
+       printf("cirrus: inport gr_index %02x\n", reg_index);
+#endif
+       *reg_value = 0xff;
+    }
+
+    return CIRRUS_HOOK_HANDLED;
+}
+
+static int
+cirrus_hook_write_gr(CirrusVGAState * s, unsigned reg_index, int reg_value)
+{
+#if defined(DEBUG_BITBLT) && 0
+    printf("gr%02x: %02x\n", reg_index, reg_value);
+#endif
+    switch (reg_index) {
+    case 0x00:                 // Standard VGA, BGCOLOR 0x000000ff
+       s->cirrus_shadow_gr0 = reg_value;
+       return CIRRUS_HOOK_NOT_HANDLED;
+    case 0x01:                 // Standard VGA, FGCOLOR 0x000000ff
+       s->cirrus_shadow_gr1 = reg_value;
+       return CIRRUS_HOOK_NOT_HANDLED;
+    case 0x02:                 // Standard VGA
+    case 0x03:                 // Standard VGA
+    case 0x04:                 // Standard VGA
+    case 0x06:                 // Standard VGA
+    case 0x07:                 // Standard VGA
+    case 0x08:                 // Standard VGA
+       return CIRRUS_HOOK_NOT_HANDLED;
+    case 0x05:                 // Standard VGA, Cirrus extended mode
+       s->gr[reg_index] = reg_value & 0x7f;
+        cirrus_update_memory_access(s);
+       break;
+    case 0x09:                 // bank offset #0
+    case 0x0A:                 // bank offset #1
+       s->gr[reg_index] = reg_value;
+       cirrus_update_bank_ptr(s, 0);
+       cirrus_update_bank_ptr(s, 1);
+        break;
+    case 0x0B:
+       s->gr[reg_index] = reg_value;
+       cirrus_update_bank_ptr(s, 0);
+       cirrus_update_bank_ptr(s, 1);
+        cirrus_update_memory_access(s);
+       break;
+    case 0x10:                 // BGCOLOR 0x0000ff00
+    case 0x11:                 // FGCOLOR 0x0000ff00
+    case 0x12:                 // BGCOLOR 0x00ff0000
+    case 0x13:                 // FGCOLOR 0x00ff0000
+    case 0x14:                 // BGCOLOR 0xff000000
+    case 0x15:                 // FGCOLOR 0xff000000
+    case 0x20:                 // BLT WIDTH 0x0000ff
+    case 0x22:                 // BLT HEIGHT 0x0000ff
+    case 0x24:                 // BLT DEST PITCH 0x0000ff
+    case 0x26:                 // BLT SRC PITCH 0x0000ff
+    case 0x28:                 // BLT DEST ADDR 0x0000ff
+    case 0x29:                 // BLT DEST ADDR 0x00ff00
+    case 0x2c:                 // BLT SRC ADDR 0x0000ff
+    case 0x2d:                 // BLT SRC ADDR 0x00ff00
+    case 0x2f:                  // BLT WRITEMASK
+    case 0x30:                 // BLT MODE
+    case 0x32:                 // RASTER OP
+    case 0x33:                 // BLT MODEEXT
+    case 0x34:                 // BLT TRANSPARENT COLOR 0x00ff
+    case 0x35:                 // BLT TRANSPARENT COLOR 0xff00
+    case 0x38:                 // BLT TRANSPARENT COLOR MASK 0x00ff
+    case 0x39:                 // BLT TRANSPARENT COLOR MASK 0xff00
+       s->gr[reg_index] = reg_value;
+       break;
+    case 0x21:                 // BLT WIDTH 0x001f00
+    case 0x23:                 // BLT HEIGHT 0x001f00
+    case 0x25:                 // BLT DEST PITCH 0x001f00
+    case 0x27:                 // BLT SRC PITCH 0x001f00
+       s->gr[reg_index] = reg_value & 0x1f;
+       break;
+    case 0x2a:                 // BLT DEST ADDR 0x3f0000
+       s->gr[reg_index] = reg_value & 0x3f;
+        /* if auto start mode, starts bit blt now */
+        if (s->gr[0x31] & CIRRUS_BLT_AUTOSTART) {
+            cirrus_bitblt_start(s);
+        }
+       break;
+    case 0x2e:                 // BLT SRC ADDR 0x3f0000
+       s->gr[reg_index] = reg_value & 0x3f;
+       break;
+    case 0x31:                 // BLT STATUS/START
+       cirrus_write_bitblt(s, reg_value);
+       break;
+    default:
+#ifdef DEBUG_CIRRUS
+       printf("cirrus: outport gr_index %02x, gr_value %02x\n", reg_index,
+              reg_value);
+#endif
+       break;
+    }
+
+    return CIRRUS_HOOK_HANDLED;
+}
+
+/***************************************
+ *
+ *  I/O access between 0x3d4-0x3d5
+ *
+ ***************************************/
+
+static int
+cirrus_hook_read_cr(CirrusVGAState * s, unsigned reg_index, int *reg_value)
+{
+    switch (reg_index) {
+    case 0x00:                 // Standard VGA
+    case 0x01:                 // Standard VGA
+    case 0x02:                 // Standard VGA
+    case 0x03:                 // Standard VGA
+    case 0x04:                 // Standard VGA
+    case 0x05:                 // Standard VGA
+    case 0x06:                 // Standard VGA
+    case 0x07:                 // Standard VGA
+    case 0x08:                 // Standard VGA
+    case 0x09:                 // Standard VGA
+    case 0x0a:                 // Standard VGA
+    case 0x0b:                 // Standard VGA
+    case 0x0c:                 // Standard VGA
+    case 0x0d:                 // Standard VGA
+    case 0x0e:                 // Standard VGA
+    case 0x0f:                 // Standard VGA
+    case 0x10:                 // Standard VGA
+    case 0x11:                 // Standard VGA
+    case 0x12:                 // Standard VGA
+    case 0x13:                 // Standard VGA
+    case 0x14:                 // Standard VGA
+    case 0x15:                 // Standard VGA
+    case 0x16:                 // Standard VGA
+    case 0x17:                 // Standard VGA
+    case 0x18:                 // Standard VGA
+       return CIRRUS_HOOK_NOT_HANDLED;
+    case 0x19:                 // Interlace End
+    case 0x1a:                 // Miscellaneous Control
+    case 0x1b:                 // Extended Display Control
+    case 0x1c:                 // Sync Adjust and Genlock
+    case 0x1d:                 // Overlay Extended Control
+    case 0x22:                 // Graphics Data Latches Readback (R)
+    case 0x24:                 // Attribute Controller Toggle Readback (R)
+    case 0x25:                 // Part Status
+    case 0x27:                 // Part ID (R)
+       *reg_value = s->cr[reg_index];
+       break;
+    case 0x26:                 // Attribute Controller Index Readback (R)
+       *reg_value = s->ar_index & 0x3f;
+       break;
+    default:
+#ifdef DEBUG_CIRRUS
+       printf("cirrus: inport cr_index %02x\n", reg_index);
+       *reg_value = 0xff;
+#endif
+       break;
+    }
+
+    return CIRRUS_HOOK_HANDLED;
+}
+
+static int
+cirrus_hook_write_cr(CirrusVGAState * s, unsigned reg_index, int reg_value)
+{
+    switch (reg_index) {
+    case 0x00:                 // Standard VGA
+    case 0x01:                 // Standard VGA
+    case 0x02:                 // Standard VGA
+    case 0x03:                 // Standard VGA
+    case 0x04:                 // Standard VGA
+    case 0x05:                 // Standard VGA
+    case 0x06:                 // Standard VGA
+    case 0x07:                 // Standard VGA
+    case 0x08:                 // Standard VGA
+    case 0x09:                 // Standard VGA
+    case 0x0a:                 // Standard VGA
+    case 0x0b:                 // Standard VGA
+    case 0x0c:                 // Standard VGA
+    case 0x0d:                 // Standard VGA
+    case 0x0e:                 // Standard VGA
+    case 0x0f:                 // Standard VGA
+    case 0x10:                 // Standard VGA
+    case 0x11:                 // Standard VGA
+    case 0x12:                 // Standard VGA
+    case 0x13:                 // Standard VGA
+    case 0x14:                 // Standard VGA
+    case 0x15:                 // Standard VGA
+    case 0x16:                 // Standard VGA
+    case 0x17:                 // Standard VGA
+    case 0x18:                 // Standard VGA
+       return CIRRUS_HOOK_NOT_HANDLED;
+    case 0x19:                 // Interlace End
+    case 0x1a:                 // Miscellaneous Control
+    case 0x1b:                 // Extended Display Control
+    case 0x1c:                 // Sync Adjust and Genlock
+    case 0x1d:                 // Overlay Extended Control
+       s->cr[reg_index] = reg_value;
+#ifdef DEBUG_CIRRUS
+       printf("cirrus: handled outport cr_index %02x, cr_value %02x\n",
+              reg_index, reg_value);
+#endif
+       break;
+    case 0x22:                 // Graphics Data Latches Readback (R)
+    case 0x24:                 // Attribute Controller Toggle Readback (R)
+    case 0x26:                 // Attribute Controller Index Readback (R)
+    case 0x27:                 // Part ID (R)
+       break;
+    case 0x25:                 // Part Status
+    default:
+#ifdef DEBUG_CIRRUS
+       printf("cirrus: outport cr_index %02x, cr_value %02x\n", reg_index,
+              reg_value);
+#endif
+       break;
+    }
+
+    return CIRRUS_HOOK_HANDLED;
+}
+
+/***************************************
+ *
+ *  memory-mapped I/O (bitblt)
+ *
+ ***************************************/
+
+static uint8_t cirrus_mmio_blt_read(CirrusVGAState * s, unsigned address)
+{
+    int value = 0xff;
+
+    switch (address) {
+    case (CIRRUS_MMIO_BLTBGCOLOR + 0):
+       cirrus_hook_read_gr(s, 0x00, &value);
+       break;
+    case (CIRRUS_MMIO_BLTBGCOLOR + 1):
+       cirrus_hook_read_gr(s, 0x10, &value);
+       break;
+    case (CIRRUS_MMIO_BLTBGCOLOR + 2):
+       cirrus_hook_read_gr(s, 0x12, &value);
+       break;
+    case (CIRRUS_MMIO_BLTBGCOLOR + 3):
+       cirrus_hook_read_gr(s, 0x14, &value);
+       break;
+    case (CIRRUS_MMIO_BLTFGCOLOR + 0):
+       cirrus_hook_read_gr(s, 0x01, &value);
+       break;
+    case (CIRRUS_MMIO_BLTFGCOLOR + 1):
+       cirrus_hook_read_gr(s, 0x11, &value);
+       break;
+    case (CIRRUS_MMIO_BLTFGCOLOR + 2):
+       cirrus_hook_read_gr(s, 0x13, &value);
+       break;
+    case (CIRRUS_MMIO_BLTFGCOLOR + 3):
+       cirrus_hook_read_gr(s, 0x15, &value);
+       break;
+    case (CIRRUS_MMIO_BLTWIDTH + 0):
+       cirrus_hook_read_gr(s, 0x20, &value);
+       break;
+    case (CIRRUS_MMIO_BLTWIDTH + 1):
+       cirrus_hook_read_gr(s, 0x21, &value);
+       break;
+    case (CIRRUS_MMIO_BLTHEIGHT + 0):
+       cirrus_hook_read_gr(s, 0x22, &value);
+       break;
+    case (CIRRUS_MMIO_BLTHEIGHT + 1):
+       cirrus_hook_read_gr(s, 0x23, &value);
+       break;
+    case (CIRRUS_MMIO_BLTDESTPITCH + 0):
+       cirrus_hook_read_gr(s, 0x24, &value);
+       break;
+    case (CIRRUS_MMIO_BLTDESTPITCH + 1):
+       cirrus_hook_read_gr(s, 0x25, &value);
+       break;
+    case (CIRRUS_MMIO_BLTSRCPITCH + 0):
+       cirrus_hook_read_gr(s, 0x26, &value);
+       break;
+    case (CIRRUS_MMIO_BLTSRCPITCH + 1):
+       cirrus_hook_read_gr(s, 0x27, &value);
+       break;
+    case (CIRRUS_MMIO_BLTDESTADDR + 0):
+       cirrus_hook_read_gr(s, 0x28, &value);
+       break;
+    case (CIRRUS_MMIO_BLTDESTADDR + 1):
+       cirrus_hook_read_gr(s, 0x29, &value);
+       break;
+    case (CIRRUS_MMIO_BLTDESTADDR + 2):
+       cirrus_hook_read_gr(s, 0x2a, &value);
+       break;
+    case (CIRRUS_MMIO_BLTSRCADDR + 0):
+       cirrus_hook_read_gr(s, 0x2c, &value);
+       break;
+    case (CIRRUS_MMIO_BLTSRCADDR + 1):
+       cirrus_hook_read_gr(s, 0x2d, &value);
+       break;
+    case (CIRRUS_MMIO_BLTSRCADDR + 2):
+       cirrus_hook_read_gr(s, 0x2e, &value);
+       break;
+    case CIRRUS_MMIO_BLTWRITEMASK:
+       cirrus_hook_read_gr(s, 0x2f, &value);
+       break;
+    case CIRRUS_MMIO_BLTMODE:
+       cirrus_hook_read_gr(s, 0x30, &value);
+       break;
+    case CIRRUS_MMIO_BLTROP:
+       cirrus_hook_read_gr(s, 0x32, &value);
+       break;
+    case CIRRUS_MMIO_BLTMODEEXT:
+       cirrus_hook_read_gr(s, 0x33, &value);
+       break;
+    case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 0):
+       cirrus_hook_read_gr(s, 0x34, &value);
+       break;
+    case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 1):
+       cirrus_hook_read_gr(s, 0x35, &value);
+       break;
+    case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 0):
+       cirrus_hook_read_gr(s, 0x38, &value);
+       break;
+    case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 1):
+       cirrus_hook_read_gr(s, 0x39, &value);
+       break;
+    case CIRRUS_MMIO_BLTSTATUS:
+       cirrus_hook_read_gr(s, 0x31, &value);
+       break;
+    default:
+#ifdef DEBUG_CIRRUS
+       printf("cirrus: mmio read - address 0x%04x\n", address);
+#endif
+       break;
+    }
+
+    return (uint8_t) value;
+}
+
+static void cirrus_mmio_blt_write(CirrusVGAState * s, unsigned address,
+                                 uint8_t value)
+{
+    switch (address) {
+    case (CIRRUS_MMIO_BLTBGCOLOR + 0):
+       cirrus_hook_write_gr(s, 0x00, value);
+       break;
+    case (CIRRUS_MMIO_BLTBGCOLOR + 1):
+       cirrus_hook_write_gr(s, 0x10, value);
+       break;
+    case (CIRRUS_MMIO_BLTBGCOLOR + 2):
+       cirrus_hook_write_gr(s, 0x12, value);
+       break;
+    case (CIRRUS_MMIO_BLTBGCOLOR + 3):
+       cirrus_hook_write_gr(s, 0x14, value);
+       break;
+    case (CIRRUS_MMIO_BLTFGCOLOR + 0):
+       cirrus_hook_write_gr(s, 0x01, value);
+       break;
+    case (CIRRUS_MMIO_BLTFGCOLOR + 1):
+       cirrus_hook_write_gr(s, 0x11, value);
+       break;
+    case (CIRRUS_MMIO_BLTFGCOLOR + 2):
+       cirrus_hook_write_gr(s, 0x13, value);
+       break;
+    case (CIRRUS_MMIO_BLTFGCOLOR + 3):
+       cirrus_hook_write_gr(s, 0x15, value);
+       break;
+    case (CIRRUS_MMIO_BLTWIDTH + 0):
+       cirrus_hook_write_gr(s, 0x20, value);
+       break;
+    case (CIRRUS_MMIO_BLTWIDTH + 1):
+       cirrus_hook_write_gr(s, 0x21, value);
+       break;
+    case (CIRRUS_MMIO_BLTHEIGHT + 0):
+       cirrus_hook_write_gr(s, 0x22, value);
+       break;
+    case (CIRRUS_MMIO_BLTHEIGHT + 1):
+       cirrus_hook_write_gr(s, 0x23, value);
+       break;
+    case (CIRRUS_MMIO_BLTDESTPITCH + 0):
+       cirrus_hook_write_gr(s, 0x24, value);
+       break;
+    case (CIRRUS_MMIO_BLTDESTPITCH + 1):
+       cirrus_hook_write_gr(s, 0x25, value);
+       break;
+    case (CIRRUS_MMIO_BLTSRCPITCH + 0):
+       cirrus_hook_write_gr(s, 0x26, value);
+       break;
+    case (CIRRUS_MMIO_BLTSRCPITCH + 1):
+       cirrus_hook_write_gr(s, 0x27, value);
+       break;
+    case (CIRRUS_MMIO_BLTDESTADDR + 0):
+       cirrus_hook_write_gr(s, 0x28, value);
+       break;
+    case (CIRRUS_MMIO_BLTDESTADDR + 1):
+       cirrus_hook_write_gr(s, 0x29, value);
+       break;
+    case (CIRRUS_MMIO_BLTDESTADDR + 2):
+       cirrus_hook_write_gr(s, 0x2a, value);
+       break;
+    case (CIRRUS_MMIO_BLTDESTADDR + 3):
+       /* ignored */
+       break;
+    case (CIRRUS_MMIO_BLTSRCADDR + 0):
+       cirrus_hook_write_gr(s, 0x2c, value);
+       break;
+    case (CIRRUS_MMIO_BLTSRCADDR + 1):
+       cirrus_hook_write_gr(s, 0x2d, value);
+       break;
+    case (CIRRUS_MMIO_BLTSRCADDR + 2):
+       cirrus_hook_write_gr(s, 0x2e, value);
+       break;
+    case CIRRUS_MMIO_BLTWRITEMASK:
+       cirrus_hook_write_gr(s, 0x2f, value);
+       break;
+    case CIRRUS_MMIO_BLTMODE:
+       cirrus_hook_write_gr(s, 0x30, value);
+       break;
+    case CIRRUS_MMIO_BLTROP:
+       cirrus_hook_write_gr(s, 0x32, value);
+       break;
+    case CIRRUS_MMIO_BLTMODEEXT:
+       cirrus_hook_write_gr(s, 0x33, value);
+       break;
+    case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 0):
+       cirrus_hook_write_gr(s, 0x34, value);
+       break;
+    case (CIRRUS_MMIO_BLTTRANSPARENTCOLOR + 1):
+       cirrus_hook_write_gr(s, 0x35, value);
+       break;
+    case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 0):
+       cirrus_hook_write_gr(s, 0x38, value);
+       break;
+    case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 1):
+       cirrus_hook_write_gr(s, 0x39, value);
+       break;
+    case CIRRUS_MMIO_BLTSTATUS:
+       cirrus_hook_write_gr(s, 0x31, value);
+       break;
+    default:
+#ifdef DEBUG_CIRRUS
+       printf("cirrus: mmio write - addr 0x%04x val 0x%02x (ignored)\n",
+              address, value);
+#endif
+       break;
+    }
+}
+
+/***************************************
+ *
+ *  write mode 4/5
+ *
+ * assume TARGET_PAGE_SIZE >= 16
+ *
+ ***************************************/
+
+static void cirrus_mem_writeb_mode4and5_8bpp(CirrusVGAState * s,
+                                            unsigned mode,
+                                            unsigned offset,
+                                            uint32_t mem_value)
+{
+    int x;
+    unsigned val = mem_value;
+    uint8_t *dst;
+
+    dst = s->vram_ptr + offset;
+    for (x = 0; x < 8; x++) {
+       if (val & 0x80) {
+           *dst++ = s->cirrus_shadow_gr1;
+       } else if (mode == 5) {
+           *dst++ = s->cirrus_shadow_gr0;
+       }
+       val <<= 1;
+    }
+    cpu_physical_memory_set_dirty(s->vram_offset + offset);
+    cpu_physical_memory_set_dirty(s->vram_offset + offset + 7);
+}
+
+static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s,
+                                             unsigned mode,
+                                             unsigned offset,
+                                             uint32_t mem_value)
+{
+    int x;
+    unsigned val = mem_value;
+    uint8_t *dst;
+
+    dst = s->vram_ptr + offset;
+    for (x = 0; x < 8; x++) {
+       if (val & 0x80) {
+           *dst++ = s->cirrus_shadow_gr1;
+           *dst++ = s->gr[0x11];
+       } else if (mode == 5) {
+           *dst++ = s->cirrus_shadow_gr0;
+           *dst++ = s->gr[0x10];
+       }
+       val <<= 1;
+    }
+    cpu_physical_memory_set_dirty(s->vram_offset + offset);
+    cpu_physical_memory_set_dirty(s->vram_offset + offset + 15);
+}
+
+/***************************************
+ *
+ *  memory access between 0xa0000-0xbffff
+ *
+ ***************************************/
+
+static uint32_t cirrus_vga_mem_readb(void *opaque, target_phys_addr_t addr)
+{
+    CirrusVGAState *s = opaque;
+    unsigned bank_index;
+    unsigned bank_offset;
+    uint32_t val;
+
+    if ((s->sr[0x07] & 0x01) == 0) {
+       return vga_mem_readb(s, addr);
+    }
+
+    addr &= 0x1ffff;
+
+    if (addr < 0x10000) {
+       /* XXX handle bitblt */
+       /* video memory */
+       bank_index = addr >> 15;
+       bank_offset = addr & 0x7fff;
+       if (bank_offset < s->cirrus_bank_limit[bank_index]) {
+           bank_offset += s->cirrus_bank_base[bank_index];
+           if ((s->gr[0x0B] & 0x14) == 0x14) {
+               bank_offset <<= 4;
+           } else if (s->gr[0x0B] & 0x02) {
+               bank_offset <<= 3;
+           }
+           bank_offset &= s->cirrus_addr_mask;
+           val = *(s->vram_ptr + bank_offset);
+       } else
+           val = 0xff;
+    } else if (addr >= 0x18000 && addr < 0x18100) {
+       /* memory-mapped I/O */
+       val = 0xff;
+       if ((s->sr[0x17] & 0x44) == 0x04) {
+           val = cirrus_mmio_blt_read(s, addr & 0xff);
+       }
+    } else {
+       val = 0xff;
+#ifdef DEBUG_CIRRUS
+       printf("cirrus: mem_readb %06x\n", addr);
+#endif
+    }
+    return val;
+}
+
+static uint32_t cirrus_vga_mem_readw(void *opaque, target_phys_addr_t addr)
+{
+    uint32_t v;
+#ifdef TARGET_WORDS_BIGENDIAN
+    v = cirrus_vga_mem_readb(opaque, addr) << 8;
+    v |= cirrus_vga_mem_readb(opaque, addr + 1);
+#else
+    v = cirrus_vga_mem_readb(opaque, addr);
+    v |= cirrus_vga_mem_readb(opaque, addr + 1) << 8;
+#endif
+    return v;
+}
+
+static uint32_t cirrus_vga_mem_readl(void *opaque, target_phys_addr_t addr)
+{
+    uint32_t v;
+#ifdef TARGET_WORDS_BIGENDIAN
+    v = cirrus_vga_mem_readb(opaque, addr) << 24;
+    v |= cirrus_vga_mem_readb(opaque, addr + 1) << 16;
+    v |= cirrus_vga_mem_readb(opaque, addr + 2) << 8;
+    v |= cirrus_vga_mem_readb(opaque, addr + 3);
+#else
+    v = cirrus_vga_mem_readb(opaque, addr);
+    v |= cirrus_vga_mem_readb(opaque, addr + 1) << 8;
+    v |= cirrus_vga_mem_readb(opaque, addr + 2) << 16;
+    v |= cirrus_vga_mem_readb(opaque, addr + 3) << 24;
+#endif
+    return v;
+}
+
+static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr, 
+                                  uint32_t mem_value)
+{
+    CirrusVGAState *s = opaque;
+    unsigned bank_index;
+    unsigned bank_offset;
+    unsigned mode;
+
+    if ((s->sr[0x07] & 0x01) == 0) {
+       vga_mem_writeb(s, addr, mem_value);
+        return;
+    }
+
+    addr &= 0x1ffff;
+
+    if (addr < 0x10000) {
+       if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
+           /* bitblt */
+           *s->cirrus_srcptr++ = (uint8_t) mem_value;
+           if (s->cirrus_srcptr >= s->cirrus_srcptr_end) {
+               cirrus_bitblt_cputovideo_next(s);
+           }
+       } else {
+           /* video memory */
+           bank_index = addr >> 15;
+           bank_offset = addr & 0x7fff;
+           if (bank_offset < s->cirrus_bank_limit[bank_index]) {
+               bank_offset += s->cirrus_bank_base[bank_index];
+               if ((s->gr[0x0B] & 0x14) == 0x14) {
+                   bank_offset <<= 4;
+               } else if (s->gr[0x0B] & 0x02) {
+                   bank_offset <<= 3;
+               }
+               bank_offset &= s->cirrus_addr_mask;
+               mode = s->gr[0x05] & 0x7;
+               if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) {
+                   *(s->vram_ptr + bank_offset) = mem_value;
+                   cpu_physical_memory_set_dirty(s->vram_offset +
+                                                 bank_offset);
+               } else {
+                   if ((s->gr[0x0B] & 0x14) != 0x14) {
+                       cirrus_mem_writeb_mode4and5_8bpp(s, mode,
+                                                        bank_offset,
+                                                        mem_value);
+                   } else {
+                       cirrus_mem_writeb_mode4and5_16bpp(s, mode,
+                                                         bank_offset,
+                                                         mem_value);
+                   }
+               }
+           }
+       }
+    } else if (addr >= 0x18000 && addr < 0x18100) {
+       /* memory-mapped I/O */
+       if ((s->sr[0x17] & 0x44) == 0x04) {
+           cirrus_mmio_blt_write(s, addr & 0xff, mem_value);
+       }
+    } else {
+#ifdef DEBUG_CIRRUS
+       printf("cirrus: mem_writeb %06x value %02x\n", addr, mem_value);
+#endif
+    }
+}
+
+static void cirrus_vga_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
+{
+#ifdef TARGET_WORDS_BIGENDIAN
+    cirrus_vga_mem_writeb(opaque, addr, (val >> 8) & 0xff);
+    cirrus_vga_mem_writeb(opaque, addr + 1, val & 0xff);
+#else
+    cirrus_vga_mem_writeb(opaque, addr, val & 0xff);
+    cirrus_vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
+#endif
+}
+
+static void cirrus_vga_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
+{
+#ifdef TARGET_WORDS_BIGENDIAN
+    cirrus_vga_mem_writeb(opaque, addr, (val >> 24) & 0xff);
+    cirrus_vga_mem_writeb(opaque, addr + 1, (val >> 16) & 0xff);
+    cirrus_vga_mem_writeb(opaque, addr + 2, (val >> 8) & 0xff);
+    cirrus_vga_mem_writeb(opaque, addr + 3, val & 0xff);
+#else
+    cirrus_vga_mem_writeb(opaque, addr, val & 0xff);
+    cirrus_vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
+    cirrus_vga_mem_writeb(opaque, addr + 2, (val >> 16) & 0xff);
+    cirrus_vga_mem_writeb(opaque, addr + 3, (val >> 24) & 0xff);
+#endif
+}
+
+static CPUReadMemoryFunc *cirrus_vga_mem_read[3] = {
+    cirrus_vga_mem_readb,
+    cirrus_vga_mem_readw,
+    cirrus_vga_mem_readl,
+};
+
+static CPUWriteMemoryFunc *cirrus_vga_mem_write[3] = {
+    cirrus_vga_mem_writeb,
+    cirrus_vga_mem_writew,
+    cirrus_vga_mem_writel,
+};
+
+/***************************************
+ *
+ *  hardware cursor
+ *
+ ***************************************/
+
+static inline void invalidate_cursor1(CirrusVGAState *s)
+{
+    if (s->last_hw_cursor_size) {
+        vga_invalidate_scanlines((VGAState *)s, 
+                                 s->last_hw_cursor_y + s->last_hw_cursor_y_start,
+                                 s->last_hw_cursor_y + s->last_hw_cursor_y_end);
+    }
+}
+
+static inline void cirrus_cursor_compute_yrange(CirrusVGAState *s)
+{
+    const uint8_t *src;
+    uint32_t content;
+    int y, y_min, y_max;
+
+    src = s->vram_ptr + s->real_vram_size - 16 * 1024;
+    if (s->sr[0x12] & CIRRUS_CURSOR_LARGE) {
+        src += (s->sr[0x13] & 0x3c) * 256;
+        y_min = 64;
+        y_max = -1;
+        for(y = 0; y < 64; y++) {
+            content = ((uint32_t *)src)[0] |
+                ((uint32_t *)src)[1] |
+                ((uint32_t *)src)[2] |
+                ((uint32_t *)src)[3];
+            if (content) {
+                if (y < y_min)
+                    y_min = y;
+                if (y > y_max)
+                    y_max = y;
+            }
+            src += 16;
+        }
+    } else {
+        src += (s->sr[0x13] & 0x3f) * 256;
+        y_min = 32;
+        y_max = -1;
+        for(y = 0; y < 32; y++) {
+            content = ((uint32_t *)src)[0] |
+                ((uint32_t *)(src + 128))[0];
+            if (content) {
+                if (y < y_min)
+                    y_min = y;
+                if (y > y_max)
+                    y_max = y;
+            }
+            src += 4;
+        }
+    }
+    if (y_min > y_max) {
+        s->last_hw_cursor_y_start = 0;
+        s->last_hw_cursor_y_end = 0;
+    } else {
+        s->last_hw_cursor_y_start = y_min;
+        s->last_hw_cursor_y_end = y_max + 1;
+    }
+}
+
+/* NOTE: we do not currently handle the cursor bitmap change, so we
+   update the cursor only if it moves. */
+static void cirrus_cursor_invalidate(VGAState *s1)
+{
+    CirrusVGAState *s = (CirrusVGAState *)s1;
+    int size;
+
+    if (!s->sr[0x12] & CIRRUS_CURSOR_SHOW) {
+        size = 0;
+    } else {
+        if (s->sr[0x12] & CIRRUS_CURSOR_LARGE)
+            size = 64;
+        else
+            size = 32;
+    }
+    /* invalidate last cursor and new cursor if any change */
+    if (s->last_hw_cursor_size != size ||
+        s->last_hw_cursor_x != s->hw_cursor_x ||
+        s->last_hw_cursor_y != s->hw_cursor_y) {
+
+        invalidate_cursor1(s);
+        
+        s->last_hw_cursor_size = size;
+        s->last_hw_cursor_x = s->hw_cursor_x;
+        s->last_hw_cursor_y = s->hw_cursor_y;
+        /* compute the real cursor min and max y */
+        cirrus_cursor_compute_yrange(s);
+        invalidate_cursor1(s);
+    }
+}
+
+static void cirrus_cursor_draw_line(VGAState *s1, uint8_t *d1, int scr_y)
+{
+    CirrusVGAState *s = (CirrusVGAState *)s1;
+    int w, h, bpp, x1, x2, poffset;
+    unsigned int color0, color1;
+    const uint8_t *palette, *src;
+    uint32_t content;
+    
+    if (!(s->sr[0x12] & CIRRUS_CURSOR_SHOW)) 
+        return;
+    /* fast test to see if the cursor intersects with the scan line */
+    if (s->sr[0x12] & CIRRUS_CURSOR_LARGE) {
+        h = 64;
+    } else {
+        h = 32;
+    }
+    if (scr_y < s->hw_cursor_y ||
+        scr_y >= (s->hw_cursor_y + h))
+        return;
+    
+    src = s->vram_ptr + s->real_vram_size - 16 * 1024;
+    if (s->sr[0x12] & CIRRUS_CURSOR_LARGE) {
+        src += (s->sr[0x13] & 0x3c) * 256;
+        src += (scr_y - s->hw_cursor_y) * 16;
+        poffset = 8;
+        content = ((uint32_t *)src)[0] |
+            ((uint32_t *)src)[1] |
+            ((uint32_t *)src)[2] |
+            ((uint32_t *)src)[3];
+    } else {
+        src += (s->sr[0x13] & 0x3f) * 256;
+        src += (scr_y - s->hw_cursor_y) * 4;
+        poffset = 128;
+        content = ((uint32_t *)src)[0] |
+            ((uint32_t *)(src + 128))[0];
+    }
+    /* if nothing to draw, no need to continue */
+    if (!content)
+        return;
+    w = h;
+
+    x1 = s->hw_cursor_x;
+    if (x1 >= s->last_scr_width)
+        return;
+    x2 = s->hw_cursor_x + w;
+    if (x2 > s->last_scr_width)
+        x2 = s->last_scr_width;
+    w = x2 - x1;
+    palette = s->cirrus_hidden_palette;
+    color0 = s->rgb_to_pixel(c6_to_8(palette[0x0 * 3]), 
+                             c6_to_8(palette[0x0 * 3 + 1]), 
+                             c6_to_8(palette[0x0 * 3 + 2]));
+    color1 = s->rgb_to_pixel(c6_to_8(palette[0xf * 3]), 
+                             c6_to_8(palette[0xf * 3 + 1]), 
+                             c6_to_8(palette[0xf * 3 + 2]));
+    bpp = ((s->ds->depth + 7) >> 3);
+    d1 += x1 * bpp;
+    switch(s->ds->depth) {
+    default:
+        break;
+    case 8:
+        vga_draw_cursor_line_8(d1, src, poffset, w, color0, color1, 0xff);
+        break;
+    case 15:
+        vga_draw_cursor_line_16(d1, src, poffset, w, color0, color1, 0x7fff);
+        break;
+    case 16:
+        vga_draw_cursor_line_16(d1, src, poffset, w, color0, color1, 0xffff);
+        break;
+    case 32:
+        vga_draw_cursor_line_32(d1, src, poffset, w, color0, color1, 0xffffff);
+        break;
+    }
+}
+
+/***************************************
+ *
+ *  LFB memory access
+ *
+ ***************************************/
+
+static uint32_t cirrus_linear_readb(void *opaque, target_phys_addr_t addr)
+{
+    CirrusVGAState *s = (CirrusVGAState *) opaque;
+    uint32_t ret;
+
+    addr &= s->cirrus_addr_mask;
+
+    if (((s->sr[0x17] & 0x44) == 0x44) && 
+        ((addr & s->linear_mmio_mask) == s->linear_mmio_mask)) {
+       /* memory-mapped I/O */
+       ret = cirrus_mmio_blt_read(s, addr & 0xff);
+    } else if (0) {
+       /* XXX handle bitblt */
+       ret = 0xff;
+    } else {
+       /* video memory */
+       if ((s->gr[0x0B] & 0x14) == 0x14) {
+           addr <<= 4;
+       } else if (s->gr[0x0B] & 0x02) {
+           addr <<= 3;
+       }
+       addr &= s->cirrus_addr_mask;
+       ret = *(s->vram_ptr + addr);
+    }
+
+    return ret;
+}
+
+static uint32_t cirrus_linear_readw(void *opaque, target_phys_addr_t addr)
+{
+    uint32_t v;
+#ifdef TARGET_WORDS_BIGENDIAN
+    v = cirrus_linear_readb(opaque, addr) << 8;
+    v |= cirrus_linear_readb(opaque, addr + 1);
+#else
+    v = cirrus_linear_readb(opaque, addr);
+    v |= cirrus_linear_readb(opaque, addr + 1) << 8;
+#endif
+    return v;
+}
+
+static uint32_t cirrus_linear_readl(void *opaque, target_phys_addr_t addr)
+{
+    uint32_t v;
+#ifdef TARGET_WORDS_BIGENDIAN
+    v = cirrus_linear_readb(opaque, addr) << 24;
+    v |= cirrus_linear_readb(opaque, addr + 1) << 16;
+    v |= cirrus_linear_readb(opaque, addr + 2) << 8;
+    v |= cirrus_linear_readb(opaque, addr + 3);
+#else
+    v = cirrus_linear_readb(opaque, addr);
+    v |= cirrus_linear_readb(opaque, addr + 1) << 8;
+    v |= cirrus_linear_readb(opaque, addr + 2) << 16;
+    v |= cirrus_linear_readb(opaque, addr + 3) << 24;
+#endif
+    return v;
+}
+
+static void cirrus_linear_writeb(void *opaque, target_phys_addr_t addr,
+                                uint32_t val)
+{
+    CirrusVGAState *s = (CirrusVGAState *) opaque;
+    unsigned mode;
+
+    addr &= s->cirrus_addr_mask;
+        
+    if (((s->sr[0x17] & 0x44) == 0x44) && 
+        ((addr & s->linear_mmio_mask) ==  s->linear_mmio_mask)) {
+       /* memory-mapped I/O */
+       cirrus_mmio_blt_write(s, addr & 0xff, val);
+    } else if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
+       /* bitblt */
+       *s->cirrus_srcptr++ = (uint8_t) val;
+       if (s->cirrus_srcptr >= s->cirrus_srcptr_end) {
+           cirrus_bitblt_cputovideo_next(s);
+       }
+    } else {
+       /* video memory */
+       if ((s->gr[0x0B] & 0x14) == 0x14) {
+           addr <<= 4;
+       } else if (s->gr[0x0B] & 0x02) {
+           addr <<= 3;
+       }
+       addr &= s->cirrus_addr_mask;
+
+       mode = s->gr[0x05] & 0x7;
+       if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) {
+           *(s->vram_ptr + addr) = (uint8_t) val;
+           cpu_physical_memory_set_dirty(s->vram_offset + addr);
+       } else {
+           if ((s->gr[0x0B] & 0x14) != 0x14) {
+               cirrus_mem_writeb_mode4and5_8bpp(s, mode, addr, val);
+           } else {
+               cirrus_mem_writeb_mode4and5_16bpp(s, mode, addr, val);
+           }
+       }
+    }
+}
+
+static void cirrus_linear_writew(void *opaque, target_phys_addr_t addr,
+                                uint32_t val)
+{
+#ifdef TARGET_WORDS_BIGENDIAN
+    cirrus_linear_writeb(opaque, addr, (val >> 8) & 0xff);
+    cirrus_linear_writeb(opaque, addr + 1, val & 0xff);
+#else
+    cirrus_linear_writeb(opaque, addr, val & 0xff);
+    cirrus_linear_writeb(opaque, addr + 1, (val >> 8) & 0xff);
+#endif
+}
+
+static void cirrus_linear_writel(void *opaque, target_phys_addr_t addr,
+                                uint32_t val)
+{
+#ifdef TARGET_WORDS_BIGENDIAN
+    cirrus_linear_writeb(opaque, addr, (val >> 24) & 0xff);
+    cirrus_linear_writeb(opaque, addr + 1, (val >> 16) & 0xff);
+    cirrus_linear_writeb(opaque, addr + 2, (val >> 8) & 0xff);
+    cirrus_linear_writeb(opaque, addr + 3, val & 0xff);
+#else
+    cirrus_linear_writeb(opaque, addr, val & 0xff);
+    cirrus_linear_writeb(opaque, addr + 1, (val >> 8) & 0xff);
+    cirrus_linear_writeb(opaque, addr + 2, (val >> 16) & 0xff);
+    cirrus_linear_writeb(opaque, addr + 3, (val >> 24) & 0xff);
+#endif
+}
+
+
+static CPUReadMemoryFunc *cirrus_linear_read[3] = {
+    cirrus_linear_readb,
+    cirrus_linear_readw,
+    cirrus_linear_readl,
+};
+
+static CPUWriteMemoryFunc *cirrus_linear_write[3] = {
+    cirrus_linear_writeb,
+    cirrus_linear_writew,
+    cirrus_linear_writel,
+};
+
+static void cirrus_linear_mem_writeb(void *opaque, target_phys_addr_t addr,
+                                     uint32_t val)
+{
+    CirrusVGAState *s = (CirrusVGAState *) opaque;
+
+    addr &= s->cirrus_addr_mask;
+    *(s->vram_ptr + addr) = val;
+    cpu_physical_memory_set_dirty(s->vram_offset + addr);
+}
+
+static void cirrus_linear_mem_writew(void *opaque, target_phys_addr_t addr,
+                                     uint32_t val)
+{
+    CirrusVGAState *s = (CirrusVGAState *) opaque;
+
+    addr &= s->cirrus_addr_mask;
+    cpu_to_le16w((uint16_t *)(s->vram_ptr + addr), val);
+    cpu_physical_memory_set_dirty(s->vram_offset + addr);
+}
+
+static void cirrus_linear_mem_writel(void *opaque, target_phys_addr_t addr,
+                                     uint32_t val)
+{
+    CirrusVGAState *s = (CirrusVGAState *) opaque;
+
+    addr &= s->cirrus_addr_mask;
+    cpu_to_le32w((uint32_t *)(s->vram_ptr + addr), val);
+    cpu_physical_memory_set_dirty(s->vram_offset + addr);
+}
+
+/***************************************
+ *
+ *  system to screen memory access
+ *
+ ***************************************/
+
+
+static uint32_t cirrus_linear_bitblt_readb(void *opaque, target_phys_addr_t addr)
+{
+    uint32_t ret;
+
+    /* XXX handle bitblt */
+    ret = 0xff;
+    return ret;
+}
+
+static uint32_t cirrus_linear_bitblt_readw(void *opaque, target_phys_addr_t addr)
+{
+    uint32_t v;
+#ifdef TARGET_WORDS_BIGENDIAN
+    v = cirrus_linear_bitblt_readb(opaque, addr) << 8;
+    v |= cirrus_linear_bitblt_readb(opaque, addr + 1);
+#else
+    v = cirrus_linear_bitblt_readb(opaque, addr);
+    v |= cirrus_linear_bitblt_readb(opaque, addr + 1) << 8;
+#endif
+    return v;
+}
+
+static uint32_t cirrus_linear_bitblt_readl(void *opaque, target_phys_addr_t addr)
+{
+    uint32_t v;
+#ifdef TARGET_WORDS_BIGENDIAN
+    v = cirrus_linear_bitblt_readb(opaque, addr) << 24;
+    v |= cirrus_linear_bitblt_readb(opaque, addr + 1) << 16;
+    v |= cirrus_linear_bitblt_readb(opaque, addr + 2) << 8;
+    v |= cirrus_linear_bitblt_readb(opaque, addr + 3);
+#else
+    v = cirrus_linear_bitblt_readb(opaque, addr);
+    v |= cirrus_linear_bitblt_readb(opaque, addr + 1) << 8;
+    v |= cirrus_linear_bitblt_readb(opaque, addr + 2) << 16;
+    v |= cirrus_linear_bitblt_readb(opaque, addr + 3) << 24;
+#endif
+    return v;
+}
+
+static void cirrus_linear_bitblt_writeb(void *opaque, target_phys_addr_t addr,
+                                uint32_t val)
+{
+    CirrusVGAState *s = (CirrusVGAState *) opaque;
+
+    if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
+       /* bitblt */
+       *s->cirrus_srcptr++ = (uint8_t) val;
+       if (s->cirrus_srcptr >= s->cirrus_srcptr_end) {
+           cirrus_bitblt_cputovideo_next(s);
+       }
+    }
+}
+
+static void cirrus_linear_bitblt_writew(void *opaque, target_phys_addr_t addr,
+                                uint32_t val)
+{
+#ifdef TARGET_WORDS_BIGENDIAN
+    cirrus_linear_bitblt_writeb(opaque, addr, (val >> 8) & 0xff);
+    cirrus_linear_bitblt_writeb(opaque, addr + 1, val & 0xff);
+#else
+    cirrus_linear_bitblt_writeb(opaque, addr, val & 0xff);
+    cirrus_linear_bitblt_writeb(opaque, addr + 1, (val >> 8) & 0xff);
+#endif
+}
+
+static void cirrus_linear_bitblt_writel(void *opaque, target_phys_addr_t addr,
+                                uint32_t val)
+{
+#ifdef TARGET_WORDS_BIGENDIAN
+    cirrus_linear_bitblt_writeb(opaque, addr, (val >> 24) & 0xff);
+    cirrus_linear_bitblt_writeb(opaque, addr + 1, (val >> 16) & 0xff);
+    cirrus_linear_bitblt_writeb(opaque, addr + 2, (val >> 8) & 0xff);
+    cirrus_linear_bitblt_writeb(opaque, addr + 3, val & 0xff);
+#else
+    cirrus_linear_bitblt_writeb(opaque, addr, val & 0xff);
+    cirrus_linear_bitblt_writeb(opaque, addr + 1, (val >> 8) & 0xff);
+    cirrus_linear_bitblt_writeb(opaque, addr + 2, (val >> 16) & 0xff);
+    cirrus_linear_bitblt_writeb(opaque, addr + 3, (val >> 24) & 0xff);
+#endif
+}
+
+
+static CPUReadMemoryFunc *cirrus_linear_bitblt_read[3] = {
+    cirrus_linear_bitblt_readb,
+    cirrus_linear_bitblt_readw,
+    cirrus_linear_bitblt_readl,
+};
+
+static CPUWriteMemoryFunc *cirrus_linear_bitblt_write[3] = {
+    cirrus_linear_bitblt_writeb,
+    cirrus_linear_bitblt_writew,
+    cirrus_linear_bitblt_writel,
+};
+
+/* Compute the memory access functions */
+static void cirrus_update_memory_access(CirrusVGAState *s)
+{
+    unsigned mode;
+
+    if ((s->sr[0x17] & 0x44) == 0x44) {
+        goto generic_io;
+    } else if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
+        goto generic_io;
+    } else {
+       if ((s->gr[0x0B] & 0x14) == 0x14) {
+            goto generic_io;
+       } else if (s->gr[0x0B] & 0x02) {
+            goto generic_io;
+        }
+        
+       mode = s->gr[0x05] & 0x7;
+       if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) {
+            s->cirrus_linear_write[0] = cirrus_linear_mem_writeb;
+            s->cirrus_linear_write[1] = cirrus_linear_mem_writew;
+            s->cirrus_linear_write[2] = cirrus_linear_mem_writel;
+        } else {
+        generic_io:
+            s->cirrus_linear_write[0] = cirrus_linear_writeb;
+            s->cirrus_linear_write[1] = cirrus_linear_writew;
+            s->cirrus_linear_write[2] = cirrus_linear_writel;
+        }
+    }
+}
+
+
+/* I/O ports */
+
+static uint32_t vga_ioport_read(void *opaque, uint32_t addr)
+{
+    CirrusVGAState *s = opaque;
+    int val, index;
+
+    /* check port range access depending on color/monochrome mode */
+    if ((addr >= 0x3b0 && addr <= 0x3bf && (s->msr & MSR_COLOR_EMULATION))
+       || (addr >= 0x3d0 && addr <= 0x3df
+           && !(s->msr & MSR_COLOR_EMULATION))) {
+       val = 0xff;
+    } else {
+       switch (addr) {
+       case 0x3c0:
+           if (s->ar_flip_flop == 0) {
+               val = s->ar_index;
+           } else {
+               val = 0;
+           }
+           break;
+       case 0x3c1:
+           index = s->ar_index & 0x1f;
+           if (index < 21)
+               val = s->ar[index];
+           else
+               val = 0;
+           break;
+       case 0x3c2:
+           val = s->st00;
+           break;
+       case 0x3c4:
+           val = s->sr_index;
+           break;
+       case 0x3c5:
+           if (cirrus_hook_read_sr(s, s->sr_index, &val))
+               break;
+           val = s->sr[s->sr_index];
+#ifdef DEBUG_VGA_REG
+           printf("vga: read SR%x = 0x%02x\n", s->sr_index, val);
+#endif
+           break;
+       case 0x3c6:
+           cirrus_read_hidden_dac(s, &val);
+           break;
+       case 0x3c7:
+           val = s->dac_state;
+           break;
+       case 0x3c8:
+           val = s->dac_write_index;
+           s->cirrus_hidden_dac_lockindex = 0;
+           break;
+        case 0x3c9:
+           if (cirrus_hook_read_palette(s, &val))
+               break;
+           val = s->palette[s->dac_read_index * 3 + s->dac_sub_index];
+           if (++s->dac_sub_index == 3) {
+               s->dac_sub_index = 0;
+               s->dac_read_index++;
+           }
+           break;
+       case 0x3ca:
+           val = s->fcr;
+           break;
+       case 0x3cc:
+           val = s->msr;
+           break;
+       case 0x3ce:
+           val = s->gr_index;
+           break;
+       case 0x3cf:
+           if (cirrus_hook_read_gr(s, s->gr_index, &val))
+               break;
+           val = s->gr[s->gr_index];
+#ifdef DEBUG_VGA_REG
+           printf("vga: read GR%x = 0x%02x\n", s->gr_index, val);
+#endif
+           break;
+       case 0x3b4:
+       case 0x3d4:
+           val = s->cr_index;
+           break;
+       case 0x3b5:
+       case 0x3d5:
+           if (cirrus_hook_read_cr(s, s->cr_index, &val))
+               break;
+           val = s->cr[s->cr_index];
+#ifdef DEBUG_VGA_REG
+           printf("vga: read CR%x = 0x%02x\n", s->cr_index, val);
+#endif
+           break;
+       case 0x3ba:
+       case 0x3da:
+           /* just toggle to fool polling */
+           s->st01 ^= ST01_V_RETRACE | ST01_DISP_ENABLE;
+           val = s->st01;
+           s->ar_flip_flop = 0;
+           break;
+       default:
+           val = 0x00;
+           break;
+       }
+    }
+#if defined(DEBUG_VGA)
+    printf("VGA: read addr=0x%04x data=0x%02x\n", addr, val);
+#endif
+    return val;
+}
+
+static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+{
+    CirrusVGAState *s = opaque;
+    int index;
+
+    /* check port range access depending on color/monochrome mode */
+    if ((addr >= 0x3b0 && addr <= 0x3bf && (s->msr & MSR_COLOR_EMULATION))
+       || (addr >= 0x3d0 && addr <= 0x3df
+           && !(s->msr & MSR_COLOR_EMULATION)))
+       return;
+
+#ifdef DEBUG_VGA
+    printf("VGA: write addr=0x%04x data=0x%02x\n", addr, val);
+#endif
+
+    switch (addr) {
+    case 0x3c0:
+       if (s->ar_flip_flop == 0) {
+           val &= 0x3f;
+           s->ar_index = val;
+       } else {
+           index = s->ar_index & 0x1f;
+           switch (index) {
+           case 0x00 ... 0x0f:
+               s->ar[index] = val & 0x3f;
+               break;
+           case 0x10:
+               s->ar[index] = val & ~0x10;
+               break;
+           case 0x11:
+               s->ar[index] = val;
+               break;
+           case 0x12:
+               s->ar[index] = val & ~0xc0;
+               break;
+           case 0x13:
+               s->ar[index] = val & ~0xf0;
+               break;
+           case 0x14:
+               s->ar[index] = val & ~0xf0;
+               break;
+           default:
+               break;
+           }
+       }
+       s->ar_flip_flop ^= 1;
+       break;
+    case 0x3c2:
+       s->msr = val & ~0x10;
+       break;
+    case 0x3c4:
+       s->sr_index = val;
+       break;
+    case 0x3c5:
+       if (cirrus_hook_write_sr(s, s->sr_index, val))
+           break;
+#ifdef DEBUG_VGA_REG
+       printf("vga: write SR%x = 0x%02x\n", s->sr_index, val);
+#endif
+       s->sr[s->sr_index] = val & sr_mask[s->sr_index];
+       break;
+    case 0x3c6:
+       cirrus_write_hidden_dac(s, val);
+       break;
+    case 0x3c7:
+       s->dac_read_index = val;
+       s->dac_sub_index = 0;
+       s->dac_state = 3;
+       break;
+    case 0x3c8:
+       s->dac_write_index = val;
+       s->dac_sub_index = 0;
+       s->dac_state = 0;
+       break;
+    case 0x3c9:
+       if (cirrus_hook_write_palette(s, val))
+           break;
+       s->dac_cache[s->dac_sub_index] = val;
+       if (++s->dac_sub_index == 3) {
+           memcpy(&s->palette[s->dac_write_index * 3], s->dac_cache, 3);
+           s->dac_sub_index = 0;
+           s->dac_write_index++;
+       }
+       break;
+    case 0x3ce:
+       s->gr_index = val;
+       break;
+    case 0x3cf:
+       if (cirrus_hook_write_gr(s, s->gr_index, val))
+           break;
+#ifdef DEBUG_VGA_REG
+       printf("vga: write GR%x = 0x%02x\n", s->gr_index, val);
+#endif
+       s->gr[s->gr_index] = val & gr_mask[s->gr_index];
+       break;
+    case 0x3b4:
+    case 0x3d4:
+       s->cr_index = val;
+       break;
+    case 0x3b5:
+    case 0x3d5:
+       if (cirrus_hook_write_cr(s, s->cr_index, val))
+           break;
+#ifdef DEBUG_VGA_REG
+       printf("vga: write CR%x = 0x%02x\n", s->cr_index, val);
+#endif
+       /* handle CR0-7 protection */
+       if ((s->cr[0x11] & 0x80) && s->cr_index <= 7) {
+           /* can always write bit 4 of CR7 */
+           if (s->cr_index == 7)
+               s->cr[7] = (s->cr[7] & ~0x10) | (val & 0x10);
+           return;
+       }
+       switch (s->cr_index) {
+       case 0x01:              /* horizontal display end */
+       case 0x07:
+       case 0x09:
+       case 0x0c:
+       case 0x0d:
+       case 0x12:              /* veritcal display end */
+           s->cr[s->cr_index] = val;
+           break;
+
+       default:
+           s->cr[s->cr_index] = val;
+           break;
+       }
+       break;
+    case 0x3ba:
+    case 0x3da:
+       s->fcr = val & 0x10;
+       break;
+    }
+}
+
+/***************************************
+ *
+ *  memory-mapped I/O access
+ *
+ ***************************************/
+
+static uint32_t cirrus_mmio_readb(void *opaque, target_phys_addr_t addr)
+{
+    CirrusVGAState *s = (CirrusVGAState *) opaque;
+
+    addr &= CIRRUS_PNPMMIO_SIZE - 1;
+
+    if (addr >= 0x100) {
+        return cirrus_mmio_blt_read(s, addr - 0x100);
+    } else {
+        return vga_ioport_read(s, addr + 0x3c0);
+    }
+}
+
+static uint32_t cirrus_mmio_readw(void *opaque, target_phys_addr_t addr)
+{
+    uint32_t v;
+#ifdef TARGET_WORDS_BIGENDIAN
+    v = cirrus_mmio_readb(opaque, addr) << 8;
+    v |= cirrus_mmio_readb(opaque, addr + 1);
+#else
+    v = cirrus_mmio_readb(opaque, addr);
+    v |= cirrus_mmio_readb(opaque, addr + 1) << 8;
+#endif
+    return v;
+}
+
+static uint32_t cirrus_mmio_readl(void *opaque, target_phys_addr_t addr)
+{
+    uint32_t v;
+#ifdef TARGET_WORDS_BIGENDIAN
+    v = cirrus_mmio_readb(opaque, addr) << 24;
+    v |= cirrus_mmio_readb(opaque, addr + 1) << 16;
+    v |= cirrus_mmio_readb(opaque, addr + 2) << 8;
+    v |= cirrus_mmio_readb(opaque, addr + 3);
+#else
+    v = cirrus_mmio_readb(opaque, addr);
+    v |= cirrus_mmio_readb(opaque, addr + 1) << 8;
+    v |= cirrus_mmio_readb(opaque, addr + 2) << 16;
+    v |= cirrus_mmio_readb(opaque, addr + 3) << 24;
+#endif
+    return v;
+}
+
+static void cirrus_mmio_writeb(void *opaque, target_phys_addr_t addr,
+                              uint32_t val)
+{
+    CirrusVGAState *s = (CirrusVGAState *) opaque;
+
+    addr &= CIRRUS_PNPMMIO_SIZE - 1;
+
+    if (addr >= 0x100) {
+       cirrus_mmio_blt_write(s, addr - 0x100, val);
+    } else {
+        vga_ioport_write(s, addr + 0x3c0, val);
+    }
+}
+
+static void cirrus_mmio_writew(void *opaque, target_phys_addr_t addr,
+                              uint32_t val)
+{
+#ifdef TARGET_WORDS_BIGENDIAN
+    cirrus_mmio_writeb(opaque, addr, (val >> 8) & 0xff);
+    cirrus_mmio_writeb(opaque, addr + 1, val & 0xff);
+#else
+    cirrus_mmio_writeb(opaque, addr, val & 0xff);
+    cirrus_mmio_writeb(opaque, addr + 1, (val >> 8) & 0xff);
+#endif
+}
+
+static void cirrus_mmio_writel(void *opaque, target_phys_addr_t addr,
+                              uint32_t val)
+{
+#ifdef TARGET_WORDS_BIGENDIAN
+    cirrus_mmio_writeb(opaque, addr, (val >> 24) & 0xff);
+    cirrus_mmio_writeb(opaque, addr + 1, (val >> 16) & 0xff);
+    cirrus_mmio_writeb(opaque, addr + 2, (val >> 8) & 0xff);
+    cirrus_mmio_writeb(opaque, addr + 3, val & 0xff);
+#else
+    cirrus_mmio_writeb(opaque, addr, val & 0xff);
+    cirrus_mmio_writeb(opaque, addr + 1, (val >> 8) & 0xff);
+    cirrus_mmio_writeb(opaque, addr + 2, (val >> 16) & 0xff);
+    cirrus_mmio_writeb(opaque, addr + 3, (val >> 24) & 0xff);
+#endif
+}
+
+
+static CPUReadMemoryFunc *cirrus_mmio_read[3] = {
+    cirrus_mmio_readb,
+    cirrus_mmio_readw,
+    cirrus_mmio_readl,
+};
+
+static CPUWriteMemoryFunc *cirrus_mmio_write[3] = {
+    cirrus_mmio_writeb,
+    cirrus_mmio_writew,
+    cirrus_mmio_writel,
+};
+
+/* load/save state */
+
+static void cirrus_vga_save(QEMUFile *f, void *opaque)
+{
+    CirrusVGAState *s = opaque;
+
+    qemu_put_be32s(f, &s->latch);
+    qemu_put_8s(f, &s->sr_index);
+    qemu_put_buffer(f, s->sr, 256);
+    qemu_put_8s(f, &s->gr_index);
+    qemu_put_8s(f, &s->cirrus_shadow_gr0);
+    qemu_put_8s(f, &s->cirrus_shadow_gr1);
+    qemu_put_buffer(f, s->gr + 2, 254);
+    qemu_put_8s(f, &s->ar_index);
+    qemu_put_buffer(f, s->ar, 21);
+    qemu_put_be32s(f, &s->ar_flip_flop);
+    qemu_put_8s(f, &s->cr_index);
+    qemu_put_buffer(f, s->cr, 256);
+    qemu_put_8s(f, &s->msr);
+    qemu_put_8s(f, &s->fcr);
+    qemu_put_8s(f, &s->st00);
+    qemu_put_8s(f, &s->st01);
+
+    qemu_put_8s(f, &s->dac_state);
+    qemu_put_8s(f, &s->dac_sub_index);
+    qemu_put_8s(f, &s->dac_read_index);
+    qemu_put_8s(f, &s->dac_write_index);
+    qemu_put_buffer(f, s->dac_cache, 3);
+    qemu_put_buffer(f, s->palette, 768);
+
+    qemu_put_be32s(f, &s->bank_offset);
+
+    qemu_put_8s(f, &s->cirrus_hidden_dac_lockindex);
+    qemu_put_8s(f, &s->cirrus_hidden_dac_data);
+
+    qemu_put_be32s(f, &s->hw_cursor_x);
+    qemu_put_be32s(f, &s->hw_cursor_y);
+    /* XXX: we do not save the bitblt state - we assume we do not save
+       the state when the blitter is active */
+}
+
+static int cirrus_vga_load(QEMUFile *f, void *opaque, int version_id)
+{
+    CirrusVGAState *s = opaque;
+
+    if (version_id != 1)
+        return -EINVAL;
+
+    qemu_get_be32s(f, &s->latch);
+    qemu_get_8s(f, &s->sr_index);
+    qemu_get_buffer(f, s->sr, 256);
+    qemu_get_8s(f, &s->gr_index);
+    qemu_get_8s(f, &s->cirrus_shadow_gr0);
+    qemu_get_8s(f, &s->cirrus_shadow_gr1);
+    s->gr[0x00] = s->cirrus_shadow_gr0 & 0x0f;
+    s->gr[0x01] = s->cirrus_shadow_gr1 & 0x0f;
+    qemu_get_buffer(f, s->gr + 2, 254);
+    qemu_get_8s(f, &s->ar_index);
+    qemu_get_buffer(f, s->ar, 21);
+    qemu_get_be32s(f, &s->ar_flip_flop);
+    qemu_get_8s(f, &s->cr_index);
+    qemu_get_buffer(f, s->cr, 256);
+    qemu_get_8s(f, &s->msr);
+    qemu_get_8s(f, &s->fcr);
+    qemu_get_8s(f, &s->st00);
+    qemu_get_8s(f, &s->st01);
+
+    qemu_get_8s(f, &s->dac_state);
+    qemu_get_8s(f, &s->dac_sub_index);
+    qemu_get_8s(f, &s->dac_read_index);
+    qemu_get_8s(f, &s->dac_write_index);
+    qemu_get_buffer(f, s->dac_cache, 3);
+    qemu_get_buffer(f, s->palette, 768);
+
+    qemu_get_be32s(f, &s->bank_offset);
+
+    qemu_get_8s(f, &s->cirrus_hidden_dac_lockindex);
+    qemu_get_8s(f, &s->cirrus_hidden_dac_data);
+
+    qemu_get_be32s(f, &s->hw_cursor_x);
+    qemu_get_be32s(f, &s->hw_cursor_y);
+
+    /* force refresh */
+    s->graphic_mode = -1;
+    cirrus_update_bank_ptr(s, 0);
+    cirrus_update_bank_ptr(s, 1);
+    return 0;
+}
+
+/***************************************
+ *
+ *  initialize
+ *
+ ***************************************/
+
+static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci)
+{
+    int vga_io_memory, i;
+    static int inited;
+
+    if (!inited) {
+        inited = 1;
+        for(i = 0;i < 256; i++)
+            rop_to_index[i] = CIRRUS_ROP_NOP_INDEX; /* nop rop */
+        rop_to_index[CIRRUS_ROP_0] = 0;
+        rop_to_index[CIRRUS_ROP_SRC_AND_DST] = 1;
+        rop_to_index[CIRRUS_ROP_NOP] = 2;
+        rop_to_index[CIRRUS_ROP_SRC_AND_NOTDST] = 3;
+        rop_to_index[CIRRUS_ROP_NOTDST] = 4;
+        rop_to_index[CIRRUS_ROP_SRC] = 5;
+        rop_to_index[CIRRUS_ROP_1] = 6;
+        rop_to_index[CIRRUS_ROP_NOTSRC_AND_DST] = 7;
+        rop_to_index[CIRRUS_ROP_SRC_XOR_DST] = 8;
+        rop_to_index[CIRRUS_ROP_SRC_OR_DST] = 9;
+        rop_to_index[CIRRUS_ROP_NOTSRC_OR_NOTDST] = 10;
+        rop_to_index[CIRRUS_ROP_SRC_NOTXOR_DST] = 11;
+        rop_to_index[CIRRUS_ROP_SRC_OR_NOTDST] = 12;
+        rop_to_index[CIRRUS_ROP_NOTSRC] = 13;
+        rop_to_index[CIRRUS_ROP_NOTSRC_OR_DST] = 14;
+        rop_to_index[CIRRUS_ROP_NOTSRC_AND_NOTDST] = 15;
+    }
+
+    register_ioport_write(0x3c0, 16, 1, vga_ioport_write, s);
+
+    register_ioport_write(0x3b4, 2, 1, vga_ioport_write, s);
+    register_ioport_write(0x3d4, 2, 1, vga_ioport_write, s);
+    register_ioport_write(0x3ba, 1, 1, vga_ioport_write, s);
+    register_ioport_write(0x3da, 1, 1, vga_ioport_write, s);
+
+    register_ioport_read(0x3c0, 16, 1, vga_ioport_read, s);
+
+    register_ioport_read(0x3b4, 2, 1, vga_ioport_read, s);
+    register_ioport_read(0x3d4, 2, 1, vga_ioport_read, s);
+    register_ioport_read(0x3ba, 1, 1, vga_ioport_read, s);
+    register_ioport_read(0x3da, 1, 1, vga_ioport_read, s);
+
+    vga_io_memory = cpu_register_io_memory(0, cirrus_vga_mem_read, 
+                                           cirrus_vga_mem_write, s);
+    cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000, 
+                                 vga_io_memory);
+
+    s->sr[0x06] = 0x0f;
+    if (device_id == CIRRUS_ID_CLGD5446) {
+        /* 4MB 64 bit memory config, always PCI */
+        s->sr[0x1F] = 0x2d;            // MemClock
+        s->gr[0x18] = 0x0f;             // fastest memory configuration
+#if 1
+        s->sr[0x0f] = 0x98;
+        s->sr[0x17] = 0x20;
+        s->sr[0x15] = 0x04; /* memory size, 3=2MB, 4=4MB */
+        s->real_vram_size = 4096 * 1024;
+#else
+        s->sr[0x0f] = 0x18;
+        s->sr[0x17] = 0x20;
+        s->sr[0x15] = 0x03; /* memory size, 3=2MB, 4=4MB */
+        s->real_vram_size = 2048 * 1024;
+#endif
+    } else {
+        s->sr[0x1F] = 0x22;            // MemClock
+        s->sr[0x0F] = CIRRUS_MEMSIZE_2M;
+        if (is_pci) 
+            s->sr[0x17] = CIRRUS_BUSTYPE_PCI;
+        else
+            s->sr[0x17] = CIRRUS_BUSTYPE_ISA;
+        s->real_vram_size = 2048 * 1024;
+        s->sr[0x15] = 0x03; /* memory size, 3=2MB, 4=4MB */
+    }
+    s->cr[0x27] = device_id;
+
+    /* Win2K seems to assume that the pattern buffer is at 0xff
+       initially ! */
+    memset(s->vram_ptr, 0xff, s->real_vram_size);
+
+    s->cirrus_hidden_dac_lockindex = 5;
+    s->cirrus_hidden_dac_data = 0;
+
+    /* I/O handler for LFB */
+    s->cirrus_linear_io_addr =
+       cpu_register_io_memory(0, cirrus_linear_read, cirrus_linear_write,
+                              s);
+    s->cirrus_linear_write = cpu_get_io_memory_write(s->cirrus_linear_io_addr);
+
+    /* I/O handler for LFB */
+    s->cirrus_linear_bitblt_io_addr =
+       cpu_register_io_memory(0, cirrus_linear_bitblt_read, cirrus_linear_bitblt_write,
+                              s);
+
+    /* I/O handler for memory-mapped I/O */
+    s->cirrus_mmio_io_addr =
+       cpu_register_io_memory(0, cirrus_mmio_read, cirrus_mmio_write, s);
+
+    /* XXX: s->vram_size must be a power of two */
+    s->cirrus_addr_mask = s->real_vram_size - 1;
+    s->linear_mmio_mask = s->real_vram_size - 256;
+
+    s->get_bpp = cirrus_get_bpp;
+    s->get_offsets = cirrus_get_offsets;
+    s->get_resolution = cirrus_get_resolution;
+    s->cursor_invalidate = cirrus_cursor_invalidate;
+    s->cursor_draw_line = cirrus_cursor_draw_line;
+
+    register_savevm("cirrus_vga", 0, 1, cirrus_vga_save, cirrus_vga_load, s);
+}
+
+/***************************************
+ *
+ *  ISA bus support
+ *
+ ***************************************/
+
+void isa_cirrus_vga_init(DisplayState *ds, uint8_t *vga_ram_base, 
+                         unsigned long vga_ram_offset, int vga_ram_size)
+{
+    CirrusVGAState *s;
+
+    s = qemu_mallocz(sizeof(CirrusVGAState));
+    
+    vga_common_init((VGAState *)s, 
+                    ds, vga_ram_base, vga_ram_offset, vga_ram_size);
+    cirrus_init_common(s, CIRRUS_ID_CLGD5430, 0);
+    /* XXX ISA-LFB support */
+}
+
+/***************************************
+ *
+ *  PCI bus support
+ *
+ ***************************************/
+
+static void cirrus_pci_lfb_map(PCIDevice *d, int region_num,
+                              uint32_t addr, uint32_t size, int type)
+{
+    CirrusVGAState *s = &((PCICirrusVGAState *)d)->cirrus_vga;
+
+    /* XXX: add byte swapping apertures */
+    cpu_register_physical_memory(addr, s->vram_size,
+                                s->cirrus_linear_io_addr);
+    cpu_register_physical_memory(addr + 0x1000000, 0x400000,
+                                s->cirrus_linear_bitblt_io_addr);
+}
+
+static void cirrus_pci_mmio_map(PCIDevice *d, int region_num,
+                               uint32_t addr, uint32_t size, int type)
+{
+    CirrusVGAState *s = &((PCICirrusVGAState *)d)->cirrus_vga;
+
+    cpu_register_physical_memory(addr, CIRRUS_PNPMMIO_SIZE,
+                                s->cirrus_mmio_io_addr);
+}
+
+void pci_cirrus_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base, 
+                         unsigned long vga_ram_offset, int vga_ram_size)
+{
+    PCICirrusVGAState *d;
+    uint8_t *pci_conf;
+    CirrusVGAState *s;
+    int device_id;
+    
+    device_id = CIRRUS_ID_CLGD5446;
+
+    /* setup PCI configuration registers */
+    d = (PCICirrusVGAState *)pci_register_device(bus, "Cirrus VGA", 
+                                                 sizeof(PCICirrusVGAState), 
+                                                 -1, NULL, NULL);
+    pci_conf = d->dev.config;
+    pci_conf[0x00] = (uint8_t) (PCI_VENDOR_CIRRUS & 0xff);
+    pci_conf[0x01] = (uint8_t) (PCI_VENDOR_CIRRUS >> 8);
+    pci_conf[0x02] = (uint8_t) (device_id & 0xff);
+    pci_conf[0x03] = (uint8_t) (device_id >> 8);
+    pci_conf[0x04] = PCI_COMMAND_IOACCESS | PCI_COMMAND_MEMACCESS;
+    pci_conf[0x0a] = PCI_CLASS_SUB_VGA;
+    pci_conf[0x0b] = PCI_CLASS_BASE_DISPLAY;
+    pci_conf[0x0e] = PCI_CLASS_HEADERTYPE_00h;
+
+    /* setup VGA */
+    s = &d->cirrus_vga;
+    vga_common_init((VGAState *)s, 
+                    ds, vga_ram_base, vga_ram_offset, vga_ram_size);
+    cirrus_init_common(s, device_id, 1);
+
+    /* setup memory space */
+    /* memory #0 LFB */
+    /* memory #1 memory-mapped I/O */
+    /* XXX: s->vram_size must be a power of two */
+    pci_register_io_region((PCIDevice *)d, 0, 0x2000000,
+                          PCI_ADDRESS_SPACE_MEM_PREFETCH, cirrus_pci_lfb_map);
+    if (device_id == CIRRUS_ID_CLGD5446) {
+        pci_register_io_region((PCIDevice *)d, 1, CIRRUS_PNPMMIO_SIZE,
+                               PCI_ADDRESS_SPACE_MEM, cirrus_pci_mmio_map);
+    }
+    /* XXX: ROM BIOS */
+}
diff --git a/tools/ioemu/hw/cirrus_vga_rop.h b/tools/ioemu/hw/cirrus_vga_rop.h
new file mode 100644 (file)
index 0000000..c54f125
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * QEMU Cirrus CLGD 54xx VGA Emulator.
+ * 
+ * Copyright (c) 2004 Fabrice Bellard
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+static void
+glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(CirrusVGAState *s,
+                             uint8_t *dst,const uint8_t *src,
+                             int dstpitch,int srcpitch,
+                             int bltwidth,int bltheight)
+{
+    int x,y;
+    dstpitch -= bltwidth;
+    srcpitch -= bltwidth;
+    for (y = 0; y < bltheight; y++) {
+        for (x = 0; x < bltwidth; x++) {
+            ROP_OP(*dst, *src);
+            dst++;
+            src++;
+        }
+        dst += dstpitch;
+        src += srcpitch;
+    }
+}
+
+static void
+glue(cirrus_bitblt_rop_bkwd_, ROP_NAME)(CirrusVGAState *s,
+                                        uint8_t *dst,const uint8_t *src,
+                                        int dstpitch,int srcpitch,
+                                        int bltwidth,int bltheight)
+{
+    int x,y;
+    dstpitch += bltwidth;
+    srcpitch += bltwidth;
+    for (y = 0; y < bltheight; y++) {
+        for (x = 0; x < bltwidth; x++) {
+            ROP_OP(*dst, *src);
+            dst--;
+            src--;
+        }
+        dst += dstpitch;
+        src += srcpitch;
+    }
+}
+
+#define DEPTH 8
+#include "cirrus_vga_rop2.h"
+
+#define DEPTH 16
+#include "cirrus_vga_rop2.h"
+
+#define DEPTH 24
+#include "cirrus_vga_rop2.h"
+
+#define DEPTH 32
+#include "cirrus_vga_rop2.h"
+
+#undef ROP_NAME
+#undef ROP_OP
diff --git a/tools/ioemu/hw/cirrus_vga_rop2.h b/tools/ioemu/hw/cirrus_vga_rop2.h
new file mode 100644 (file)
index 0000000..5521870
--- /dev/null
@@ -0,0 +1,260 @@
+/*
+ * QEMU Cirrus CLGD 54xx VGA Emulator.
+ * 
+ * Copyright (c) 2004 Fabrice Bellard
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#if DEPTH == 8
+#define PUTPIXEL()    ROP_OP(d[0], col)
+#elif DEPTH == 16
+#define PUTPIXEL()    ROP_OP(((uint16_t *)d)[0], col);
+#elif DEPTH == 24
+#define PUTPIXEL()    ROP_OP(d[0], col); \
+                      ROP_OP(d[1], (col >> 8)); \
+                      ROP_OP(d[2], (col >> 16))
+#elif DEPTH == 32
+#define PUTPIXEL()    ROP_OP(((uint32_t *)d)[0], col)
+#else
+#error unsupported DEPTH
+#endif                
+
+static void
+glue(glue(glue(cirrus_patternfill_, ROP_NAME), _),DEPTH)
+     (CirrusVGAState * s, uint8_t * dst,
+      const uint8_t * src, 
+      int dstpitch, int srcpitch, 
+      int bltwidth, int bltheight)
+{
+    uint8_t *d;
+    int x, y, pattern_y, pattern_pitch, pattern_x;
+    unsigned int col;
+    const uint8_t *src1;
+
+#if DEPTH == 8
+    pattern_pitch = 8;
+#elif DEPTH == 16
+    pattern_pitch = 16;
+#else
+    pattern_pitch = 32;
+#endif
+    pattern_y = s->cirrus_blt_srcaddr & 7;
+    pattern_x = 0;
+    for(y = 0; y < bltheight; y++) {
+        d = dst;
+        src1 = src + pattern_y * pattern_pitch;
+        for (x = 0; x < bltwidth; x += (DEPTH / 8)) {
+#if DEPTH == 8
+            col = src1[pattern_x];
+            pattern_x = (pattern_x + 1) & 7;
+#elif DEPTH == 16
+            col = ((uint16_t *)(src1 + pattern_x))[0];
+            pattern_x = (pattern_x + 2) & 15;
+#elif DEPTH == 24
+            {
+                const uint8_t *src2 = src1 + pattern_x * 3;
+                col = src2[0] | (src2[1] << 8) | (src2[2] << 16);
+                pattern_x = (pattern_x + 1) & 7;
+            }
+#else
+            col = ((uint32_t *)(src1 + pattern_x))[0];
+            pattern_x = (pattern_x + 4) & 31;
+#endif
+            PUTPIXEL();
+            d += (DEPTH / 8);
+        }
+        pattern_y = (pattern_y + 1) & 7;
+        dst += dstpitch;
+    }
+}
+
+/* NOTE: srcpitch is ignored */
+static void
+glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH)
+     (CirrusVGAState * s, uint8_t * dst,
+      const uint8_t * src, 
+      int dstpitch, int srcpitch, 
+      int bltwidth, int bltheight)
+{
+    uint8_t *d;
+    int x, y;
+    unsigned bits, bits_xor;
+    unsigned int col;
+    unsigned bitmask;
+    unsigned index;
+    int srcskipleft = 0;
+
+    if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) {
+        bits_xor = 0xff;
+        col = s->cirrus_blt_bgcol;
+    } else {
+        bits_xor = 0x00;
+        col = s->cirrus_blt_fgcol;
+    }
+
+    for(y = 0; y < bltheight; y++) {
+        bitmask = 0x80 >> srcskipleft;
+        bits = *src++ ^ bits_xor;
+        d = dst;
+        for (x = 0; x < bltwidth; x += (DEPTH / 8)) {
+            if ((bitmask & 0xff) == 0) {
+                bitmask = 0x80;
+                bits = *src++ ^ bits_xor;
+            }
+            index = (bits & bitmask);
+            if (index) {
+                PUTPIXEL();
+            }
+            d += (DEPTH / 8);
+            bitmask >>= 1;
+        }
+        dst += dstpitch;
+    }
+}
+
+static void
+glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH)
+     (CirrusVGAState * s, uint8_t * dst,
+      const uint8_t * src, 
+      int dstpitch, int srcpitch, 
+      int bltwidth, int bltheight)
+{
+    uint32_t colors[2];
+    uint8_t *d;
+    int x, y;
+    unsigned bits;
+    unsigned int col;
+    unsigned bitmask;
+    int srcskipleft = 0;
+
+    colors[0] = s->cirrus_blt_bgcol;
+    colors[1] = s->cirrus_blt_fgcol;
+    for(y = 0; y < bltheight; y++) {
+        bitmask = 0x80 >> srcskipleft;
+        bits = *src++;
+        d = dst;
+        for (x = 0; x < bltwidth; x += (DEPTH / 8)) {
+            if ((bitmask & 0xff) == 0) {
+                bitmask = 0x80;
+                bits = *src++;
+            }
+            col = colors[!!(bits & bitmask)];
+            PUTPIXEL();
+            d += (DEPTH / 8);
+            bitmask >>= 1;
+        }
+        dst += dstpitch;
+    }
+}
+
+static void
+glue(glue(glue(cirrus_colorexpand_pattern_transp_, ROP_NAME), _),DEPTH)
+     (CirrusVGAState * s, uint8_t * dst,
+      const uint8_t * src, 
+      int dstpitch, int srcpitch, 
+      int bltwidth, int bltheight)
+{
+    uint8_t *d;
+    int x, y, bitpos, pattern_y;
+    unsigned int bits, bits_xor;
+    unsigned int col;
+
+    if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) {
+        bits_xor = 0xff;
+        col = s->cirrus_blt_bgcol;
+    } else {
+        bits_xor = 0x00;
+        col = s->cirrus_blt_fgcol;
+    }
+    pattern_y = s->cirrus_blt_srcaddr & 7;
+
+    for(y = 0; y < bltheight; y++) {
+        bits = src[pattern_y] ^ bits_xor;
+        bitpos = 7;
+        d = dst;
+        for (x = 0; x < bltwidth; x += (DEPTH / 8)) {
+            if ((bits >> bitpos) & 1) {
+                PUTPIXEL();
+            }
+            d += (DEPTH / 8);
+            bitpos = (bitpos - 1) & 7;
+        }
+        pattern_y = (pattern_y + 1) & 7;
+        dst += dstpitch;
+    }
+}
+
+static void
+glue(glue(glue(cirrus_colorexpand_pattern_, ROP_NAME), _),DEPTH)
+     (CirrusVGAState * s, uint8_t * dst,
+      const uint8_t * src, 
+      int dstpitch, int srcpitch, 
+      int bltwidth, int bltheight)
+{
+    uint32_t colors[2];
+    uint8_t *d;
+    int x, y, bitpos, pattern_y;
+    unsigned int bits;
+    unsigned int col;
+
+    colors[0] = s->cirrus_blt_bgcol;
+    colors[1] = s->cirrus_blt_fgcol;
+    pattern_y = s->cirrus_blt_srcaddr & 7;
+
+    for(y = 0; y < bltheight; y++) {
+        bits = src[pattern_y];
+        bitpos = 7;
+        d = dst;
+        for (x = 0; x < bltwidth; x += (DEPTH / 8)) {
+            col = colors[(bits >> bitpos) & 1];
+            PUTPIXEL();
+            d += (DEPTH / 8);
+            bitpos = (bitpos - 1) & 7;
+        }
+        pattern_y = (pattern_y + 1) & 7;
+        dst += dstpitch;
+    }
+}
+
+static void 
+glue(glue(glue(cirrus_fill_, ROP_NAME), _),DEPTH)
+     (CirrusVGAState *s,
+      uint8_t *dst, int dst_pitch, 
+      int width, int height)
+{
+    uint8_t *d, *d1;
+    uint32_t col;
+    int x, y;
+
+    col = s->cirrus_blt_fgcol;
+
+    d1 = dst;
+    for(y = 0; y < height; y++) {
+        d = d1;
+        for(x = 0; x < width; x += (DEPTH / 8)) {
+            PUTPIXEL();
+            d += (DEPTH / 8);
+        }
+        d1 += dst_pitch;
+    }
+}
+
+#undef DEPTH
+#undef PUTPIXEL
diff --git a/tools/ioemu/hw/cuda.c b/tools/ioemu/hw/cuda.c
new file mode 100644 (file)
index 0000000..c05cdeb
--- /dev/null
@@ -0,0 +1,614 @@
+/*
+ * QEMU CUDA support
+ * 
+ * Copyright (c) 2004 Fabrice Bellard
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+
+//#define DEBUG_CUDA
+//#define DEBUG_CUDA_PACKET
+
+/* Bits in B data register: all active low */
+#define TREQ           0x08            /* Transfer request (input) */
+#define TACK           0x10            /* Transfer acknowledge (output) */
+#define TIP            0x20            /* Transfer in progress (output) */
+
+/* Bits in ACR */
+#define SR_CTRL                0x1c            /* Shift register control bits */
+#define SR_EXT         0x0c            /* Shift on external clock */
+#define SR_OUT         0x10            /* Shift out if 1 */
+
+/* Bits in IFR and IER */
+#define IER_SET                0x80            /* set bits in IER */
+#define IER_CLR                0               /* clear bits in IER */
+#define SR_INT         0x04            /* Shift register full/empty */
+#define T1_INT          0x40            /* Timer 1 interrupt */
+
+/* Bits in ACR */
+#define T1MODE          0xc0            /* Timer 1 mode */
+#define T1MODE_CONT     0x40            /*  continuous interrupts */
+
+/* commands (1st byte) */
+#define ADB_PACKET     0
+#define CUDA_PACKET    1
+#define ERROR_PACKET   2
+#define TIMER_PACKET   3
+#define POWER_PACKET   4
+#define MACIIC_PACKET  5
+#define PMU_PACKET     6
+
+
+/* CUDA commands (2nd byte) */
+#define CUDA_WARM_START                        0x0
+#define CUDA_AUTOPOLL                  0x1
+#define CUDA_GET_6805_ADDR             0x2
+#define CUDA_GET_TIME                  0x3
+#define CUDA_GET_PRAM                  0x7
+#define CUDA_SET_6805_ADDR             0x8
+#define CUDA_SET_TIME                  0x9
+#define CUDA_POWERDOWN                 0xa
+#define CUDA_POWERUP_TIME              0xb
+#define CUDA_SET_PRAM                  0xc
+#define CUDA_MS_RESET                  0xd
+#define CUDA_SEND_DFAC                 0xe
+#define CUDA_BATTERY_SWAP_SENSE                0x10
+#define CUDA_RESET_SYSTEM              0x11
+#define CUDA_SET_IPL                   0x12
+#define CUDA_FILE_SERVER_FLAG          0x13
+#define CUDA_SET_AUTO_RATE             0x14
+#define CUDA_GET_AUTO_RATE             0x16
+#define CUDA_SET_DEVICE_LIST           0x19
+#define CUDA_GET_DEVICE_LIST           0x1a
+#define CUDA_SET_ONE_SECOND_MODE       0x1b
+#define CUDA_SET_POWER_MESSAGES                0x21
+#define CUDA_GET_SET_IIC               0x22
+#define CUDA_WAKEUP                    0x23
+#define CUDA_TIMER_TICKLE              0x24
+#define CUDA_COMBINED_FORMAT_IIC       0x25
+
+#define CUDA_TIMER_FREQ (4700000 / 6)
+#define CUDA_ADB_POLL_FREQ 50
+
+typedef struct CUDATimer {
+    unsigned int latch;
+    uint16_t counter_value; /* counter value at load time */
+    int64_t load_time;
+    int64_t next_irq_time;
+    QEMUTimer *timer;
+} CUDATimer;
+
+typedef struct CUDAState {
+    /* cuda registers */
+    uint8_t b;      /* B-side data */
+    uint8_t a;      /* A-side data */
+    uint8_t dirb;   /* B-side direction (1=output) */
+    uint8_t dira;   /* A-side direction (1=output) */
+    uint8_t sr;     /* Shift register */
+    uint8_t acr;    /* Auxiliary control register */
+    uint8_t pcr;    /* Peripheral control register */
+    uint8_t ifr;    /* Interrupt flag register */
+    uint8_t ier;    /* Interrupt enable register */
+    uint8_t anh;    /* A-side data, no handshake */
+
+    CUDATimer timers[2];
+    
+    uint8_t last_b; /* last value of B register */
+    uint8_t last_acr; /* last value of B register */
+    
+    int data_in_size;
+    int data_in_index;
+    int data_out_index;
+
+    int irq;
+    openpic_t *openpic;
+    uint8_t autopoll;
+    uint8_t data_in[128];
+    uint8_t data_out[16];
+    QEMUTimer *adb_poll_timer;
+} CUDAState;
+
+static CUDAState cuda_state;
+ADBBusState adb_bus;
+
+static void cuda_update(CUDAState *s);
+static void cuda_receive_packet_from_host(CUDAState *s, 
+                                          const uint8_t *data, int len);
+static void cuda_timer_update(CUDAState *s, CUDATimer *ti, 
+                              int64_t current_time);
+
+static void cuda_update_irq(CUDAState *s)
+{
+    if (s->ifr & s->ier & (SR_INT | T1_INT)) {
+        openpic_set_irq(s->openpic, s->irq, 1);
+    } else {
+        openpic_set_irq(s->openpic, s->irq, 0);
+    }
+}
+
+static unsigned int get_counter(CUDATimer *s)
+{
+    int64_t d;
+    unsigned int counter;
+
+    d = muldiv64(qemu_get_clock(vm_clock) - s->load_time, 
+                 CUDA_TIMER_FREQ, ticks_per_sec);
+    if (d <= s->counter_value) {
+        counter = d;
+    } else {
+        counter = s->latch - 1 - ((d - s->counter_value) % s->latch);
+    }
+    return counter;
+}
+
+static void set_counter(CUDAState *s, CUDATimer *ti, unsigned int val)
+{
+#ifdef DEBUG_CUDA
+    printf("cuda: T%d.counter=%d\n",
+           1 + (ti->timer == NULL), val);
+#endif
+    ti->load_time = qemu_get_clock(vm_clock);
+    ti->counter_value = val;
+    cuda_timer_update(s, ti, ti->load_time);
+}
+
+static int64_t get_next_irq_time(CUDATimer *s, int64_t current_time)
+{
+    int64_t d, next_time, base;
+    /* current counter value */
+    d = muldiv64(current_time - s->load_time, 
+                 CUDA_TIMER_FREQ, ticks_per_sec);
+    if (d <= s->counter_value) {
+        next_time = s->counter_value + 1;
+    } else {
+        base = ((d - s->counter_value) / s->latch);
+        base = (base * s->latch) + s->counter_value;
+        next_time = base + s->latch;
+    }
+#ifdef DEBUG_CUDA
+    printf("latch=%d counter=%lld delta_next=%lld\n", 
+           s->latch, d, next_time - d);
+#endif
+    next_time = muldiv64(next_time, ticks_per_sec, CUDA_TIMER_FREQ) + 
+        s->load_time;
+    if (next_time <= current_time)
+        next_time = current_time + 1;
+    return next_time;
+}
+
+static void cuda_timer_update(CUDAState *s, CUDATimer *ti, 
+                              int64_t current_time)
+{
+    if (!ti->timer)
+        return;
+    if ((s->acr & T1MODE) != T1MODE_CONT) {
+        qemu_del_timer(ti->timer);
+    } else {
+        ti->next_irq_time = get_next_irq_time(ti, current_time);
+        qemu_mod_timer(ti->timer, ti->next_irq_time);
+    }
+}
+
+static void cuda_timer1(void *opaque)
+{
+    CUDAState *s = opaque;
+    CUDATimer *ti = &s->timers[0];
+
+    cuda_timer_update(s, ti, ti->next_irq_time);
+    s->ifr |= T1_INT;
+    cuda_update_irq(s);
+}
+
+static uint32_t cuda_readb(void *opaque, target_phys_addr_t addr)
+{
+    CUDAState *s = opaque;
+    uint32_t val;
+
+    addr = (addr >> 9) & 0xf;
+    switch(addr) {
+    case 0:
+        val = s->b;
+        break;
+    case 1:
+        val = s->a;
+        break;
+    case 2:
+        val = s->dirb;
+        break;
+    case 3:
+        val = s->dira;
+        break;
+    case 4:
+        val = get_counter(&s->timers[0]) & 0xff;
+        s->ifr &= ~T1_INT;
+        cuda_update_irq(s);
+        break;
+    case 5:
+        val = get_counter(&s->timers[0]) >> 8;
+        s->ifr &= ~T1_INT;
+        cuda_update_irq(s);
+        break;
+    case 6:
+        val = s->timers[0].latch & 0xff;
+        break;
+    case 7:
+        val = (s->timers[0].latch >> 8) & 0xff;
+        break;
+    case 8:
+        val = get_counter(&s->timers[1]) & 0xff;
+        break;
+    case 9:
+        val = get_counter(&s->timers[1]) >> 8;
+        break;
+    case 10:
+        val = s->sr;
+        s->ifr &= ~SR_INT;
+        cuda_update_irq(s);
+        break;
+    case 11:
+        val = s->acr;
+        break;
+    case 12:
+        val = s->pcr;
+        break;
+    case 13:
+        val = s->ifr;
+        break;
+    case 14:
+        val = s->ier;
+        break;
+    default:
+    case 15:
+        val = s->anh;
+        break;
+    }
+#ifdef DEBUG_CUDA
+    if (addr != 13 || val != 0)
+        printf("cuda: read: reg=0x%x val=%02x\n", addr, val);
+#endif
+    return val;
+}
+
+static void cuda_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
+{
+    CUDAState *s = opaque;
+    
+    addr = (addr >> 9) & 0xf;
+#ifdef DEBUG_CUDA
+    printf("cuda: write: reg=0x%x val=%02x\n", addr, val);
+#endif
+
+    switch(addr) {
+    case 0:
+        s->b = val;
+        cuda_update(s);
+        break;
+    case 1:
+        s->a = val;
+        break;
+    case 2:
+        s->dirb = val;
+        break;
+    case 3:
+        s->dira = val;
+        break;
+    case 4:
+        val = val | (get_counter(&s->timers[0]) & 0xff00);
+        set_counter(s, &s->timers[0], val);
+        break;
+    case 5:
+        val = (val << 8) |  (get_counter(&s->timers[0]) & 0xff);
+        set_counter(s, &s->timers[0], val);
+        break;
+    case 6:
+        s->timers[0].latch = (s->timers[0].latch & 0xff00) | val;
+        cuda_timer_update(s, &s->timers[0], qemu_get_clock(vm_clock));
+        break;
+    case 7:
+        s->timers[0].latch = (s->timers[0].latch & 0xff) | (val << 8);
+        cuda_timer_update(s, &s->timers[0], qemu_get_clock(vm_clock));
+        break;
+    case 8:
+        val = val | (get_counter(&s->timers[1]) & 0xff00);
+        set_counter(s, &s->timers[1], val);
+        break;
+    case 9:
+        val = (val << 8) |  (get_counter(&s->timers[1]) & 0xff);
+        set_counter(s, &s->timers[1], val);
+        break;
+    case 10:
+        s->sr = val;
+        break;
+    case 11:
+        s->acr = val;
+        cuda_timer_update(s, &s->timers[0], qemu_get_clock(vm_clock));
+        cuda_update(s);
+        break;
+    case 12:
+        s->pcr = val;
+        break;
+    case 13:
+        /* reset bits */
+        s->ifr &= ~val;
+        cuda_update_irq(s);
+        break;
+    case 14:
+        if (val & IER_SET) {
+            /* set bits */
+            s->ier |= val & 0x7f;
+        } else {
+            /* reset bits */
+            s->ier &= ~val;
+        }
+        cuda_update_irq(s);
+        break;
+    default:
+    case 15:
+        s->anh = val;
+        break;
+    }
+}
+
+/* NOTE: TIP and TREQ are negated */
+static void cuda_update(CUDAState *s)
+{
+    int packet_received, len;
+
+    packet_received = 0;
+    if (!(s->b & TIP)) {
+        /* transfer requested from host */
+
+        if (s->acr & SR_OUT) {
+            /* data output */
+            if ((s->b & (TACK | TIP)) != (s->last_b & (TACK | TIP))) {
+                if (s->data_out_index < sizeof(s->data_out)) {
+#ifdef DEBUG_CUDA
+                    printf("cuda: send: %02x\n", s->sr);
+#endif
+                    s->data_out[s->data_out_index++] = s->sr;
+                    s->ifr |= SR_INT;
+                    cuda_update_irq(s);
+                }
+            }
+        } else {
+            if (s->data_in_index < s->data_in_size) {
+                /* data input */
+                if ((s->b & (TACK | TIP)) != (s->last_b & (TACK | TIP))) {
+                    s->sr = s->data_in[s->data_in_index++];
+#ifdef DEBUG_CUDA
+                    printf("cuda: recv: %02x\n", s->sr);
+#endif
+                    /* indicate end of transfer */
+                    if (s->data_in_index >= s->data_in_size) {
+                        s->b = (s->b | TREQ);
+                    }
+                    s->ifr |= SR_INT;
+                    cuda_update_irq(s);
+                }
+            }
+        }
+    } else {
+        /* no transfer requested: handle sync case */
+        if ((s->last_b & TIP) && (s->b & TACK) != (s->last_b & TACK)) {
+            /* update TREQ state each time TACK change state */
+            if (s->b & TACK)
+                s->b = (s->b | TREQ);
+            else
+                s->b = (s->b & ~TREQ);
+            s->ifr |= SR_INT;
+            cuda_update_irq(s);
+        } else {
+            if (!(s->last_b & TIP)) {
+                /* handle end of host to cuda transfert */
+                packet_received = (s->data_out_index > 0);
+                /* always an IRQ at the end of transfert */
+                s->ifr |= SR_INT;
+                cuda_update_irq(s);
+            }
+            /* signal if there is data to read */
+            if (s->data_in_index < s->data_in_size) {
+                s->b = (s->b & ~TREQ);
+            }
+        }
+    }
+
+    s->last_acr = s->acr;
+    s->last_b = s->b;
+
+    /* NOTE: cuda_receive_packet_from_host() can call cuda_update()
+       recursively */
+    if (packet_received) {
+        len = s->data_out_index;
+        s->data_out_index = 0;
+        cuda_receive_packet_from_host(s, s->data_out, len);
+    }
+}
+
+static void cuda_send_packet_to_host(CUDAState *s, 
+                                     const uint8_t *data, int len)
+{
+#ifdef DEBUG_CUDA_PACKET
+    {
+        int i;
+        printf("cuda_send_packet_to_host:\n");
+        for(i = 0; i < len; i++)
+            printf(" %02x", data[i]);
+        printf("\n");
+    }
+#endif
+    memcpy(s->data_in, data, len);
+    s->data_in_size = len;
+    s->data_in_index = 0;
+    cuda_update(s);
+    s->ifr |= SR_INT;
+    cuda_update_irq(s);
+}
+
+static void cuda_adb_poll(void *opaque)
+{
+    CUDAState *s = opaque;
+    uint8_t obuf[ADB_MAX_OUT_LEN + 2];
+    int olen;
+
+    olen = adb_poll(&adb_bus, obuf + 2);
+    if (olen > 0) {
+        obuf[0] = ADB_PACKET;
+        obuf[1] = 0x40; /* polled data */
+        cuda_send_packet_to_host(s, obuf, olen + 2);
+    }
+    qemu_mod_timer(s->adb_poll_timer, 
+                   qemu_get_clock(vm_clock) + 
+                   (ticks_per_sec / CUDA_ADB_POLL_FREQ));
+}
+
+static void cuda_receive_packet(CUDAState *s, 
+                                const uint8_t *data, int len)
+{
+    uint8_t obuf[16];
+    int ti, autopoll;
+
+    switch(data[0]) {
+    case CUDA_AUTOPOLL:
+        autopoll = (data[1] != 0);
+        if (autopoll != s->autopoll) {
+            s->autopoll = autopoll;
+            if (autopoll) {
+                qemu_mod_timer(s->adb_poll_timer, 
+                               qemu_get_clock(vm_clock) + 
+                               (ticks_per_sec / CUDA_ADB_POLL_FREQ));
+            } else {
+                qemu_del_timer(s->adb_poll_timer);
+            }
+        }
+        obuf[0] = CUDA_PACKET;
+        obuf[1] = data[1];
+        cuda_send_packet_to_host(s, obuf, 2);
+        break;
+    case CUDA_GET_TIME:
+        /* XXX: add time support ? */
+        ti = time(NULL);
+        obuf[0] = CUDA_PACKET;
+        obuf[1] = 0;
+        obuf[2] = 0;
+        obuf[3] = ti >> 24;
+        obuf[4] = ti >> 16;
+        obuf[5] = ti >> 8;
+        obuf[6] = ti;
+        cuda_send_packet_to_host(s, obuf, 7);
+        break;
+    case CUDA_SET_TIME:
+    case CUDA_FILE_SERVER_FLAG:
+    case CUDA_SET_DEVICE_LIST:
+    case CUDA_SET_AUTO_RATE:
+    case CUDA_SET_POWER_MESSAGES:
+        obuf[0] = CUDA_PACKET;
+        obuf[1] = 0;
+        cuda_send_packet_to_host(s, obuf, 2);
+        break;
+    default:
+        break;
+    }
+}
+
+static void cuda_receive_packet_from_host(CUDAState *s, 
+                                          const uint8_t *data, int len)
+{
+#ifdef DEBUG_CUDA_PACKET
+    {
+        int i;
+        printf("cuda_receive_packet_to_host:\n");
+        for(i = 0; i < len; i++)
+            printf(" %02x", data[i]);
+        printf("\n");
+    }
+#endif
+    switch(data[0]) {
+    case ADB_PACKET:
+        {
+            uint8_t obuf[ADB_MAX_OUT_LEN + 2];
+            int olen;
+            olen = adb_request(&adb_bus, obuf + 2, data + 1, len - 1);
+            if (olen > 0) {
+                obuf[0] = ADB_PACKET;
+                obuf[1] = 0x00;
+            } else {
+                /* error */
+                obuf[0] = ADB_PACKET;
+                obuf[1] = -olen;
+                olen = 0;
+            }
+            cuda_send_packet_to_host(s, obuf, olen + 2);
+        }
+        break;
+    case CUDA_PACKET:
+        cuda_receive_packet(s, data + 1, len - 1);
+        break;
+    }
+}
+
+static void cuda_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
+{
+}
+
+static void cuda_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
+{
+}
+
+static uint32_t cuda_readw (void *opaque, target_phys_addr_t addr)
+{
+    return 0;
+}
+
+static uint32_t cuda_readl (void *opaque, target_phys_addr_t addr)
+{
+    return 0;
+}
+
+static CPUWriteMemoryFunc *cuda_write[] = {
+    &cuda_writeb,
+    &cuda_writew,
+    &cuda_writel,
+};
+
+static CPUReadMemoryFunc *cuda_read[] = {
+    &cuda_readb,
+    &cuda_readw,
+    &cuda_readl,
+};
+
+int cuda_init(openpic_t *openpic, int irq)
+{
+    CUDAState *s = &cuda_state;
+    int cuda_mem_index;
+
+    s->openpic = openpic;
+    s->irq = irq;
+
+    s->timers[0].timer = qemu_new_timer(vm_clock, cuda_timer1, s);
+    s->timers[0].latch = 0x10000;
+    set_counter(s, &s->timers[0], 0xffff);
+    s->timers[1].latch = 0x10000;
+    s->ier = T1_INT | SR_INT;
+    set_counter(s, &s->timers[1], 0xffff);
+
+    s->adb_poll_timer = qemu_new_timer(vm_clock, cuda_adb_poll, s);
+    cuda_mem_index = cpu_register_io_memory(0, cuda_read, cuda_write, s);
+    return cuda_mem_index;
+}
diff --git a/tools/ioemu/hw/dma.c b/tools/ioemu/hw/dma.c
new file mode 100644 (file)
index 0000000..ce82869
--- /dev/null
@@ -0,0 +1,535 @@
+/*
+ * QEMU DMA emulation
+ *
+ * Copyright (c) 2003-2004 Vassili Karpov (malc)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+
+/* #define DEBUG_DMA */
+
+#define dolog(...) fprintf (stderr, "dma: " __VA_ARGS__)
+#ifdef DEBUG_DMA
+#define lwarn(...) fprintf (stderr, "dma: " __VA_ARGS__)
+#define linfo(...) fprintf (stderr, "dma: " __VA_ARGS__)
+#define ldebug(...) fprintf (stderr, "dma: " __VA_ARGS__)
+#else
+#define lwarn(...)
+#define linfo(...)
+#define ldebug(...)
+#endif
+
+#define LENOFA(a) ((int) (sizeof(a)/sizeof(a[0])))
+
+struct dma_regs {
+    int now[2];
+    uint16_t base[2];
+    uint8_t mode;
+    uint8_t page;
+    uint8_t pageh;
+    uint8_t dack;
+    uint8_t eop;
+    DMA_transfer_handler transfer_handler;
+    void *opaque;
+};
+
+#define ADDR 0
+#define COUNT 1
+
+static struct dma_cont {
+    uint8_t status;
+    uint8_t command;
+    uint8_t mask;
+    uint8_t flip_flop;
+    int dshift;
+    struct dma_regs regs[4];
+} dma_controllers[2];
+
+enum {
+    CMD_MEMORY_TO_MEMORY = 0x01,
+    CMD_FIXED_ADDRESS    = 0x02,
+    CMD_BLOCK_CONTROLLER = 0x04,
+    CMD_COMPRESSED_TIME  = 0x08,
+    CMD_CYCLIC_PRIORITY  = 0x10,
+    CMD_EXTENDED_WRITE   = 0x20,
+    CMD_LOW_DREQ         = 0x40,
+    CMD_LOW_DACK         = 0x80,
+    CMD_NOT_SUPPORTED    = CMD_MEMORY_TO_MEMORY | CMD_FIXED_ADDRESS
+    | CMD_COMPRESSED_TIME | CMD_CYCLIC_PRIORITY | CMD_EXTENDED_WRITE
+    | CMD_LOW_DREQ | CMD_LOW_DACK
+
+};
+
+static int channels[8] = {-1, 2, 3, 1, -1, -1, -1, 0};
+
+static void write_page (void *opaque, uint32_t nport, uint32_t data)
+{
+    struct dma_cont *d = opaque;
+    int ichan;
+
+    ichan = channels[nport & 7];
+    if (-1 == ichan) {
+        dolog ("invalid channel %#x %#x\n", nport, data);
+        return;
+    }
+    d->regs[ichan].page = data;
+}
+
+static void write_pageh (void *opaque, uint32_t nport, uint32_t data)
+{
+    struct dma_cont *d = opaque;
+    int ichan;
+
+    ichan = channels[nport & 7];
+    if (-1 == ichan) {
+        dolog ("invalid channel %#x %#x\n", nport, data);
+        return;
+    }
+    d->regs[ichan].pageh = data;
+}
+
+static uint32_t read_page (void *opaque, uint32_t nport)
+{
+    struct dma_cont *d = opaque;
+    int ichan;
+
+    ichan = channels[nport & 7];
+    if (-1 == ichan) {
+        dolog ("invalid channel read %#x\n", nport);
+        return 0;
+    }
+    return d->regs[ichan].page;
+}
+
+static uint32_t read_pageh (void *opaque, uint32_t nport)
+{
+    struct dma_cont *d = opaque;
+    int ichan;
+
+    ichan = channels[nport & 7];
+    if (-1 == ichan) {
+        dolog ("invalid channel read %#x\n", nport);
+        return 0;
+    }
+    return d->regs[ichan].pageh;
+}
+
+static inline void init_chan (struct dma_cont *d, int ichan)
+{
+    struct dma_regs *r;
+
+    r = d->regs + ichan;
+    r->now[ADDR] = r->base[ADDR] << d->dshift;
+    r->now[COUNT] = 0;
+}
+
+static inline int getff (struct dma_cont *d)
+{
+    int ff;
+
+    ff = d->flip_flop;
+    d->flip_flop = !ff;
+    return ff;
+}
+
+static uint32_t read_chan (void *opaque, uint32_t nport)
+{
+    struct dma_cont *d = opaque;
+    int ichan, nreg, iport, ff, val, dir;
+    struct dma_regs *r;
+
+    iport = (nport >> d->dshift) & 0x0f;
+    ichan = iport >> 1;
+    nreg = iport & 1;
+    r = d->regs + ichan;
+
+    dir = ((r->mode >> 5) & 1) ? -1 : 1;
+    ff = getff (d);
+    if (nreg)
+        val = (r->base[COUNT] << d->dshift) - r->now[COUNT];
+    else
+        val = r->now[ADDR] + r->now[COUNT] * dir;
+
+    ldebug ("read_chan %#x -> %d\n", iport, val);
+    return (val >> (d->dshift + (ff << 3))) & 0xff;
+}
+
+static void write_chan (void *opaque, uint32_t nport, uint32_t data)
+{
+    struct dma_cont *d = opaque;
+    int iport, ichan, nreg;
+    struct dma_regs *r;
+
+    iport = (nport >> d->dshift) & 0x0f;
+    ichan = iport >> 1;
+    nreg = iport & 1;
+    r = d->regs + ichan;
+    if (getff (d)) {
+        r->base[nreg] = (r->base[nreg] & 0xff) | ((data << 8) & 0xff00);
+        init_chan (d, ichan);
+    } else {
+        r->base[nreg] = (r->base[nreg] & 0xff00) | (data & 0xff);
+    }
+}
+
+static void write_cont (void *opaque, uint32_t nport, uint32_t data)
+{
+    struct dma_cont *d = opaque;
+    int iport, ichan = 0;
+
+    iport = (nport >> d->dshift) & 0x0f;
+    switch (iport) {
+    case 0x08:                  /* command */
+        if ((data != 0) && (data & CMD_NOT_SUPPORTED)) {
+            dolog ("command %#x not supported\n", data);
+            return;
+        }
+        d->command = data;
+        break;
+
+    case 0x09:
+        ichan = data & 3;
+        if (data & 4) {
+            d->status |= 1 << (ichan + 4);
+        }
+        else {
+            d->status &= ~(1 << (ichan + 4));
+        }
+        d->status &= ~(1 << ichan);
+        break;
+
+    case 0x0a:                  /* single mask */
+        if (data & 4)
+            d->mask |= 1 << (data & 3);
+        else
+            d->mask &= ~(1 << (data & 3));
+        break;
+
+    case 0x0b:                  /* mode */
+        {
+            ichan = data & 3;
+#ifdef DEBUG_DMA
+            {
+                int op, ai, dir, opmode;
+                op = (data >> 2) & 3;
+                ai = (data >> 4) & 1;
+                dir = (data >> 5) & 1;
+                opmode = (data >> 6) & 3;
+
+                linfo ("ichan %d, op %d, ai %d, dir %d, opmode %d\n",
+                       ichan, op, ai, dir, opmode);
+            }
+#endif
+            d->regs[ichan].mode = data;
+            break;
+        }
+
+    case 0x0c:                  /* clear flip flop */
+        d->flip_flop = 0;
+        break;
+
+    case 0x0d:                  /* reset */
+        d->flip_flop = 0;
+        d->mask = ~0;
+        d->status = 0;
+        d->command = 0;
+        break;
+
+    case 0x0e:                  /* clear mask for all channels */
+        d->mask = 0;
+        break;
+
+    case 0x0f:                  /* write mask for all channels */
+        d->mask = data;
+        break;
+
+    default:
+        dolog ("unknown iport %#x\n", iport);
+        break;
+    }
+
+#ifdef DEBUG_DMA
+    if (0xc != iport) {
+        linfo ("write_cont: nport %#06x, ichan % 2d, val %#06x\n",
+               nport, ichan, data);
+    }
+#endif
+}
+
+static uint32_t read_cont (void *opaque, uint32_t nport)
+{
+    struct dma_cont *d = opaque;
+    int iport, val;
+
+    iport = (nport >> d->dshift) & 0x0f;
+    switch (iport) {
+    case 0x08:                  /* status */
+        val = d->status;
+        d->status &= 0xf0;
+        break;
+    case 0x0f:                  /* mask */
+        val = d->mask;
+        break;
+    default:
+        val = 0;
+        break;
+    }
+
+    ldebug ("read_cont: nport %#06x, iport %#04x val %#x\n", nport, iport, val);
+    return val;
+}
+
+int DMA_get_channel_mode (int nchan)
+{
+    return dma_controllers[nchan > 3].regs[nchan & 3].mode;
+}
+
+void DMA_hold_DREQ (int nchan)
+{
+    int ncont, ichan;
+
+    ncont = nchan > 3;
+    ichan = nchan & 3;
+    linfo ("held cont=%d chan=%d\n", ncont, ichan);
+    dma_controllers[ncont].status |= 1 << (ichan + 4);
+}
+
+void DMA_release_DREQ (int nchan)
+{
+    int ncont, ichan;
+
+    ncont = nchan > 3;
+    ichan = nchan & 3;
+    linfo ("released cont=%d chan=%d\n", ncont, ichan);
+    dma_controllers[ncont].status &= ~(1 << (ichan + 4));
+}
+
+static void channel_run (int ncont, int ichan)
+{
+    int n;
+    struct dma_regs *r = &dma_controllers[ncont].regs[ichan];
+#ifdef DEBUG_DMA
+    int dir, opmode;
+
+    dir = (r->mode >> 5) & 1;
+    opmode = (r->mode >> 6) & 3;
+
+    if (dir) {
+        dolog ("DMA in address decrement mode\n");
+    }
+    if (opmode != 1) {
+        dolog ("DMA not in single mode select %#x\n", opmode);
+    }
+#endif
+
+    r = dma_controllers[ncont].regs + ichan;
+    n = r->transfer_handler (r->opaque, ichan + (ncont << 2),
+                             r->now[COUNT], (r->base[COUNT] + 1) << ncont);
+    r->now[COUNT] = n;
+    ldebug ("dma_pos %d size %d\n", n, (r->base[COUNT] + 1) << ncont);
+}
+
+void DMA_run (void)
+{
+    struct dma_cont *d;
+    int icont, ichan;
+
+    d = dma_controllers;
+
+    for (icont = 0; icont < 2; icont++, d++) {
+        for (ichan = 0; ichan < 4; ichan++) {
+            int mask;
+
+            mask = 1 << ichan;
+
+            if ((0 == (d->mask & mask)) && (0 != (d->status & (mask << 4))))
+                channel_run (icont, ichan);
+        }
+    }
+}
+
+void DMA_register_channel (int nchan,
+                           DMA_transfer_handler transfer_handler,
+                           void *opaque)
+{
+    struct dma_regs *r;
+    int ichan, ncont;
+
+    ncont = nchan > 3;
+    ichan = nchan & 3;
+
+    r = dma_controllers[ncont].regs + ichan;
+    r->transfer_handler = transfer_handler;
+    r->opaque = opaque;
+}
+
+int DMA_read_memory (int nchan, void *buf, int pos, int len)
+{
+    struct dma_regs *r = &dma_controllers[nchan > 3].regs[nchan & 3];
+    target_ulong addr = ((r->pageh & 0x7f) << 24) | (r->page << 16) | r->now[ADDR];
+
+    if (r->mode & 0x20) {
+        int i;
+        uint8_t *p = buf;
+
+        cpu_physical_memory_read (addr - pos - len, buf, len);
+        /* What about 16bit transfers? */
+        for (i = 0; i < len >> 1; i++) {
+            uint8_t b = p[len - i - 1];
+            p[i] = b;
+        }
+    }
+    else
+        cpu_physical_memory_read (addr + pos, buf, len);
+
+    return len;
+}
+
+int DMA_write_memory (int nchan, void *buf, int pos, int len)
+{
+    struct dma_regs *r = &dma_controllers[nchan > 3].regs[nchan & 3];
+    target_ulong addr = ((r->pageh & 0x7f) << 24) | (r->page << 16) | r->now[ADDR];
+
+    if (r->mode & 0x20) {
+        int i;
+        uint8_t *p = buf;
+
+        cpu_physical_memory_write (addr - pos - len, buf, len);
+        /* What about 16bit transfers? */
+        for (i = 0; i < len; i++) {
+            uint8_t b = p[len - i - 1];
+            p[i] = b;
+        }
+    }
+    else
+        cpu_physical_memory_write (addr + pos, buf, len);
+
+    return len;
+}
+
+/* request the emulator to transfer a new DMA memory block ASAP */
+void DMA_schedule(int nchan)
+{
+    cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
+}
+
+static void dma_reset(void *opaque)
+{
+    struct dma_cont *d = opaque;
+    write_cont (d, (0x0d << d->dshift), 0);
+}
+
+/* dshift = 0: 8 bit DMA, 1 = 16 bit DMA */
+static void dma_init2(struct dma_cont *d, int base, int dshift,
+                      int page_base, int pageh_base)
+{
+    const static int page_port_list[] = { 0x1, 0x2, 0x3, 0x7 };
+    int i;
+
+    d->dshift = dshift;
+    for (i = 0; i < 8; i++) {
+        register_ioport_write (base + (i << dshift), 1, 1, write_chan, d);
+        register_ioport_read (base + (i << dshift), 1, 1, read_chan, d);
+    }
+    for (i = 0; i < LENOFA (page_port_list); i++) {
+        register_ioport_write (page_base + page_port_list[i], 1, 1,
+                               write_page, d);
+        register_ioport_read (page_base + page_port_list[i], 1, 1,
+                              read_page, d);
+        if (pageh_base >= 0) {
+            register_ioport_write (pageh_base + page_port_list[i], 1, 1,
+                                   write_pageh, d);
+            register_ioport_read (pageh_base + page_port_list[i], 1, 1,
+                                  read_pageh, d);
+        }
+    }
+    for (i = 0; i < 8; i++) {
+        register_ioport_write (base + ((i + 8) << dshift), 1, 1,
+                               write_cont, d);
+        register_ioport_read (base + ((i + 8) << dshift), 1, 1,
+                              read_cont, d);
+    }
+    qemu_register_reset(dma_reset, d);
+    dma_reset(d);
+}
+
+static void dma_save (QEMUFile *f, void *opaque)
+{
+    struct dma_cont *d = opaque;
+    int i;
+
+    /* qemu_put_8s (f, &d->status); */
+    qemu_put_8s (f, &d->command);
+    qemu_put_8s (f, &d->mask);
+    qemu_put_8s (f, &d->flip_flop);
+    qemu_put_be32s (f, &d->dshift);
+
+    for (i = 0; i < 4; ++i) {
+        struct dma_regs *r = &d->regs[i];
+        qemu_put_be32s (f, &r->now[0]);
+        qemu_put_be32s (f, &r->now[1]);
+        qemu_put_be16s (f, &r->base[0]);
+        qemu_put_be16s (f, &r->base[1]);
+        qemu_put_8s (f, &r->mode);
+        qemu_put_8s (f, &r->page);
+        qemu_put_8s (f, &r->pageh);
+        qemu_put_8s (f, &r->dack);
+        qemu_put_8s (f, &r->eop);
+    }
+}
+
+static int dma_load (QEMUFile *f, void *opaque, int version_id)
+{
+    struct dma_cont *d = opaque;
+    int i;
+
+    if (version_id != 1)
+        return -EINVAL;
+
+    /* qemu_get_8s (f, &d->status); */
+    qemu_get_8s (f, &d->command);
+    qemu_get_8s (f, &d->mask);
+    qemu_get_8s (f, &d->flip_flop);
+    qemu_get_be32s (f, &d->dshift);
+
+    for (i = 0; i < 4; ++i) {
+        struct dma_regs *r = &d->regs[i];
+        qemu_get_be32s (f, &r->now[0]);
+        qemu_get_be32s (f, &r->now[1]);
+        qemu_get_be16s (f, &r->base[0]);
+        qemu_get_be16s (f, &r->base[1]);
+        qemu_get_8s (f, &r->mode);
+        qemu_get_8s (f, &r->page);
+        qemu_get_8s (f, &r->pageh);
+        qemu_get_8s (f, &r->dack);
+        qemu_get_8s (f, &r->eop);
+    }
+    return 0;
+}
+
+void DMA_init (int high_page_enable)
+{
+    dma_init2(&dma_controllers[0], 0x00, 0, 0x80,
+              high_page_enable ? 0x480 : -1);
+    dma_init2(&dma_controllers[1], 0xc0, 1, 0x88,
+              high_page_enable ? 0x488 : -1);
+    register_savevm ("dma", 0, 1, dma_save, dma_load, &dma_controllers[0]);
+    register_savevm ("dma", 1, 1, dma_save, dma_load, &dma_controllers[1]);
+}
diff --git a/tools/ioemu/hw/fdc.c b/tools/ioemu/hw/fdc.c
new file mode 100644 (file)
index 0000000..d512b1c
--- /dev/null
@@ -0,0 +1,1719 @@
+/*
+ * QEMU Floppy disk emulator (Intel 82078)
+ * 
+ * Copyright (c) 2003 Jocelyn Mayer
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+
+/********************************************************/
+/* debug Floppy devices */
+//#define DEBUG_FLOPPY
+
+#ifdef DEBUG_FLOPPY
+#define FLOPPY_DPRINTF(fmt, args...) \
+do { printf("FLOPPY: " fmt , ##args); } while (0)
+#else
+#define FLOPPY_DPRINTF(fmt, args...)
+#endif
+
+#define FLOPPY_ERROR(fmt, args...) \
+do { printf("FLOPPY ERROR: %s: " fmt, __func__ , ##args); } while (0)
+
+/********************************************************/
+/* Floppy drive emulation                               */
+
+/* Will always be a fixed parameter for us */
+#define FD_SECTOR_LEN 512
+#define FD_SECTOR_SC  2   /* Sector size code */
+
+/* Floppy disk drive emulation */
+typedef enum fdisk_type_t {
+    FDRIVE_DISK_288   = 0x01, /* 2.88 MB disk           */
+    FDRIVE_DISK_144   = 0x02, /* 1.44 MB disk           */
+    FDRIVE_DISK_720   = 0x03, /* 720 kB disk            */
+    FDRIVE_DISK_USER  = 0x04, /* User defined geometry  */
+    FDRIVE_DISK_NONE  = 0x05, /* No disk                */
+} fdisk_type_t;
+
+typedef enum fdrive_type_t {
+    FDRIVE_DRV_144  = 0x00,   /* 1.44 MB 3"5 drive      */
+    FDRIVE_DRV_288  = 0x01,   /* 2.88 MB 3"5 drive      */
+    FDRIVE_DRV_120  = 0x02,   /* 1.2  MB 5"25 drive     */
+    FDRIVE_DRV_NONE = 0x03,   /* No drive connected     */
+} fdrive_type_t;
+
+typedef enum fdrive_flags_t {
+    FDRIVE_MOTOR_ON   = 0x01, /* motor on/off           */
+    FDRIVE_REVALIDATE = 0x02, /* Revalidated            */
+} fdrive_flags_t;
+
+typedef enum fdisk_flags_t {
+    FDISK_DBL_SIDES  = 0x01,
+} fdisk_flags_t;
+
+typedef struct fdrive_t {
+    BlockDriverState *bs;
+    /* Drive status */
+    fdrive_type_t drive;
+    fdrive_flags_t drflags;
+    uint8_t perpendicular;    /* 2.88 MB access mode    */
+    /* Position */
+    uint8_t head;
+    uint8_t track;
+    uint8_t sect;
+    /* Last operation status */
+    uint8_t dir;              /* Direction              */
+    uint8_t rw;               /* Read/write             */
+    /* Media */
+    fdisk_flags_t flags;
+    uint8_t last_sect;        /* Nb sector per track    */
+    uint8_t max_track;        /* Nb of tracks           */
+    uint16_t bps;             /* Bytes per sector       */
+    uint8_t ro;               /* Is read-only           */
+} fdrive_t;
+
+static void fd_init (fdrive_t *drv, BlockDriverState *bs)
+{
+    /* Drive */
+    drv->bs = bs;
+    drv->drive = FDRIVE_DRV_NONE;
+    drv->drflags = 0;
+    drv->perpendicular = 0;
+    /* Disk */
+    drv->last_sect = 0;
+    drv->max_track = 0;
+}
+
+static int _fd_sector (uint8_t head, uint8_t track,
+                        uint8_t sect, uint8_t last_sect)
+{
+    return (((track * 2) + head) * last_sect) + sect - 1;
+}
+
+/* Returns current position, in sectors, for given drive */
+static int fd_sector (fdrive_t *drv)
+{
+    return _fd_sector(drv->head, drv->track, drv->sect, drv->last_sect);
+}
+
+static int fd_seek (fdrive_t *drv, uint8_t head, uint8_t track, uint8_t sect,
+                    int enable_seek)
+{
+    uint32_t sector;
+    int ret;
+
+    if (track > drv->max_track ||
+       (head != 0 && (drv->flags & FDISK_DBL_SIDES) == 0)) {
+        FLOPPY_DPRINTF("try to read %d %02x %02x (max=%d %d %02x %02x)\n",
+                       head, track, sect, 1,
+                       (drv->flags & FDISK_DBL_SIDES) == 0 ? 0 : 1,
+                       drv->max_track, drv->last_sect);
+        return 2;
+    }
+    if (sect > drv->last_sect) {
+        FLOPPY_DPRINTF("try to read %d %02x %02x (max=%d %d %02x %02x)\n",
+                       head, track, sect, 1,
+                       (drv->flags & FDISK_DBL_SIDES) == 0 ? 0 : 1,
+                       drv->max_track, drv->last_sect);
+        return 3;
+    }
+    sector = _fd_sector(head, track, sect, drv->last_sect);
+    ret = 0;
+    if (sector != fd_sector(drv)) {
+#if 0
+        if (!enable_seek) {
+            FLOPPY_ERROR("no implicit seek %d %02x %02x (max=%d %02x %02x)\n",
+                         head, track, sect, 1, drv->max_track, drv->last_sect);
+            return 4;
+        }
+#endif
+        drv->head = head;
+       if (drv->track != track)
+           ret = 1;
+        drv->track = track;
+        drv->sect = sect;
+    }
+
+    return ret;
+}
+
+/* Set drive back to track 0 */
+static void fd_recalibrate (fdrive_t *drv)
+{
+    FLOPPY_DPRINTF("recalibrate\n");
+    drv->head = 0;
+    drv->track = 0;
+    drv->sect = 1;
+    drv->dir = 1;
+    drv->rw = 0;
+}
+
+/* Recognize floppy formats */
+typedef struct fd_format_t {
+    fdrive_type_t drive;
+    fdisk_type_t  disk;
+    uint8_t last_sect;
+    uint8_t max_track;
+    uint8_t max_head;
+    const unsigned char *str;
+} fd_format_t;
+
+static fd_format_t fd_formats[] = {
+    /* First entry is default format */
+    /* 1.44 MB 3"1/2 floppy disks */
+    { FDRIVE_DRV_144, FDRIVE_DISK_144, 18, 80, 1, "1.44 MB 3\"1/2", },
+    { FDRIVE_DRV_144, FDRIVE_DISK_144, 20, 80, 1,  "1.6 MB 3\"1/2", },
+    { FDRIVE_DRV_144, FDRIVE_DISK_144, 21, 80, 1, "1.68 MB 3\"1/2", },
+    { FDRIVE_DRV_144, FDRIVE_DISK_144, 21, 82, 1, "1.72 MB 3\"1/2", },
+    { FDRIVE_DRV_144, FDRIVE_DISK_144, 21, 83, 1, "1.74 MB 3\"1/2", },
+    { FDRIVE_DRV_144, FDRIVE_DISK_144, 22, 80, 1, "1.76 MB 3\"1/2", },
+    { FDRIVE_DRV_144, FDRIVE_DISK_144, 23, 80, 1, "1.84 MB 3\"1/2", },
+    { FDRIVE_DRV_144, FDRIVE_DISK_144, 24, 80, 1, "1.92 MB 3\"1/2", },
+    /* 2.88 MB 3"1/2 floppy disks */
+    { FDRIVE_DRV_288, FDRIVE_DISK_288, 36, 80, 1, "2.88 MB 3\"1/2", },
+    { FDRIVE_DRV_288, FDRIVE_DISK_288, 39, 80, 1, "3.12 MB 3\"1/2", },
+    { FDRIVE_DRV_288, FDRIVE_DISK_288, 40, 80, 1,  "3.2 MB 3\"1/2", },
+    { FDRIVE_DRV_288, FDRIVE_DISK_288, 44, 80, 1, "3.52 MB 3\"1/2", },
+    { FDRIVE_DRV_288, FDRIVE_DISK_288, 48, 80, 1, "3.84 MB 3\"1/2", },
+    /* 720 kB 3"1/2 floppy disks */
+    { FDRIVE_DRV_144, FDRIVE_DISK_720,  9, 80, 1,  "720 kB 3\"1/2", },
+    { FDRIVE_DRV_144, FDRIVE_DISK_720, 10, 80, 1,  "800 kB 3\"1/2", },
+    { FDRIVE_DRV_144, FDRIVE_DISK_720, 10, 82, 1,  "820 kB 3\"1/2", },
+    { FDRIVE_DRV_144, FDRIVE_DISK_720, 10, 83, 1,  "830 kB 3\"1/2", },
+    { FDRIVE_DRV_144, FDRIVE_DISK_720, 13, 80, 1, "1.04 MB 3\"1/2", },
+    { FDRIVE_DRV_144, FDRIVE_DISK_720, 14, 80, 1, "1.12 MB 3\"1/2", },
+    /* 1.2 MB 5"1/4 floppy disks */
+    { FDRIVE_DRV_120, FDRIVE_DISK_288, 15, 80, 1,  "1.2 kB 5\"1/4", },
+    { FDRIVE_DRV_120, FDRIVE_DISK_288, 18, 80, 1, "1.44 MB 5\"1/4", },
+    { FDRIVE_DRV_120, FDRIVE_DISK_288, 18, 82, 1, "1.48 MB 5\"1/4", },
+    { FDRIVE_DRV_120, FDRIVE_DISK_288, 18, 83, 1, "1.49 MB 5\"1/4", },
+    { FDRIVE_DRV_120, FDRIVE_DISK_288, 20, 80, 1,  "1.6 MB 5\"1/4", },
+    /* 720 kB 5"1/4 floppy disks */
+    { FDRIVE_DRV_120, FDRIVE_DISK_288,  9, 80, 1,  "720 kB 5\"1/4", },
+    { FDRIVE_DRV_120, FDRIVE_DISK_288, 11, 80, 1,  "880 kB 5\"1/4", },
+    /* 360 kB 5"1/4 floppy disks */
+    { FDRIVE_DRV_120, FDRIVE_DISK_288,  9, 40, 1,  "360 kB 5\"1/4", },
+    { FDRIVE_DRV_120, FDRIVE_DISK_288,  9, 40, 0,  "180 kB 5\"1/4", },
+    { FDRIVE_DRV_120, FDRIVE_DISK_288, 10, 41, 1,  "410 kB 5\"1/4", },
+    { FDRIVE_DRV_120, FDRIVE_DISK_288, 10, 42, 1,  "420 kB 5\"1/4", },
+    /* 320 kB 5"1/4 floppy disks */ 
+    { FDRIVE_DRV_120, FDRIVE_DISK_288,  8, 40, 1,  "320 kB 5\"1/4", },
+    { FDRIVE_DRV_120, FDRIVE_DISK_288,  8, 40, 0,  "160 kB 5\"1/4", },
+    /* 360 kB must match 5"1/4 better than 3"1/2... */
+    { FDRIVE_DRV_144, FDRIVE_DISK_720,  9, 80, 0,  "360 kB 3\"1/2", },
+    /* end */
+    { FDRIVE_DRV_NONE, FDRIVE_DISK_NONE, -1, -1, 0, NULL, },
+};
+
+/* Revalidate a disk drive after a disk change */
+static void fd_revalidate (fdrive_t *drv)
+{
+    fd_format_t *parse;
+    int64_t nb_sectors, size;
+    int i, first_match, match;
+    int nb_heads, max_track, last_sect, ro;
+
+    FLOPPY_DPRINTF("revalidate\n");
+    drv->drflags &= ~FDRIVE_REVALIDATE;
+    if (drv->bs != NULL && bdrv_is_inserted(drv->bs)) {
+       ro = bdrv_is_read_only(drv->bs);
+       bdrv_get_geometry_hint(drv->bs, &nb_heads, &max_track, &last_sect);
+       if (nb_heads != 0 && max_track != 0 && last_sect != 0) {
+           FLOPPY_DPRINTF("User defined disk (%d %d %d)",
+                           nb_heads - 1, max_track, last_sect);
+       } else {
+           bdrv_get_geometry(drv->bs, &nb_sectors);
+           match = -1;
+           first_match = -1;
+           for (i = 0;; i++) {
+               parse = &fd_formats[i];
+               if (parse->drive == FDRIVE_DRV_NONE)
+                   break;
+               if (drv->drive == parse->drive ||
+                   drv->drive == FDRIVE_DRV_NONE) {
+                   size = (parse->max_head + 1) * parse->max_track *
+                       parse->last_sect;
+                   if (nb_sectors == size) {
+                       match = i;
+                       break;
+                   }
+                   if (first_match == -1)
+                       first_match = i;
+               }
+           }
+           if (match == -1) {
+               if (first_match == -1)
+                   match = 1;
+               else
+                   match = first_match;
+               parse = &fd_formats[match];
+           }
+           nb_heads = parse->max_head + 1;
+           max_track = parse->max_track;
+           last_sect = parse->last_sect;
+           drv->drive = parse->drive;
+           FLOPPY_DPRINTF("%s floppy disk (%d h %d t %d s) %s\n", parse->str,
+                           nb_heads, max_track, last_sect, ro ? "ro" : "rw");
+       }
+           if (nb_heads == 1) {
+               drv->flags &= ~FDISK_DBL_SIDES;
+           } else {
+               drv->flags |= FDISK_DBL_SIDES;
+           }
+           drv->max_track = max_track;
+           drv->last_sect = last_sect;
+       drv->ro = ro;
+    } else {
+       FLOPPY_DPRINTF("No disk in drive\n");
+        drv->last_sect = 0;
+       drv->max_track = 0;
+       drv->flags &= ~FDISK_DBL_SIDES;
+    }
+    drv->drflags |= FDRIVE_REVALIDATE;
+}
+
+/* Motor control */
+static void fd_start (fdrive_t *drv)
+{
+    drv->drflags |= FDRIVE_MOTOR_ON;
+}
+
+static void fd_stop (fdrive_t *drv)
+{
+    drv->drflags &= ~FDRIVE_MOTOR_ON;
+}
+
+/* Re-initialise a drives (motor off, repositioned) */
+static void fd_reset (fdrive_t *drv)
+{
+    fd_stop(drv);
+    fd_recalibrate(drv);
+}
+
+/********************************************************/
+/* Intel 82078 floppy disk controller emulation          */
+
+static void fdctrl_reset (fdctrl_t *fdctrl, int do_irq);
+static void fdctrl_reset_fifo (fdctrl_t *fdctrl);
+static int fdctrl_transfer_handler (void *opaque, int nchan,
+                                    int dma_pos, int dma_len);
+static void fdctrl_raise_irq (fdctrl_t *fdctrl, uint8_t status);
+static void fdctrl_result_timer(void *opaque);
+
+static uint32_t fdctrl_read_statusB (fdctrl_t *fdctrl);
+static uint32_t fdctrl_read_dor (fdctrl_t *fdctrl);
+static void fdctrl_write_dor (fdctrl_t *fdctrl, uint32_t value);
+static uint32_t fdctrl_read_tape (fdctrl_t *fdctrl);
+static void fdctrl_write_tape (fdctrl_t *fdctrl, uint32_t value);
+static uint32_t fdctrl_read_main_status (fdctrl_t *fdctrl);
+static void fdctrl_write_rate (fdctrl_t *fdctrl, uint32_t value);
+static uint32_t fdctrl_read_data (fdctrl_t *fdctrl);
+static void fdctrl_write_data (fdctrl_t *fdctrl, uint32_t value);
+static uint32_t fdctrl_read_dir (fdctrl_t *fdctrl);
+
+enum {
+    FD_CTRL_ACTIVE = 0x01, /* XXX: suppress that */
+    FD_CTRL_RESET  = 0x02,
+    FD_CTRL_SLEEP  = 0x04, /* XXX: suppress that */
+    FD_CTRL_BUSY   = 0x08, /* dma transfer in progress */
+    FD_CTRL_INTR   = 0x10,
+};
+
+enum {
+    FD_DIR_WRITE   = 0,
+    FD_DIR_READ    = 1,
+    FD_DIR_SCANE   = 2,
+    FD_DIR_SCANL   = 3,
+    FD_DIR_SCANH   = 4,
+};
+
+enum {
+    FD_STATE_CMD    = 0x00,
+    FD_STATE_STATUS = 0x01,
+    FD_STATE_DATA   = 0x02,
+    FD_STATE_STATE  = 0x03,
+    FD_STATE_MULTI  = 0x10,
+    FD_STATE_SEEK   = 0x20,
+    FD_STATE_FORMAT = 0x40,
+};
+
+#define FD_STATE(state) ((state) & FD_STATE_STATE)
+#define FD_SET_STATE(state, new_state) \
+do { (state) = ((state) & ~FD_STATE_STATE) | (new_state); } while (0)
+#define FD_MULTI_TRACK(state) ((state) & FD_STATE_MULTI)
+#define FD_DID_SEEK(state) ((state) & FD_STATE_SEEK)
+#define FD_FORMAT_CMD(state) ((state) & FD_STATE_FORMAT)
+
+struct fdctrl_t {
+    fdctrl_t *fdctrl;
+    /* Controller's identification */
+    uint8_t version;
+    /* HW */
+    int irq_lvl;
+    int dma_chann;
+    uint32_t io_base;
+    /* Controller state */
+    QEMUTimer *result_timer;
+    uint8_t state;
+    uint8_t dma_en;
+    uint8_t cur_drv;
+    uint8_t bootsel;
+    /* Command FIFO */
+    uint8_t fifo[FD_SECTOR_LEN];
+    uint32_t data_pos;
+    uint32_t data_len;
+    uint8_t data_state;
+    uint8_t data_dir;
+    uint8_t int_status;
+    uint8_t eot; /* last wanted sector */
+    /* States kept only to be returned back */
+    /* Timers state */
+    uint8_t timer0;
+    uint8_t timer1;
+    /* precompensation */
+    uint8_t precomp_trk;
+    uint8_t config;
+    uint8_t lock;
+    /* Power down config (also with status regB access mode */
+    uint8_t pwrd;
+    /* Floppy drives */
+    fdrive_t drives[2];
+};
+
+static uint32_t fdctrl_read (void *opaque, uint32_t reg)
+{
+    fdctrl_t *fdctrl = opaque;
+    uint32_t retval;
+
+    switch (reg & 0x07) {
+    case 0x01:
+       retval = fdctrl_read_statusB(fdctrl);
+       break;
+    case 0x02:
+       retval = fdctrl_read_dor(fdctrl);
+       break;
+    case 0x03:
+        retval = fdctrl_read_tape(fdctrl);
+       break;
+    case 0x04:
+        retval = fdctrl_read_main_status(fdctrl);
+       break;
+    case 0x05:
+        retval = fdctrl_read_data(fdctrl);
+       break;
+    case 0x07:
+        retval = fdctrl_read_dir(fdctrl);
+       break;
+    default:
+       retval = (uint32_t)(-1);
+       break;
+    }
+    FLOPPY_DPRINTF("read reg%d: 0x%02x\n", reg & 7, retval);
+
+    return retval;
+}
+
+static void fdctrl_write (void *opaque, uint32_t reg, uint32_t value)
+{
+    fdctrl_t *fdctrl = opaque;
+
+    FLOPPY_DPRINTF("write reg%d: 0x%02x\n", reg & 7, value);
+
+    switch (reg & 0x07) {
+    case 0x02:
+       fdctrl_write_dor(fdctrl, value);
+       break;
+    case 0x03:
+        fdctrl_write_tape(fdctrl, value);
+       break;
+    case 0x04:
+        fdctrl_write_rate(fdctrl, value);
+       break;
+    case 0x05:
+        fdctrl_write_data(fdctrl, value);
+       break;
+    default:
+       break;
+    }
+}
+
+static void fd_change_cb (void *opaque)
+{
+    fdrive_t *drv = opaque;
+
+    FLOPPY_DPRINTF("disk change\n");
+    fd_revalidate(drv);
+#if 0
+    fd_recalibrate(drv);
+    fdctrl_reset_fifo(drv->fdctrl);
+    fdctrl_raise_irq(drv->fdctrl, 0x20);
+#endif
+}
+
+fdctrl_t *fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped, 
+                       uint32_t io_base,
+                       BlockDriverState **fds)
+{
+    fdctrl_t *fdctrl;
+//    int io_mem;
+    int i;
+
+    FLOPPY_DPRINTF("init controller\n");
+    fdctrl = qemu_mallocz(sizeof(fdctrl_t));
+    if (!fdctrl)
+        return NULL;
+    fdctrl->result_timer = qemu_new_timer(vm_clock, 
+                                          fdctrl_result_timer, fdctrl);
+
+    fdctrl->version = 0x90; /* Intel 82078 controller */
+    fdctrl->irq_lvl = irq_lvl;
+    fdctrl->dma_chann = dma_chann;
+    fdctrl->io_base = io_base;
+    fdctrl->config = 0x60; /* Implicit seek, polling & FIFO enabled */
+    if (fdctrl->dma_chann != -1) {
+        fdctrl->dma_en = 1;
+        DMA_register_channel(dma_chann, &fdctrl_transfer_handler, fdctrl);
+    } else {
+        fdctrl->dma_en = 0;
+    }
+    for (i = 0; i < 2; i++) {
+        fd_init(&fdctrl->drives[i], fds[i]);
+        if (fds[i]) {
+            bdrv_set_change_cb(fds[i],
+                               &fd_change_cb, &fdctrl->drives[i]);
+        }
+    }
+    fdctrl_reset(fdctrl, 0);
+    fdctrl->state = FD_CTRL_ACTIVE;
+    if (mem_mapped) {
+        FLOPPY_ERROR("memory mapped floppy not supported by now !\n");
+#if 0
+        io_mem = cpu_register_io_memory(0, fdctrl_mem_read, fdctrl_mem_write);
+        cpu_register_physical_memory(base, 0x08, io_mem);
+#endif
+    } else {
+        register_ioport_read(io_base + 0x01, 5, 1, &fdctrl_read, fdctrl);
+        register_ioport_read(io_base + 0x07, 1, 1, &fdctrl_read, fdctrl);
+        register_ioport_write(io_base + 0x01, 5, 1, &fdctrl_write, fdctrl);
+        register_ioport_write(io_base + 0x07, 1, 1, &fdctrl_write, fdctrl);
+    }
+    for (i = 0; i < 2; i++) {
+        fd_revalidate(&fdctrl->drives[i]);
+    }
+
+    return fdctrl;
+}
+
+/* XXX: may change if moved to bdrv */
+int fdctrl_get_drive_type(fdctrl_t *fdctrl, int drive_num)
+{
+    return fdctrl->drives[drive_num].drive;
+}
+
+/* Change IRQ state */
+static void fdctrl_reset_irq (fdctrl_t *fdctrl)
+{
+    FLOPPY_DPRINTF("Reset interrupt\n");
+    pic_set_irq(fdctrl->irq_lvl, 0);
+    fdctrl->state &= ~FD_CTRL_INTR;
+}
+
+static void fdctrl_raise_irq (fdctrl_t *fdctrl, uint8_t status)
+{
+    if (~(fdctrl->state & FD_CTRL_INTR)) {
+        pic_set_irq(fdctrl->irq_lvl, 1);
+        fdctrl->state |= FD_CTRL_INTR;
+    }
+    FLOPPY_DPRINTF("Set interrupt status to 0x%02x\n", status);
+    fdctrl->int_status = status;
+}
+
+/* Reset controller */
+static void fdctrl_reset (fdctrl_t *fdctrl, int do_irq)
+{
+    int i;
+
+    FLOPPY_DPRINTF("reset controller\n");
+    fdctrl_reset_irq(fdctrl);
+    /* Initialise controller */
+    fdctrl->cur_drv = 0;
+    /* FIFO state */
+    fdctrl->data_pos = 0;
+    fdctrl->data_len = 0;
+    fdctrl->data_state = FD_STATE_CMD;
+    fdctrl->data_dir = FD_DIR_WRITE;
+    for (i = 0; i < MAX_FD; i++)
+        fd_reset(&fdctrl->drives[i]);
+    fdctrl_reset_fifo(fdctrl);
+    if (do_irq)
+        fdctrl_raise_irq(fdctrl, 0xc0);
+}
+
+static inline fdrive_t *drv0 (fdctrl_t *fdctrl)
+{
+    return &fdctrl->drives[fdctrl->bootsel];
+}
+
+static inline fdrive_t *drv1 (fdctrl_t *fdctrl)
+{
+    return &fdctrl->drives[1 - fdctrl->bootsel];
+}
+
+static fdrive_t *get_cur_drv (fdctrl_t *fdctrl)
+{
+    return fdctrl->cur_drv == 0 ? drv0(fdctrl) : drv1(fdctrl);
+}
+
+/* Status B register : 0x01 (read-only) */
+static uint32_t fdctrl_read_statusB (fdctrl_t *fdctrl)
+{
+    FLOPPY_DPRINTF("status register: 0x00\n");
+    return 0;
+}
+
+/* Digital output register : 0x02 */
+static uint32_t fdctrl_read_dor (fdctrl_t *fdctrl)
+{
+    uint32_t retval = 0;
+
+    /* Drive motors state indicators */
+    if (drv0(fdctrl)->drflags & FDRIVE_MOTOR_ON)
+       retval |= 1 << 5;
+    if (drv1(fdctrl)->drflags & FDRIVE_MOTOR_ON)
+       retval |= 1 << 4;
+    /* DMA enable */
+    retval |= fdctrl->dma_en << 3;
+    /* Reset indicator */
+    retval |= (fdctrl->state & FD_CTRL_RESET) == 0 ? 0x04 : 0;
+    /* Selected drive */
+    retval |= fdctrl->cur_drv;
+    FLOPPY_DPRINTF("digital output register: 0x%02x\n", retval);
+
+    return retval;
+}
+
+static void fdctrl_write_dor (fdctrl_t *fdctrl, uint32_t value)
+{
+    /* Reset mode */
+    if (fdctrl->state & FD_CTRL_RESET) {
+        if (!(value & 0x04)) {
+            FLOPPY_DPRINTF("Floppy controller in RESET state !\n");
+            return;
+        }
+    }
+    FLOPPY_DPRINTF("digital output register set to 0x%02x\n", value);
+    /* Drive motors state indicators */
+    if (value & 0x20)
+        fd_start(drv1(fdctrl));
+    else
+        fd_stop(drv1(fdctrl));
+    if (value & 0x10)
+        fd_start(drv0(fdctrl));
+    else
+        fd_stop(drv0(fdctrl));
+    /* DMA enable */
+#if 0
+    if (fdctrl->dma_chann != -1)
+        fdctrl->dma_en = 1 - ((value >> 3) & 1);
+#endif
+    /* Reset */
+    if (!(value & 0x04)) {
+        if (!(fdctrl->state & FD_CTRL_RESET)) {
+            FLOPPY_DPRINTF("controller enter RESET state\n");
+            fdctrl->state |= FD_CTRL_RESET;
+        }
+    } else {
+        if (fdctrl->state & FD_CTRL_RESET) {
+            FLOPPY_DPRINTF("controller out of RESET state\n");
+            fdctrl_reset(fdctrl, 1);
+            fdctrl->state &= ~(FD_CTRL_RESET | FD_CTRL_SLEEP);
+        }
+    }
+    /* Selected drive */
+    fdctrl->cur_drv = value & 1;
+}
+
+/* Tape drive register : 0x03 */
+static uint32_t fdctrl_read_tape (fdctrl_t *fdctrl)
+{
+    uint32_t retval = 0;
+
+    /* Disk boot selection indicator */
+    retval |= fdctrl->bootsel << 2;
+    /* Tape indicators: never allowed */
+    FLOPPY_DPRINTF("tape drive register: 0x%02x\n", retval);
+
+    return retval;
+}
+
+static void fdctrl_write_tape (fdctrl_t *fdctrl, uint32_t value)
+{
+    /* Reset mode */
+    if (fdctrl->state & FD_CTRL_RESET) {
+        FLOPPY_DPRINTF("Floppy controller in RESET state !\n");
+        return;
+    }
+    FLOPPY_DPRINTF("tape drive register set to 0x%02x\n", value);
+    /* Disk boot selection indicator */
+    fdctrl->bootsel = (value >> 2) & 1;
+    /* Tape indicators: never allow */
+}
+
+/* Main status register : 0x04 (read) */
+static uint32_t fdctrl_read_main_status (fdctrl_t *fdctrl)
+{
+    uint32_t retval = 0;
+
+    fdctrl->state &= ~(FD_CTRL_SLEEP | FD_CTRL_RESET);
+    if (!(fdctrl->state & FD_CTRL_BUSY)) {
+        /* Data transfer allowed */
+        retval |= 0x80;
+        /* Data transfer direction indicator */
+        if (fdctrl->data_dir == FD_DIR_READ)
+            retval |= 0x40;
+    }
+    /* Should handle 0x20 for SPECIFY command */
+    /* Command busy indicator */
+    if (FD_STATE(fdctrl->data_state) == FD_STATE_DATA ||
+        FD_STATE(fdctrl->data_state) == FD_STATE_STATUS)
+        retval |= 0x10;
+    FLOPPY_DPRINTF("main status register: 0x%02x\n", retval);
+
+    return retval;
+}
+
+/* Data select rate register : 0x04 (write) */
+static void fdctrl_write_rate (fdctrl_t *fdctrl, uint32_t value)
+{
+    /* Reset mode */
+    if (fdctrl->state & FD_CTRL_RESET) {
+            FLOPPY_DPRINTF("Floppy controller in RESET state !\n");
+            return;
+        }
+    FLOPPY_DPRINTF("select rate register set to 0x%02x\n", value);
+    /* Reset: autoclear */
+    if (value & 0x80) {
+        fdctrl->state |= FD_CTRL_RESET;
+        fdctrl_reset(fdctrl, 1);
+        fdctrl->state &= ~FD_CTRL_RESET;
+    }
+    if (value & 0x40) {
+        fdctrl->state |= FD_CTRL_SLEEP;
+        fdctrl_reset(fdctrl, 1);
+    }
+//        fdctrl.precomp = (value >> 2) & 0x07;
+}
+
+/* Digital input register : 0x07 (read-only) */
+static uint32_t fdctrl_read_dir (fdctrl_t *fdctrl)
+{
+    uint32_t retval = 0;
+
+    if (drv0(fdctrl)->drflags & FDRIVE_REVALIDATE ||
+       drv1(fdctrl)->drflags & FDRIVE_REVALIDATE)
+        retval |= 0x80;
+    if (retval != 0)
+        FLOPPY_DPRINTF("Floppy digital input register: 0x%02x\n", retval);
+    drv0(fdctrl)->drflags &= ~FDRIVE_REVALIDATE;
+    drv1(fdctrl)->drflags &= ~FDRIVE_REVALIDATE;
+
+    return retval;
+}
+
+/* FIFO state control */
+static void fdctrl_reset_fifo (fdctrl_t *fdctrl)
+{
+    fdctrl->data_dir = FD_DIR_WRITE;
+    fdctrl->data_pos = 0;
+    FD_SET_STATE(fdctrl->data_state, FD_STATE_CMD);
+}
+
+/* Set FIFO status for the host to read */
+static void fdctrl_set_fifo (fdctrl_t *fdctrl, int fifo_len, int do_irq)
+{
+    fdctrl->data_dir = FD_DIR_READ;
+    fdctrl->data_len = fifo_len;
+    fdctrl->data_pos = 0;
+    FD_SET_STATE(fdctrl->data_state, FD_STATE_STATUS);
+    if (do_irq)
+        fdctrl_raise_irq(fdctrl, 0x00);
+}
+
+/* Set an error: unimplemented/unknown command */
+static void fdctrl_unimplemented (fdctrl_t *fdctrl)
+{
+#if 0
+    fdrive_t *cur_drv;
+
+    cur_drv = get_cur_drv(fdctrl);
+    fdctrl->fifo[0] = 0x60 | (cur_drv->head << 2) | fdctrl->cur_drv;
+    fdctrl->fifo[1] = 0x00;
+    fdctrl->fifo[2] = 0x00;
+    fdctrl_set_fifo(fdctrl, 3, 1);
+#else
+    //    fdctrl_reset_fifo(fdctrl);
+    fdctrl->fifo[0] = 0x80;
+    fdctrl_set_fifo(fdctrl, 1, 0);
+#endif
+}
+
+/* Callback for transfer end (stop or abort) */
+static void fdctrl_stop_transfer (fdctrl_t *fdctrl, uint8_t status0,
+                                 uint8_t status1, uint8_t status2)
+{
+    fdrive_t *cur_drv;
+
+    cur_drv = get_cur_drv(fdctrl);
+    FLOPPY_DPRINTF("transfer status: %02x %02x %02x (%02x)\n",
+                   status0, status1, status2,
+                   status0 | (cur_drv->head << 2) | fdctrl->cur_drv);
+    fdctrl->fifo[0] = status0 | (cur_drv->head << 2) | fdctrl->cur_drv;
+    fdctrl->fifo[1] = status1;
+    fdctrl->fifo[2] = status2;
+    fdctrl->fifo[3] = cur_drv->track;
+    fdctrl->fifo[4] = cur_drv->head;
+    fdctrl->fifo[5] = cur_drv->sect;
+    fdctrl->fifo[6] = FD_SECTOR_SC;
+    fdctrl->data_dir = FD_DIR_READ;
+    if (fdctrl->state & FD_CTRL_BUSY) {
+        DMA_release_DREQ(fdctrl->dma_chann);
+        fdctrl->state &= ~FD_CTRL_BUSY;
+    }
+    fdctrl_set_fifo(fdctrl, 7, 1);
+}
+
+/* Prepare a data transfer (either DMA or FIFO) */
+static void fdctrl_start_transfer (fdctrl_t *fdctrl, int direction)
+{
+    fdrive_t *cur_drv;
+    uint8_t kh, kt, ks;
+    int did_seek;
+
+    fdctrl->cur_drv = fdctrl->fifo[1] & 1;
+    cur_drv = get_cur_drv(fdctrl);
+    kt = fdctrl->fifo[2];
+    kh = fdctrl->fifo[3];
+    ks = fdctrl->fifo[4];
+    FLOPPY_DPRINTF("Start transfer at %d %d %02x %02x (%d)\n",
+                   fdctrl->cur_drv, kh, kt, ks,
+                   _fd_sector(kh, kt, ks, cur_drv->last_sect));
+    did_seek = 0;
+    switch (fd_seek(cur_drv, kh, kt, ks, fdctrl->config & 0x40)) {
+    case 2:
+        /* sect too big */
+        fdctrl_stop_transfer(fdctrl, 0x40, 0x00, 0x00);
+        fdctrl->fifo[3] = kt;
+        fdctrl->fifo[4] = kh;
+        fdctrl->fifo[5] = ks;
+        return;
+    case 3:
+        /* track too big */
+        fdctrl_stop_transfer(fdctrl, 0x40, 0x80, 0x00);
+        fdctrl->fifo[3] = kt;
+        fdctrl->fifo[4] = kh;
+        fdctrl->fifo[5] = ks;
+        return;
+    case 4:
+        /* No seek enabled */
+        fdctrl_stop_transfer(fdctrl, 0x40, 0x00, 0x00);
+        fdctrl->fifo[3] = kt;
+        fdctrl->fifo[4] = kh;
+        fdctrl->fifo[5] = ks;
+        return;
+    case 1:
+        did_seek = 1;
+        break;
+    default:
+        break;
+    }
+    /* Set the FIFO state */
+    fdctrl->data_dir = direction;
+    fdctrl->data_pos = 0;
+    FD_SET_STATE(fdctrl->data_state, FD_STATE_DATA); /* FIFO ready for data */
+    if (fdctrl->fifo[0] & 0x80)
+        fdctrl->data_state |= FD_STATE_MULTI;
+    else
+        fdctrl->data_state &= ~FD_STATE_MULTI;
+    if (did_seek)
+        fdctrl->data_state |= FD_STATE_SEEK;
+    else
+        fdctrl->data_state &= ~FD_STATE_SEEK;
+    if (fdctrl->fifo[5] == 00) {
+        fdctrl->data_len = fdctrl->fifo[8];
+    } else {
+       int tmp;
+        fdctrl->data_len = 128 << fdctrl->fifo[5];
+        tmp = (cur_drv->last_sect - ks + 1);
+        if (fdctrl->fifo[0] & 0x80)
+            tmp += cur_drv->last_sect;
+       fdctrl->data_len *= tmp;
+    }
+    fdctrl->eot = fdctrl->fifo[6];
+    if (fdctrl->dma_en) {
+        int dma_mode;
+        /* DMA transfer are enabled. Check if DMA channel is well programmed */
+        dma_mode = DMA_get_channel_mode(fdctrl->dma_chann);
+        dma_mode = (dma_mode >> 2) & 3;
+        FLOPPY_DPRINTF("dma_mode=%d direction=%d (%d - %d)\n",
+                      dma_mode, direction,
+                       (128 << fdctrl->fifo[5]) *
+                      (cur_drv->last_sect - ks + 1), fdctrl->data_len);
+        if (((direction == FD_DIR_SCANE || direction == FD_DIR_SCANL ||
+              direction == FD_DIR_SCANH) && dma_mode == 0) ||
+            (direction == FD_DIR_WRITE && dma_mode == 2) ||
+            (direction == FD_DIR_READ && dma_mode == 1)) {
+            /* No access is allowed until DMA transfer has completed */
+            fdctrl->state |= FD_CTRL_BUSY;
+            /* Now, we just have to wait for the DMA controller to
+             * recall us...
+             */
+            DMA_hold_DREQ(fdctrl->dma_chann);
+            DMA_schedule(fdctrl->dma_chann);
+            return;
+        } else {
+           FLOPPY_ERROR("dma_mode=%d direction=%d\n", dma_mode, direction);
+        }
+    }
+    FLOPPY_DPRINTF("start non-DMA transfer\n");
+    /* IO based transfer: calculate len */
+    fdctrl_raise_irq(fdctrl, 0x00);
+
+    return;
+}
+
+/* Prepare a transfer of deleted data */
+static void fdctrl_start_transfer_del (fdctrl_t *fdctrl, int direction)
+{
+    /* We don't handle deleted data,
+     * so we don't return *ANYTHING*
+     */
+    fdctrl_stop_transfer(fdctrl, 0x60, 0x00, 0x00);
+}
+
+/* handlers for DMA transfers */
+static int fdctrl_transfer_handler (void *opaque, int nchan,
+                                    int dma_pos, int dma_len)
+{
+    fdctrl_t *fdctrl;
+    fdrive_t *cur_drv;
+    int len, start_pos, rel_pos;
+    uint8_t status0 = 0x00, status1 = 0x00, status2 = 0x00;
+
+    fdctrl = opaque;
+    if (!(fdctrl->state & FD_CTRL_BUSY)) {
+        FLOPPY_DPRINTF("Not in DMA transfer mode !\n");
+        return 0;
+    }
+    cur_drv = get_cur_drv(fdctrl);
+    if (fdctrl->data_dir == FD_DIR_SCANE || fdctrl->data_dir == FD_DIR_SCANL ||
+        fdctrl->data_dir == FD_DIR_SCANH)
+        status2 = 0x04;
+    if (dma_len > fdctrl->data_len)
+        dma_len = fdctrl->data_len;
+    if (cur_drv->bs == NULL) {
+       if (fdctrl->data_dir == FD_DIR_WRITE)
+           fdctrl_stop_transfer(fdctrl, 0x60, 0x00, 0x00);
+       else
+           fdctrl_stop_transfer(fdctrl, 0x40, 0x00, 0x00);
+       len = 0;
+        goto transfer_error;
+    }
+    rel_pos = fdctrl->data_pos % FD_SECTOR_LEN;
+    for (start_pos = fdctrl->data_pos; fdctrl->data_pos < dma_len;) {
+        len = dma_len - fdctrl->data_pos;
+        if (len + rel_pos > FD_SECTOR_LEN)
+            len = FD_SECTOR_LEN - rel_pos;
+        FLOPPY_DPRINTF("copy %d bytes (%d %d %d) %d pos %d %02x %02x "
+                       "(%d-0x%08x 0x%08x)\n", len, size, fdctrl->data_pos,
+                       fdctrl->data_len, fdctrl->cur_drv, cur_drv->head,
+                       cur_drv->track, cur_drv->sect, fd_sector(cur_drv),
+                       fd_sector(cur_drv) * 512, addr);
+        if (fdctrl->data_dir != FD_DIR_WRITE ||
+           len < FD_SECTOR_LEN || rel_pos != 0) {
+            /* READ & SCAN commands and realign to a sector for WRITE */
+            if (bdrv_read(cur_drv->bs, fd_sector(cur_drv),
+                         fdctrl->fifo, 1) < 0) {
+                FLOPPY_DPRINTF("Floppy: error getting sector %d\n",
+                               fd_sector(cur_drv));
+                /* Sure, image size is too small... */
+                memset(fdctrl->fifo, 0, FD_SECTOR_LEN);
+            }
+        }
+       switch (fdctrl->data_dir) {
+       case FD_DIR_READ:
+           /* READ commands */
+            DMA_write_memory (nchan, fdctrl->fifo + rel_pos,
+                              fdctrl->data_pos, len);
+/*         cpu_physical_memory_write(addr + fdctrl->data_pos, */
+/*                                   fdctrl->fifo + rel_pos, len); */
+           break;
+       case FD_DIR_WRITE:
+            /* WRITE commands */
+            DMA_read_memory (nchan, fdctrl->fifo + rel_pos,
+                             fdctrl->data_pos, len);
+/*             cpu_physical_memory_read(addr + fdctrl->data_pos, */
+/*                                  fdctrl->fifo + rel_pos, len); */
+            if (bdrv_write(cur_drv->bs, fd_sector(cur_drv),
+                          fdctrl->fifo, 1) < 0) {
+                FLOPPY_ERROR("writting sector %d\n", fd_sector(cur_drv));
+                fdctrl_stop_transfer(fdctrl, 0x60, 0x00, 0x00);
+                goto transfer_error;
+            }
+           break;
+       default:
+           /* SCAN commands */
+            {
+               uint8_t tmpbuf[FD_SECTOR_LEN];
+                int ret;
+                DMA_read_memory (nchan, tmpbuf, fdctrl->data_pos, len);
+/*                 cpu_physical_memory_read(addr + fdctrl->data_pos, */
+/*                                          tmpbuf, len); */
+                ret = memcmp(tmpbuf, fdctrl->fifo + rel_pos, len);
+                if (ret == 0) {
+                    status2 = 0x08;
+                    goto end_transfer;
+                }
+                if ((ret < 0 && fdctrl->data_dir == FD_DIR_SCANL) ||
+                    (ret > 0 && fdctrl->data_dir == FD_DIR_SCANH)) {
+                    status2 = 0x00;
+                    goto end_transfer;
+                }
+            }
+           break;
+        }
+       fdctrl->data_pos += len;
+       rel_pos = fdctrl->data_pos % FD_SECTOR_LEN;
+        if (rel_pos == 0) {
+            /* Seek to next sector */
+           FLOPPY_DPRINTF("seek to next sector (%d %02x %02x => %d) (%d)\n",
+                          cur_drv->head, cur_drv->track, cur_drv->sect,
+                          fd_sector(cur_drv),
+                          fdctrl->data_pos - size);
+            /* XXX: cur_drv->sect >= cur_drv->last_sect should be an
+               error in fact */
+            if (cur_drv->sect >= cur_drv->last_sect ||
+                cur_drv->sect == fdctrl->eot) {
+               cur_drv->sect = 1;
+               if (FD_MULTI_TRACK(fdctrl->data_state)) {
+                   if (cur_drv->head == 0 &&
+                       (cur_drv->flags & FDISK_DBL_SIDES) != 0) {      
+                        cur_drv->head = 1;
+                    } else {
+                        cur_drv->head = 0;
+                       cur_drv->track++;
+                       if ((cur_drv->flags & FDISK_DBL_SIDES) == 0)
+                           break;
+                    }
+                } else {
+                    cur_drv->track++;
+                    break;
+                }
+               FLOPPY_DPRINTF("seek to next track (%d %02x %02x => %d)\n",
+                              cur_drv->head, cur_drv->track,
+                              cur_drv->sect, fd_sector(cur_drv));
+            } else {
+                cur_drv->sect++;
+            }
+        }
+    }
+end_transfer:
+    len = fdctrl->data_pos - start_pos;
+    FLOPPY_DPRINTF("end transfer %d %d %d\n",
+                  fdctrl->data_pos, len, fdctrl->data_len);
+    if (fdctrl->data_dir == FD_DIR_SCANE ||
+        fdctrl->data_dir == FD_DIR_SCANL ||
+        fdctrl->data_dir == FD_DIR_SCANH)
+        status2 = 0x08;
+    if (FD_DID_SEEK(fdctrl->data_state))
+        status0 |= 0x20;
+    fdctrl->data_len -= len;
+    //    if (fdctrl->data_len == 0)
+    fdctrl_stop_transfer(fdctrl, status0, status1, status2);
+transfer_error:
+
+    return len;
+}
+
+/* Data register : 0x05 */
+static uint32_t fdctrl_read_data (fdctrl_t *fdctrl)
+{
+    fdrive_t *cur_drv;
+    uint32_t retval = 0;
+    int pos, len;
+
+    cur_drv = get_cur_drv(fdctrl);
+    fdctrl->state &= ~FD_CTRL_SLEEP;
+    if (FD_STATE(fdctrl->data_state) == FD_STATE_CMD) {
+        FLOPPY_ERROR("can't read data in CMD state\n");
+        return 0;
+    }
+    pos = fdctrl->data_pos;
+    if (FD_STATE(fdctrl->data_state) == FD_STATE_DATA) {
+        pos %= FD_SECTOR_LEN;
+        if (pos == 0) {
+            len = fdctrl->data_len - fdctrl->data_pos;
+            if (len > FD_SECTOR_LEN)
+                len = FD_SECTOR_LEN;
+            bdrv_read(cur_drv->bs, fd_sector(cur_drv),
+                      fdctrl->fifo, len);
+        }
+    }
+    retval = fdctrl->fifo[pos];
+    if (++fdctrl->data_pos == fdctrl->data_len) {
+        fdctrl->data_pos = 0;
+        /* Switch from transfer mode to status mode
+         * then from status mode to command mode
+         */
+        if (FD_STATE(fdctrl->data_state) == FD_STATE_DATA) {
+            fdctrl_stop_transfer(fdctrl, 0x20, 0x00, 0x00);
+        } else {
+            fdctrl_reset_fifo(fdctrl);
+            fdctrl_reset_irq(fdctrl);
+        }
+    }
+    FLOPPY_DPRINTF("data register: 0x%02x\n", retval);
+
+    return retval;
+}
+
+static void fdctrl_format_sector (fdctrl_t *fdctrl)
+{
+    fdrive_t *cur_drv;
+    uint8_t kh, kt, ks;
+    int did_seek;
+
+    fdctrl->cur_drv = fdctrl->fifo[1] & 1;
+    cur_drv = get_cur_drv(fdctrl);
+    kt = fdctrl->fifo[6];
+    kh = fdctrl->fifo[7];
+    ks = fdctrl->fifo[8];
+    FLOPPY_DPRINTF("format sector at %d %d %02x %02x (%d)\n",
+                   fdctrl->cur_drv, kh, kt, ks,
+                   _fd_sector(kh, kt, ks, cur_drv->last_sect));
+    did_seek = 0;
+    switch (fd_seek(cur_drv, kh, kt, ks, fdctrl->config & 0x40)) {
+    case 2:
+        /* sect too big */
+        fdctrl_stop_transfer(fdctrl, 0x40, 0x00, 0x00);
+        fdctrl->fifo[3] = kt;
+        fdctrl->fifo[4] = kh;
+        fdctrl->fifo[5] = ks;
+        return;
+    case 3:
+        /* track too big */
+        fdctrl_stop_transfer(fdctrl, 0x40, 0x80, 0x00);
+        fdctrl->fifo[3] = kt;
+        fdctrl->fifo[4] = kh;
+        fdctrl->fifo[5] = ks;
+        return;
+    case 4:
+        /* No seek enabled */
+        fdctrl_stop_transfer(fdctrl, 0x40, 0x00, 0x00);
+        fdctrl->fifo[3] = kt;
+        fdctrl->fifo[4] = kh;
+        fdctrl->fifo[5] = ks;
+        return;
+    case 1:
+        did_seek = 1;
+        fdctrl->data_state |= FD_STATE_SEEK;
+        break;
+    default:
+        break;
+    }
+    memset(fdctrl->fifo, 0, FD_SECTOR_LEN);
+    if (cur_drv->bs == NULL ||
+        bdrv_write(cur_drv->bs, fd_sector(cur_drv), fdctrl->fifo, 1) < 0) {
+        FLOPPY_ERROR("formating sector %d\n", fd_sector(cur_drv));
+        fdctrl_stop_transfer(fdctrl, 0x60, 0x00, 0x00);
+    } else {
+       if (cur_drv->sect == cur_drv->last_sect) {
+           fdctrl->data_state &= ~FD_STATE_FORMAT;
+           /* Last sector done */
+           if (FD_DID_SEEK(fdctrl->data_state))
+               fdctrl_stop_transfer(fdctrl, 0x20, 0x00, 0x00);
+           else
+               fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
+       } else {
+           /* More to do */
+           fdctrl->data_pos = 0;
+           fdctrl->data_len = 4;
+       }
+    }
+}
+
+static void fdctrl_write_data (fdctrl_t *fdctrl, uint32_t value)
+{
+    fdrive_t *cur_drv;
+
+    cur_drv = get_cur_drv(fdctrl);
+    /* Reset mode */
+    if (fdctrl->state & FD_CTRL_RESET) {
+        FLOPPY_DPRINTF("Floppy controller in RESET state !\n");
+        return;
+    }
+    fdctrl->state &= ~FD_CTRL_SLEEP;
+    if (FD_STATE(fdctrl->data_state) == FD_STATE_STATUS) {
+        FLOPPY_ERROR("can't write data in status mode\n");
+        return;
+    }
+    /* Is it write command time ? */
+    if (FD_STATE(fdctrl->data_state) == FD_STATE_DATA) {
+        /* FIFO data write */
+        fdctrl->fifo[fdctrl->data_pos++] = value;
+        if (fdctrl->data_pos % FD_SECTOR_LEN == (FD_SECTOR_LEN - 1) ||
+            fdctrl->data_pos == fdctrl->data_len) {
+            bdrv_write(cur_drv->bs, fd_sector(cur_drv),
+                       fdctrl->fifo, FD_SECTOR_LEN);
+        }
+        /* Switch from transfer mode to status mode
+         * then from status mode to command mode
+         */
+        if (FD_STATE(fdctrl->data_state) == FD_STATE_DATA)
+            fdctrl_stop_transfer(fdctrl, 0x20, 0x00, 0x00);
+        return;
+    }
+    if (fdctrl->data_pos == 0) {
+        /* Command */
+        switch (value & 0x5F) {
+        case 0x46:
+            /* READ variants */
+            FLOPPY_DPRINTF("READ command\n");
+            /* 8 parameters cmd */
+            fdctrl->data_len = 9;
+            goto enqueue;
+        case 0x4C:
+            /* READ_DELETED variants */
+            FLOPPY_DPRINTF("READ_DELETED command\n");
+            /* 8 parameters cmd */
+            fdctrl->data_len = 9;
+            goto enqueue;
+        case 0x50:
+            /* SCAN_EQUAL variants */
+            FLOPPY_DPRINTF("SCAN_EQUAL command\n");
+            /* 8 parameters cmd */
+            fdctrl->data_len = 9;
+            goto enqueue;
+        case 0x56:
+            /* VERIFY variants */
+            FLOPPY_DPRINTF("VERIFY command\n");
+            /* 8 parameters cmd */
+            fdctrl->data_len = 9;
+            goto enqueue;
+        case 0x59:
+            /* SCAN_LOW_OR_EQUAL variants */
+            FLOPPY_DPRINTF("SCAN_LOW_OR_EQUAL command\n");
+            /* 8 parameters cmd */
+            fdctrl->data_len = 9;
+            goto enqueue;
+        case 0x5D:
+            /* SCAN_HIGH_OR_EQUAL variants */
+            FLOPPY_DPRINTF("SCAN_HIGH_OR_EQUAL command\n");
+            /* 8 parameters cmd */
+            fdctrl->data_len = 9;
+            goto enqueue;
+        default:
+            break;
+        }
+        switch (value & 0x7F) {
+        case 0x45:
+            /* WRITE variants */
+            FLOPPY_DPRINTF("WRITE command\n");
+            /* 8 parameters cmd */
+            fdctrl->data_len = 9;
+            goto enqueue;
+        case 0x49:
+            /* WRITE_DELETED variants */
+            FLOPPY_DPRINTF("WRITE_DELETED command\n");
+            /* 8 parameters cmd */
+            fdctrl->data_len = 9;
+            goto enqueue;
+        default:
+            break;
+        }
+        switch (value) {
+        case 0x03:
+            /* SPECIFY */
+            FLOPPY_DPRINTF("SPECIFY command\n");
+            /* 1 parameter cmd */
+            fdctrl->data_len = 3;
+            goto enqueue;
+        case 0x04:
+            /* SENSE_DRIVE_STATUS */
+            FLOPPY_DPRINTF("SENSE_DRIVE_STATUS command\n");
+            /* 1 parameter cmd */
+            fdctrl->data_len = 2;
+            goto enqueue;
+        case 0x07:
+            /* RECALIBRATE */
+            FLOPPY_DPRINTF("RECALIBRATE command\n");
+            /* 1 parameter cmd */
+            fdctrl->data_len = 2;
+            goto enqueue;
+        case 0x08:
+            /* SENSE_INTERRUPT_STATUS */
+            FLOPPY_DPRINTF("SENSE_INTERRUPT_STATUS command (%02x)\n",
+                           fdctrl->int_status);
+            /* No parameters cmd: returns status if no interrupt */
+#if 0
+            fdctrl->fifo[0] =
+                fdctrl->int_status | (cur_drv->head << 2) | fdctrl->cur_drv;
+#else
+            /* XXX: int_status handling is broken for read/write
+               commands, so we do this hack. It should be suppressed
+               ASAP */
+            fdctrl->fifo[0] =
+                0x20 | (cur_drv->head << 2) | fdctrl->cur_drv;
+#endif
+            fdctrl->fifo[1] = cur_drv->track;
+            fdctrl_set_fifo(fdctrl, 2, 0);
+           fdctrl_reset_irq(fdctrl);
+           fdctrl->int_status = 0xC0;
+            return;
+        case 0x0E:
+            /* DUMPREG */
+            FLOPPY_DPRINTF("DUMPREG command\n");
+            /* Drives position */
+            fdctrl->fifo[0] = drv0(fdctrl)->track;
+            fdctrl->fifo[1] = drv1(fdctrl)->track;
+            fdctrl->fifo[2] = 0;
+            fdctrl->fifo[3] = 0;
+            /* timers */
+            fdctrl->fifo[4] = fdctrl->timer0;
+            fdctrl->fifo[5] = (fdctrl->timer1 << 1) | fdctrl->dma_en;
+            fdctrl->fifo[6] = cur_drv->last_sect;
+            fdctrl->fifo[7] = (fdctrl->lock << 7) |
+                    (cur_drv->perpendicular << 2);
+            fdctrl->fifo[8] = fdctrl->config;
+            fdctrl->fifo[9] = fdctrl->precomp_trk;
+            fdctrl_set_fifo(fdctrl, 10, 0);
+            return;
+        case 0x0F:
+            /* SEEK */
+            FLOPPY_DPRINTF("SEEK command\n");
+            /* 2 parameters cmd */
+            fdctrl->data_len = 3;
+            goto enqueue;
+        case 0x10:
+            /* VERSION */
+            FLOPPY_DPRINTF("VERSION command\n");
+            /* No parameters cmd */
+            /* Controller's version */
+            fdctrl->fifo[0] = fdctrl->version;
+            fdctrl_set_fifo(fdctrl, 1, 1);
+            return;
+        case 0x12:
+            /* PERPENDICULAR_MODE */
+            FLOPPY_DPRINTF("PERPENDICULAR_MODE command\n");
+            /* 1 parameter cmd */
+            fdctrl->data_len = 2;
+            goto enqueue;
+        case 0x13:
+            /* CONFIGURE */
+            FLOPPY_DPRINTF("CONFIGURE command\n");
+            /* 3 parameters cmd */
+            fdctrl->data_len = 4;
+            goto enqueue;
+        case 0x14:
+            /* UNLOCK */
+            FLOPPY_DPRINTF("UNLOCK command\n");
+            /* No parameters cmd */
+            fdctrl->lock = 0;
+            fdctrl->fifo[0] = 0;
+            fdctrl_set_fifo(fdctrl, 1, 0);
+            return;
+        case 0x17:
+            /* POWERDOWN_MODE */
+            FLOPPY_DPRINTF("POWERDOWN_MODE command\n");
+            /* 2 parameters cmd */
+            fdctrl->data_len = 3;
+            goto enqueue;
+        case 0x18:
+            /* PART_ID */
+            FLOPPY_DPRINTF("PART_ID command\n");
+            /* No parameters cmd */
+            fdctrl->fifo[0] = 0x41; /* Stepping 1 */
+            fdctrl_set_fifo(fdctrl, 1, 0);
+            return;
+        case 0x2C:
+            /* SAVE */
+            FLOPPY_DPRINTF("SAVE command\n");
+            /* No parameters cmd */
+            fdctrl->fifo[0] = 0;
+            fdctrl->fifo[1] = 0;
+            /* Drives position */
+            fdctrl->fifo[2] = drv0(fdctrl)->track;
+            fdctrl->fifo[3] = drv1(fdctrl)->track;
+            fdctrl->fifo[4] = 0;
+            fdctrl->fifo[5] = 0;
+            /* timers */
+            fdctrl->fifo[6] = fdctrl->timer0;
+            fdctrl->fifo[7] = fdctrl->timer1;
+            fdctrl->fifo[8] = cur_drv->last_sect;
+            fdctrl->fifo[9] = (fdctrl->lock << 7) |
+                    (cur_drv->perpendicular << 2);
+            fdctrl->fifo[10] = fdctrl->config;
+            fdctrl->fifo[11] = fdctrl->precomp_trk;
+            fdctrl->fifo[12] = fdctrl->pwrd;
+            fdctrl->fifo[13] = 0;
+            fdctrl->fifo[14] = 0;
+            fdctrl_set_fifo(fdctrl, 15, 1);
+            return;
+        case 0x33:
+            /* OPTION */
+            FLOPPY_DPRINTF("OPTION command\n");
+            /* 1 parameter cmd */
+            fdctrl->data_len = 2;
+            goto enqueue;
+        case 0x42:
+            /* READ_TRACK */
+            FLOPPY_DPRINTF("READ_TRACK command\n");
+            /* 8 parameters cmd */
+            fdctrl->data_len = 9;
+            goto enqueue;
+        case 0x4A:
+            /* READ_ID */
+            FLOPPY_DPRINTF("READ_ID command\n");
+            /* 1 parameter cmd */
+            fdctrl->data_len = 2;
+            goto enqueue;
+        case 0x4C:
+            /* RESTORE */
+            FLOPPY_DPRINTF("RESTORE command\n");
+            /* 17 parameters cmd */
+            fdctrl->data_len = 18;
+            goto enqueue;
+        case 0x4D:
+            /* FORMAT_TRACK */
+            FLOPPY_DPRINTF("FORMAT_TRACK command\n");
+            /* 5 parameters cmd */
+            fdctrl->data_len = 6;
+            goto enqueue;
+        case 0x8E:
+            /* DRIVE_SPECIFICATION_COMMAND */
+            FLOPPY_DPRINTF("DRIVE_SPECIFICATION_COMMAND command\n");
+            /* 5 parameters cmd */
+            fdctrl->data_len = 6;
+            goto enqueue;
+        case 0x8F:
+            /* RELATIVE_SEEK_OUT */
+            FLOPPY_DPRINTF("RELATIVE_SEEK_OUT command\n");
+            /* 2 parameters cmd */
+            fdctrl->data_len = 3;
+            goto enqueue;
+        case 0x94:
+            /* LOCK */
+            FLOPPY_DPRINTF("LOCK command\n");
+            /* No parameters cmd */
+            fdctrl->lock = 1;
+            fdctrl->fifo[0] = 0x10;
+            fdctrl_set_fifo(fdctrl, 1, 1);
+            return;
+        case 0xCD:
+            /* FORMAT_AND_WRITE */
+            FLOPPY_DPRINTF("FORMAT_AND_WRITE command\n");
+            /* 10 parameters cmd */
+            fdctrl->data_len = 11;
+            goto enqueue;
+        case 0xCF:
+            /* RELATIVE_SEEK_IN */
+            FLOPPY_DPRINTF("RELATIVE_SEEK_IN command\n");
+            /* 2 parameters cmd */
+            fdctrl->data_len = 3;
+            goto enqueue;
+        default:
+            /* Unknown command */
+            FLOPPY_ERROR("unknown command: 0x%02x\n", value);
+            fdctrl_unimplemented(fdctrl);
+            return;
+        }
+    }
+enqueue:
+    FLOPPY_DPRINTF("%s: %02x\n", __func__, value);
+    fdctrl->fifo[fdctrl->data_pos] = value;
+    if (++fdctrl->data_pos == fdctrl->data_len) {
+        /* We now have all parameters
+         * and will be able to treat the command
+         */
+       if (fdctrl->data_state & FD_STATE_FORMAT) {
+           fdctrl_format_sector(fdctrl);
+           return;
+       }
+        switch (fdctrl->fifo[0] & 0x1F) {
+        case 0x06:
+        {
+            /* READ variants */
+            FLOPPY_DPRINTF("treat READ command\n");
+            fdctrl_start_transfer(fdctrl, FD_DIR_READ);
+            return;
+        }
+        case 0x0C:
+            /* READ_DELETED variants */
+//            FLOPPY_DPRINTF("treat READ_DELETED command\n");
+            FLOPPY_ERROR("treat READ_DELETED command\n");
+            fdctrl_start_transfer_del(fdctrl, FD_DIR_READ);
+            return;
+        case 0x16:
+            /* VERIFY variants */
+//            FLOPPY_DPRINTF("treat VERIFY command\n");
+            FLOPPY_ERROR("treat VERIFY command\n");
+            fdctrl_stop_transfer(fdctrl, 0x20, 0x00, 0x00);
+            return;
+        case 0x10:
+            /* SCAN_EQUAL variants */
+//            FLOPPY_DPRINTF("treat SCAN_EQUAL command\n");
+            FLOPPY_ERROR("treat SCAN_EQUAL command\n");
+            fdctrl_start_transfer(fdctrl, FD_DIR_SCANE);
+            return;
+        case 0x19:
+            /* SCAN_LOW_OR_EQUAL variants */
+//            FLOPPY_DPRINTF("treat SCAN_LOW_OR_EQUAL command\n");
+            FLOPPY_ERROR("treat SCAN_LOW_OR_EQUAL command\n");
+            fdctrl_start_transfer(fdctrl, FD_DIR_SCANL);
+            return;
+        case 0x1D:
+            /* SCAN_HIGH_OR_EQUAL variants */
+//            FLOPPY_DPRINTF("treat SCAN_HIGH_OR_EQUAL command\n");
+            FLOPPY_ERROR("treat SCAN_HIGH_OR_EQUAL command\n");
+            fdctrl_start_transfer(fdctrl, FD_DIR_SCANH);
+            return;
+        default:
+            break;
+        }
+        switch (fdctrl->fifo[0] & 0x3F) {
+        case 0x05:
+            /* WRITE variants */
+            FLOPPY_DPRINTF("treat WRITE command (%02x)\n", fdctrl->fifo[0]);
+            fdctrl_start_transfer(fdctrl, FD_DIR_WRITE);
+            return;
+        case 0x09:
+            /* WRITE_DELETED variants */
+//            FLOPPY_DPRINTF("treat WRITE_DELETED command\n");
+            FLOPPY_ERROR("treat WRITE_DELETED command\n");
+            fdctrl_start_transfer_del(fdctrl, FD_DIR_WRITE);
+            return;
+        default:
+            break;
+        }
+        switch (fdctrl->fifo[0]) {
+        case 0x03:
+            /* SPECIFY */
+            FLOPPY_DPRINTF("treat SPECIFY command\n");
+            fdctrl->timer0 = (fdctrl->fifo[1] >> 4) & 0xF;
+            fdctrl->timer1 = fdctrl->fifo[2] >> 1;
+           fdctrl->dma_en = 1 - (fdctrl->fifo[2] & 1) ;
+            /* No result back */
+            fdctrl_reset_fifo(fdctrl);
+            break;
+        case 0x04:
+            /* SENSE_DRIVE_STATUS */
+            FLOPPY_DPRINTF("treat SENSE_DRIVE_STATUS command\n");
+            fdctrl->cur_drv = fdctrl->fifo[1] & 1;
+           cur_drv = get_cur_drv(fdctrl);
+            cur_drv->head = (fdctrl->fifo[1] >> 2) & 1;
+            /* 1 Byte status back */
+            fdctrl->fifo[0] = (cur_drv->ro << 6) |
+                (cur_drv->track == 0 ? 0x10 : 0x00) |
+                (cur_drv->head << 2) |
+                fdctrl->cur_drv |
+                0x28;
+            fdctrl_set_fifo(fdctrl, 1, 0);
+            break;
+        case 0x07:
+            /* RECALIBRATE */
+            FLOPPY_DPRINTF("treat RECALIBRATE command\n");
+            fdctrl->cur_drv = fdctrl->fifo[1] & 1;
+           cur_drv = get_cur_drv(fdctrl);
+            fd_recalibrate(cur_drv);
+           fdctrl_reset_fifo(fdctrl);
+            /* Raise Interrupt */
+           fdctrl_raise_irq(fdctrl, 0x20);
+            break;
+        case 0x0F:
+            /* SEEK */
+            FLOPPY_DPRINTF("treat SEEK command\n");
+            fdctrl->cur_drv = fdctrl->fifo[1] & 1;
+           cur_drv = get_cur_drv(fdctrl);
+           fd_start(cur_drv);
+            if (fdctrl->fifo[2] <= cur_drv->track)
+                cur_drv->dir = 1;
+            else
+                cur_drv->dir = 0;
+           fdctrl_reset_fifo(fdctrl);
+            if (fdctrl->fifo[2] > cur_drv->max_track) {
+                fdctrl_raise_irq(fdctrl, 0x60);
+            } else {
+                cur_drv->track = fdctrl->fifo[2];
+                /* Raise Interrupt */
+                fdctrl_raise_irq(fdctrl, 0x20);
+            }
+            break;
+        case 0x12:
+            /* PERPENDICULAR_MODE */
+            FLOPPY_DPRINTF("treat PERPENDICULAR_MODE command\n");
+            if (fdctrl->fifo[1] & 0x80)
+                cur_drv->perpendicular = fdctrl->fifo[1] & 0x7;
+            /* No result back */
+            fdctrl_reset_fifo(fdctrl);
+            break;
+        case 0x13:
+            /* CONFIGURE */
+            FLOPPY_DPRINTF("treat CONFIGURE command\n");
+            fdctrl->config = fdctrl->fifo[2];
+            fdctrl->precomp_trk =  fdctrl->fifo[3];
+            /* No result back */
+            fdctrl_reset_fifo(fdctrl);
+            break;
+        case 0x17:
+            /* POWERDOWN_MODE */
+            FLOPPY_DPRINTF("treat POWERDOWN_MODE command\n");
+            fdctrl->pwrd = fdctrl->fifo[1];
+            fdctrl->fifo[0] = fdctrl->fifo[1];
+            fdctrl_set_fifo(fdctrl, 1, 1);
+            break;
+        case 0x33:
+            /* OPTION */
+            FLOPPY_DPRINTF("treat OPTION command\n");
+            /* No result back */
+            fdctrl_reset_fifo(fdctrl);
+            break;
+        case 0x42:
+            /* READ_TRACK */
+//            FLOPPY_DPRINTF("treat READ_TRACK command\n");
+            FLOPPY_ERROR("treat READ_TRACK command\n");
+            fdctrl_start_transfer(fdctrl, FD_DIR_READ);
+            break;
+        case 0x4A:
+                /* READ_ID */
+            FLOPPY_DPRINTF("treat READ_ID command\n");
+            /* XXX: should set main status register to busy */
+            cur_drv->head = (fdctrl->fifo[1] >> 2) & 1;
+            qemu_mod_timer(fdctrl->result_timer, 
+                           qemu_get_clock(vm_clock) + (ticks_per_sec / 50));
+            break;
+        case 0x4C:
+            /* RESTORE */
+            FLOPPY_DPRINTF("treat RESTORE command\n");
+            /* Drives position */
+            drv0(fdctrl)->track = fdctrl->fifo[3];
+            drv1(fdctrl)->track = fdctrl->fifo[4];
+            /* timers */
+            fdctrl->timer0 = fdctrl->fifo[7];
+            fdctrl->timer1 = fdctrl->fifo[8];
+            cur_drv->last_sect = fdctrl->fifo[9];
+            fdctrl->lock = fdctrl->fifo[10] >> 7;
+            cur_drv->perpendicular = (fdctrl->fifo[10] >> 2) & 0xF;
+            fdctrl->config = fdctrl->fifo[11];
+            fdctrl->precomp_trk = fdctrl->fifo[12];
+            fdctrl->pwrd = fdctrl->fifo[13];
+            fdctrl_reset_fifo(fdctrl);
+            break;
+        case 0x4D:
+            /* FORMAT_TRACK */
+           FLOPPY_DPRINTF("treat FORMAT_TRACK command\n");
+           fdctrl->cur_drv = fdctrl->fifo[1] & 1;
+           cur_drv = get_cur_drv(fdctrl);
+           fdctrl->data_state |= FD_STATE_FORMAT;
+           if (fdctrl->fifo[0] & 0x80)
+               fdctrl->data_state |= FD_STATE_MULTI;
+           else
+               fdctrl->data_state &= ~FD_STATE_MULTI;
+           fdctrl->data_state &= ~FD_STATE_SEEK;
+           cur_drv->bps =
+               fdctrl->fifo[2] > 7 ? 16384 : 128 << fdctrl->fifo[2];
+#if 0
+           cur_drv->last_sect =
+               cur_drv->flags & FDISK_DBL_SIDES ? fdctrl->fifo[3] :
+               fdctrl->fifo[3] / 2;
+#else
+           cur_drv->last_sect = fdctrl->fifo[3];
+#endif
+           /* Bochs BIOS is buggy and don't send format informations
+            * for each sector. So, pretend all's done right now...
+            */
+           fdctrl->data_state &= ~FD_STATE_FORMAT;
+           fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
+            break;
+        case 0x8E:
+            /* DRIVE_SPECIFICATION_COMMAND */
+            FLOPPY_DPRINTF("treat DRIVE_SPECIFICATION_COMMAND command\n");
+            if (fdctrl->fifo[fdctrl->data_pos - 1] & 0x80) {
+                /* Command parameters done */
+                if (fdctrl->fifo[fdctrl->data_pos - 1] & 0x40) {
+                    fdctrl->fifo[0] = fdctrl->fifo[1];
+                    fdctrl->fifo[2] = 0;
+                    fdctrl->fifo[3] = 0;
+                    fdctrl_set_fifo(fdctrl, 4, 1);
+                } else {
+                    fdctrl_reset_fifo(fdctrl);
+                }
+            } else if (fdctrl->data_len > 7) {
+                /* ERROR */
+                fdctrl->fifo[0] = 0x80 |
+                    (cur_drv->head << 2) | fdctrl->cur_drv;
+                fdctrl_set_fifo(fdctrl, 1, 1);
+            }
+            break;
+        case 0x8F:
+            /* RELATIVE_SEEK_OUT */
+            FLOPPY_DPRINTF("treat RELATIVE_SEEK_OUT command\n");
+            fdctrl->cur_drv = fdctrl->fifo[1] & 1;
+           cur_drv = get_cur_drv(fdctrl);
+           fd_start(cur_drv);
+                cur_drv->dir = 0;
+            if (fdctrl->fifo[2] + cur_drv->track >= cur_drv->max_track) {
+               cur_drv->track = cur_drv->max_track - 1;
+            } else {
+                cur_drv->track += fdctrl->fifo[2];
+            }
+           fdctrl_reset_fifo(fdctrl);
+           fdctrl_raise_irq(fdctrl, 0x20);
+            break;
+        case 0xCD:
+            /* FORMAT_AND_WRITE */
+//                FLOPPY_DPRINTF("treat FORMAT_AND_WRITE command\n");
+            FLOPPY_ERROR("treat FORMAT_AND_WRITE command\n");
+            fdctrl_unimplemented(fdctrl);
+            break;
+        case 0xCF:
+                /* RELATIVE_SEEK_IN */
+            FLOPPY_DPRINTF("treat RELATIVE_SEEK_IN command\n");
+            fdctrl->cur_drv = fdctrl->fifo[1] & 1;
+           cur_drv = get_cur_drv(fdctrl);
+           fd_start(cur_drv);
+                cur_drv->dir = 1;
+            if (fdctrl->fifo[2] > cur_drv->track) {
+               cur_drv->track = 0;
+            } else {
+                cur_drv->track -= fdctrl->fifo[2];
+            }
+           fdctrl_reset_fifo(fdctrl);
+           /* Raise Interrupt */
+           fdctrl_raise_irq(fdctrl, 0x20);
+            break;
+        }
+    }
+}
+
+static void fdctrl_result_timer(void *opaque)
+{
+    fdctrl_t *fdctrl = opaque;
+    fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
+}
diff --git a/tools/ioemu/hw/fmopl.c b/tools/ioemu/hw/fmopl.c
new file mode 100644 (file)
index 0000000..2b0e82b
--- /dev/null
@@ -0,0 +1,1390 @@
+/*
+**
+** File: fmopl.c -- software implementation of FM sound generator
+**
+** Copyright (C) 1999,2000 Tatsuyuki Satoh , MultiArcadeMachineEmurator development
+**
+** Version 0.37a
+**
+*/
+
+/*
+       preliminary :
+       Problem :
+       note:
+*/
+
+/* This version of fmopl.c is a fork of the MAME one, relicensed under the LGPL.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#define INLINE         __inline
+#define HAS_YM3812     1
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <math.h>
+//#include "driver.h"          /* use M.A.M.E. */
+#include "fmopl.h"
+
+#ifndef PI
+#define PI 3.14159265358979323846
+#endif
+
+/* -------------------- for debug --------------------- */
+/* #define OPL_OUTPUT_LOG */
+#ifdef OPL_OUTPUT_LOG
+static FILE *opl_dbg_fp = NULL;
+static FM_OPL *opl_dbg_opl[16];
+static int opl_dbg_maxchip,opl_dbg_chip;
+#endif
+
+/* -------------------- preliminary define section --------------------- */
+/* attack/decay rate time rate */
+#define OPL_ARRATE     141280  /* RATE 4 =  2826.24ms @ 3.6MHz */
+#define OPL_DRRATE    1956000  /* RATE 4 = 39280.64ms @ 3.6MHz */
+
+#define DELTAT_MIXING_LEVEL (1) /* DELTA-T ADPCM MIXING LEVEL */
+
+#define FREQ_BITS 24                   /* frequency turn          */
+
+/* counter bits = 20 , octerve 7 */
+#define FREQ_RATE   (1<<(FREQ_BITS-20))
+#define TL_BITS    (FREQ_BITS+2)
+
+/* final output shift , limit minimum and maximum */
+#define OPL_OUTSB   (TL_BITS+3-16)             /* OPL output final shift 16bit */
+#define OPL_MAXOUT (0x7fff<<OPL_OUTSB)
+#define OPL_MINOUT (-0x8000<<OPL_OUTSB)
+
+/* -------------------- quality selection --------------------- */
+
+/* sinwave entries */
+/* used static memory = SIN_ENT * 4 (byte) */
+#define SIN_ENT 2048
+
+/* output level entries (envelope,sinwave) */
+/* envelope counter lower bits */
+#define ENV_BITS 16
+/* envelope output entries */
+#define EG_ENT   4096
+/* used dynamic memory = EG_ENT*4*4(byte)or EG_ENT*6*4(byte) */
+/* used static  memory = EG_ENT*4 (byte)                     */
+
+#define EG_OFF   ((2*EG_ENT)<<ENV_BITS)  /* OFF          */
+#define EG_DED   EG_OFF
+#define EG_DST   (EG_ENT<<ENV_BITS)      /* DECAY  START */
+#define EG_AED   EG_DST
+#define EG_AST   0                       /* ATTACK START */
+
+#define EG_STEP (96.0/EG_ENT) /* OPL is 0.1875 dB step  */
+
+/* LFO table entries */
+#define VIB_ENT 512
+#define VIB_SHIFT (32-9)
+#define AMS_ENT 512
+#define AMS_SHIFT (32-9)
+
+#define VIB_RATE 256
+
+/* -------------------- local defines , macros --------------------- */
+
+/* register number to channel number , slot offset */
+#define SLOT1 0
+#define SLOT2 1
+
+/* envelope phase */
+#define ENV_MOD_RR  0x00
+#define ENV_MOD_DR  0x01
+#define ENV_MOD_AR  0x02
+
+/* -------------------- tables --------------------- */
+static const int slot_array[32]=
+{
+        0, 2, 4, 1, 3, 5,-1,-1,
+        6, 8,10, 7, 9,11,-1,-1,
+       12,14,16,13,15,17,-1,-1,
+       -1,-1,-1,-1,-1,-1,-1,-1
+};
+
+/* key scale level */
+/* table is 3dB/OCT , DV converts this in TL step at 6dB/OCT */
+#define DV (EG_STEP/2)
+static const UINT32 KSL_TABLE[8*16]=
+{
+       /* OCT 0 */
+        0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
+        0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
+        0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
+        0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
+       /* OCT 1 */
+        0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
+        0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
+        0.000/DV, 0.750/DV, 1.125/DV, 1.500/DV,
+        1.875/DV, 2.250/DV, 2.625/DV, 3.000/DV,
+       /* OCT 2 */
+        0.000/DV, 0.000/DV, 0.000/DV, 0.000/DV,
+        0.000/DV, 1.125/DV, 1.875/DV, 2.625/DV,
+        3.000/DV, 3.750/DV, 4.125/DV, 4.500/DV,
+        4.875/DV, 5.250/DV, 5.625/DV, 6.000/DV,
+       /* OCT 3 */
+        0.000/DV, 0.000/DV, 0.000/DV, 1.875/DV,
+        3.000/DV, 4.125/DV, 4.875/DV, 5.625/DV,
+        6.000/DV, 6.750/DV, 7.125/DV, 7.500/DV,
+        7.875/DV, 8.250/DV, 8.625/DV, 9.000/DV,
+       /* OCT 4 */
+        0.000/DV, 0.000/DV, 3.000/DV, 4.875/DV,
+        6.000/DV, 7.125/DV, 7.875/DV, 8.625/DV,
+        9.000/DV, 9.750/DV,10.125/DV,10.500/DV,
+       10.875/DV,11.250/DV,11.625/DV,12.000/DV,
+       /* OCT 5 */
+        0.000/DV, 3.000/DV, 6.000/DV, 7.875/DV,
+        9.000/DV,10.125/DV,10.875/DV,11.625/DV,
+       12.000/DV,12.750/DV,13.125/DV,13.500/DV,
+       13.875/DV,14.250/DV,14.625/DV,15.000/DV,
+       /* OCT 6 */
+        0.000/DV, 6.000/DV, 9.000/DV,10.875/DV,
+       12.000/DV,13.125/DV,13.875/DV,14.625/DV,
+       15.000/DV,15.750/DV,16.125/DV,16.500/DV,
+       16.875/DV,17.250/DV,17.625/DV,18.000/DV,
+       /* OCT 7 */
+        0.000/DV, 9.000/DV,12.000/DV,13.875/DV,
+       15.000/DV,16.125/DV,16.875/DV,17.625/DV,
+       18.000/DV,18.750/DV,19.125/DV,19.500/DV,
+       19.875/DV,20.250/DV,20.625/DV,21.000/DV
+};
+#undef DV
+
+/* sustain lebel table (3db per step) */
+/* 0 - 15: 0, 3, 6, 9,12,15,18,21,24,27,30,33,36,39,42,93 (dB)*/
+#define SC(db) (db*((3/EG_STEP)*(1<<ENV_BITS)))+EG_DST
+static const INT32 SL_TABLE[16]={
+ SC( 0),SC( 1),SC( 2),SC(3 ),SC(4 ),SC(5 ),SC(6 ),SC( 7),
+ SC( 8),SC( 9),SC(10),SC(11),SC(12),SC(13),SC(14),SC(31)
+};
+#undef SC
+
+#define TL_MAX (EG_ENT*2) /* limit(tl + ksr + envelope) + sinwave */
+/* TotalLevel : 48 24 12  6  3 1.5 0.75 (dB) */
+/* TL_TABLE[ 0      to TL_MAX          ] : plus  section */
+/* TL_TABLE[ TL_MAX to TL_MAX+TL_MAX-1 ] : minus section */
+static INT32 *TL_TABLE;
+
+/* pointers to TL_TABLE with sinwave output offset */
+static INT32 **SIN_TABLE;
+
+/* LFO table */
+static INT32 *AMS_TABLE;
+static INT32 *VIB_TABLE;
+
+/* envelope output curve table */
+/* attack + decay + OFF */
+static INT32 ENV_CURVE[2*EG_ENT+1];
+
+/* multiple table */
+#define ML 2
+static const UINT32 MUL_TABLE[16]= {
+/* 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15 */
+   0.50*ML, 1.00*ML, 2.00*ML, 3.00*ML, 4.00*ML, 5.00*ML, 6.00*ML, 7.00*ML,
+   8.00*ML, 9.00*ML,10.00*ML,10.00*ML,12.00*ML,12.00*ML,15.00*ML,15.00*ML
+};
+#undef ML
+
+/* dummy attack / decay rate ( when rate == 0 ) */
+static INT32 RATE_0[16]=
+{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+
+/* -------------------- static state --------------------- */
+
+/* lock level of common table */
+static int num_lock = 0;
+
+/* work table */
+static void *cur_chip = NULL;  /* current chip point */
+/* currenct chip state */
+/* static OPLSAMPLE  *bufL,*bufR; */
+static OPL_CH *S_CH;
+static OPL_CH *E_CH;
+OPL_SLOT *SLOT7_1,*SLOT7_2,*SLOT8_1,*SLOT8_2;
+
+static INT32 outd[1];
+static INT32 ams;
+static INT32 vib;
+INT32  *ams_table;
+INT32  *vib_table;
+static INT32 amsIncr;
+static INT32 vibIncr;
+static INT32 feedback2;                /* connect for SLOT 2 */
+
+/* log output level */
+#define LOG_ERR  3      /* ERROR       */
+#define LOG_WAR  2      /* WARNING     */
+#define LOG_INF  1      /* INFORMATION */
+
+//#define LOG_LEVEL LOG_INF
+#define LOG_LEVEL      LOG_ERR
+
+//#define LOG(n,x) if( (n)>=LOG_LEVEL ) logerror x
+#define LOG(n,x)
+
+/* --------------------- subroutines  --------------------- */
+
+INLINE int Limit( int val, int max, int min ) {
+       if ( val > max )
+               val = max;
+       else if ( val < min )
+               val = min;
+
+       return val;
+}
+
+/* status set and IRQ handling */
+INLINE void OPL_STATUS_SET(FM_OPL *OPL,int flag)
+{
+       /* set status flag */
+       OPL->status |= flag;
+       if(!(OPL->status & 0x80))
+       {
+               if(OPL->status & OPL->statusmask)
+               {       /* IRQ on */
+                       OPL->status |= 0x80;
+                       /* callback user interrupt handler (IRQ is OFF to ON) */
+                       if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,1);
+               }
+       }
+}
+
+/* status reset and IRQ handling */
+INLINE void OPL_STATUS_RESET(FM_OPL *OPL,int flag)
+{
+       /* reset status flag */
+       OPL->status &=~flag;
+       if((OPL->status & 0x80))
+       {
+               if (!(OPL->status & OPL->statusmask) )
+               {
+                       OPL->status &= 0x7f;
+                       /* callback user interrupt handler (IRQ is ON to OFF) */
+                       if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,0);
+               }
+       }
+}
+
+/* IRQ mask set */
+INLINE void OPL_STATUSMASK_SET(FM_OPL *OPL,int flag)
+{
+       OPL->statusmask = flag;
+       /* IRQ handling check */
+       OPL_STATUS_SET(OPL,0);
+       OPL_STATUS_RESET(OPL,0);
+}
+
+/* ----- key on  ----- */
+INLINE void OPL_KEYON(OPL_SLOT *SLOT)
+{
+       /* sin wave restart */
+       SLOT->Cnt = 0;
+       /* set attack */
+       SLOT->evm = ENV_MOD_AR;
+       SLOT->evs = SLOT->evsa;
+       SLOT->evc = EG_AST;
+       SLOT->eve = EG_AED;
+}
+/* ----- key off ----- */
+INLINE void OPL_KEYOFF(OPL_SLOT *SLOT)
+{
+       if( SLOT->evm > ENV_MOD_RR)
+       {
+               /* set envelope counter from envleope output */
+               SLOT->evm = ENV_MOD_RR;
+               if( !(SLOT->evc&EG_DST) )
+                       //SLOT->evc = (ENV_CURVE[SLOT->evc>>ENV_BITS]<<ENV_BITS) + EG_DST;
+                       SLOT->evc = EG_DST;
+               SLOT->eve = EG_DED;
+               SLOT->evs = SLOT->evsr;
+       }
+}
+
+/* ---------- calcrate Envelope Generator & Phase Generator ---------- */
+/* return : envelope output */
+INLINE UINT32 OPL_CALC_SLOT( OPL_SLOT *SLOT )
+{
+       /* calcrate envelope generator */
+       if( (SLOT->evc+=SLOT->evs) >= SLOT->eve )
+       {
+               switch( SLOT->evm ){
+               case ENV_MOD_AR: /* ATTACK -> DECAY1 */
+                       /* next DR */
+                       SLOT->evm = ENV_MOD_DR;
+                       SLOT->evc = EG_DST;
+                       SLOT->eve = SLOT->SL;
+                       SLOT->evs = SLOT->evsd;
+                       break;
+               case ENV_MOD_DR: /* DECAY -> SL or RR */
+                       SLOT->evc = SLOT->SL;
+                       SLOT->eve = EG_DED;
+                       if(SLOT->eg_typ)
+                       {
+                               SLOT->evs = 0;
+                       }
+                       else
+                       {
+                               SLOT->evm = ENV_MOD_RR;
+                               SLOT->evs = SLOT->evsr;
+                       }
+                       break;
+               case ENV_MOD_RR: /* RR -> OFF */
+                       SLOT->evc = EG_OFF;
+                       SLOT->eve = EG_OFF+1;
+                       SLOT->evs = 0;
+                       break;
+               }
+       }
+       /* calcrate envelope */
+       return SLOT->TLL+ENV_CURVE[SLOT->evc>>ENV_BITS]+(SLOT->ams ? ams : 0);
+}
+
+/* set algorythm connection */
+static void set_algorythm( OPL_CH *CH)
+{
+       INT32 *carrier = &outd[0];
+       CH->connect1 = CH->CON ? carrier : &feedback2;
+       CH->connect2 = carrier;
+}
+
+/* ---------- frequency counter for operater update ---------- */
+INLINE void CALC_FCSLOT(OPL_CH *CH,OPL_SLOT *SLOT)
+{
+       int ksr;
+
+       /* frequency step counter */
+       SLOT->Incr = CH->fc * SLOT->mul;
+       ksr = CH->kcode >> SLOT->KSR;
+
+       if( SLOT->ksr != ksr )
+       {
+               SLOT->ksr = ksr;
+               /* attack , decay rate recalcration */
+               SLOT->evsa = SLOT->AR[ksr];
+               SLOT->evsd = SLOT->DR[ksr];
+               SLOT->evsr = SLOT->RR[ksr];
+       }
+       SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl);
+}
+
+/* set multi,am,vib,EG-TYP,KSR,mul */
+INLINE void set_mul(FM_OPL *OPL,int slot,int v)
+{
+       OPL_CH   *CH   = &OPL->P_CH[slot/2];
+       OPL_SLOT *SLOT = &CH->SLOT[slot&1];
+
+       SLOT->mul    = MUL_TABLE[v&0x0f];
+       SLOT->KSR    = (v&0x10) ? 0 : 2;
+       SLOT->eg_typ = (v&0x20)>>5;
+       SLOT->vib    = (v&0x40);
+       SLOT->ams    = (v&0x80);
+       CALC_FCSLOT(CH,SLOT);
+}
+
+/* set ksl & tl */
+INLINE void set_ksl_tl(FM_OPL *OPL,int slot,int v)
+{
+       OPL_CH   *CH   = &OPL->P_CH[slot/2];
+       OPL_SLOT *SLOT = &CH->SLOT[slot&1];
+       int ksl = v>>6; /* 0 / 1.5 / 3 / 6 db/OCT */
+
+       SLOT->ksl = ksl ? 3-ksl : 31;
+       SLOT->TL  = (v&0x3f)*(0.75/EG_STEP); /* 0.75db step */
+
+       if( !(OPL->mode&0x80) )
+       {       /* not CSM latch total level */
+               SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl);
+       }
+}
+
+/* set attack rate & decay rate  */
+INLINE void set_ar_dr(FM_OPL *OPL,int slot,int v)
+{
+       OPL_CH   *CH   = &OPL->P_CH[slot/2];
+       OPL_SLOT *SLOT = &CH->SLOT[slot&1];
+       int ar = v>>4;
+       int dr = v&0x0f;
+
+       SLOT->AR = ar ? &OPL->AR_TABLE[ar<<2] : RATE_0;
+       SLOT->evsa = SLOT->AR[SLOT->ksr];
+       if( SLOT->evm == ENV_MOD_AR ) SLOT->evs = SLOT->evsa;
+
+       SLOT->DR = dr ? &OPL->DR_TABLE[dr<<2] : RATE_0;
+       SLOT->evsd = SLOT->DR[SLOT->ksr];
+       if( SLOT->evm == ENV_MOD_DR ) SLOT->evs = SLOT->evsd;
+}
+
+/* set sustain level & release rate */
+INLINE void set_sl_rr(FM_OPL *OPL,int slot,int v)
+{
+       OPL_CH   *CH   = &OPL->P_CH[slot/2];
+       OPL_SLOT *SLOT = &CH->SLOT[slot&1];
+       int sl = v>>4;
+       int rr = v & 0x0f;
+
+       SLOT->SL = SL_TABLE[sl];
+       if( SLOT->evm == ENV_MOD_DR ) SLOT->eve = SLOT->SL;
+       SLOT->RR = &OPL->DR_TABLE[rr<<2];
+       SLOT->evsr = SLOT->RR[SLOT->ksr];
+       if( SLOT->evm == ENV_MOD_RR ) SLOT->evs = SLOT->evsr;
+}
+
+/* operator output calcrator */
+#define OP_OUT(slot,env,con)   slot->wavetable[((slot->Cnt+con)/(0x1000000/SIN_ENT))&(SIN_ENT-1)][env]
+/* ---------- calcrate one of channel ---------- */
+INLINE void OPL_CALC_CH( OPL_CH *CH )
+{
+       UINT32 env_out;
+       OPL_SLOT *SLOT;
+
+       feedback2 = 0;
+       /* SLOT 1 */
+       SLOT = &CH->SLOT[SLOT1];
+       env_out=OPL_CALC_SLOT(SLOT);
+       if( env_out < EG_ENT-1 )
+       {
+               /* PG */
+               if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
+               else          SLOT->Cnt += SLOT->Incr;
+               /* connectoion */
+               if(CH->FB)
+               {
+                       int feedback1 = (CH->op1_out[0]+CH->op1_out[1])>>CH->FB;
+                       CH->op1_out[1] = CH->op1_out[0];
+                       *CH->connect1 += CH->op1_out[0] = OP_OUT(SLOT,env_out,feedback1);
+               }
+               else
+               {
+                       *CH->connect1 += OP_OUT(SLOT,env_out,0);
+               }
+       }else
+       {
+               CH->op1_out[1] = CH->op1_out[0];
+               CH->op1_out[0] = 0;
+       }
+       /* SLOT 2 */
+       SLOT = &CH->SLOT[SLOT2];
+       env_out=OPL_CALC_SLOT(SLOT);
+       if( env_out < EG_ENT-1 )
+       {
+               /* PG */
+               if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
+               else          SLOT->Cnt += SLOT->Incr;
+               /* connectoion */
+               outd[0] += OP_OUT(SLOT,env_out, feedback2);
+       }
+}
+
+/* ---------- calcrate rythm block ---------- */
+#define WHITE_NOISE_db 6.0
+INLINE void OPL_CALC_RH( OPL_CH *CH )
+{
+       UINT32 env_tam,env_sd,env_top,env_hh;
+       int whitenoise = (rand()&1)*(WHITE_NOISE_db/EG_STEP);
+       INT32 tone8;
+
+       OPL_SLOT *SLOT;
+       int env_out;
+
+       /* BD : same as FM serial mode and output level is large */
+       feedback2 = 0;
+       /* SLOT 1 */
+       SLOT = &CH[6].SLOT[SLOT1];
+       env_out=OPL_CALC_SLOT(SLOT);
+       if( env_out < EG_ENT-1 )
+       {
+               /* PG */
+               if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
+               else          SLOT->Cnt += SLOT->Incr;
+               /* connectoion */
+               if(CH[6].FB)
+               {
+                       int feedback1 = (CH[6].op1_out[0]+CH[6].op1_out[1])>>CH[6].FB;
+                       CH[6].op1_out[1] = CH[6].op1_out[0];
+                       feedback2 = CH[6].op1_out[0] = OP_OUT(SLOT,env_out,feedback1);
+               }
+               else
+               {
+                       feedback2 = OP_OUT(SLOT,env_out,0);
+               }
+       }else
+       {
+               feedback2 = 0;
+               CH[6].op1_out[1] = CH[6].op1_out[0];
+               CH[6].op1_out[0] = 0;
+       }
+       /* SLOT 2 */
+       SLOT = &CH[6].SLOT[SLOT2];
+       env_out=OPL_CALC_SLOT(SLOT);
+       if( env_out < EG_ENT-1 )
+       {
+               /* PG */
+               if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
+               else          SLOT->Cnt += SLOT->Incr;
+               /* connectoion */
+               outd[0] += OP_OUT(SLOT,env_out, feedback2)*2;
+       }
+
+       // SD  (17) = mul14[fnum7] + white noise
+       // TAM (15) = mul15[fnum8]
+       // TOP (18) = fnum6(mul18[fnum8]+whitenoise)
+       // HH  (14) = fnum7(mul18[fnum8]+whitenoise) + white noise
+       env_sd =OPL_CALC_SLOT(SLOT7_2) + whitenoise;
+       env_tam=OPL_CALC_SLOT(SLOT8_1);
+       env_top=OPL_CALC_SLOT(SLOT8_2);
+       env_hh =OPL_CALC_SLOT(SLOT7_1) + whitenoise;
+
+       /* PG */
+       if(SLOT7_1->vib) SLOT7_1->Cnt += (2*SLOT7_1->Incr*vib/VIB_RATE);
+       else             SLOT7_1->Cnt += 2*SLOT7_1->Incr;
+       if(SLOT7_2->vib) SLOT7_2->Cnt += ((CH[7].fc*8)*vib/VIB_RATE);
+       else             SLOT7_2->Cnt += (CH[7].fc*8);
+       if(SLOT8_1->vib) SLOT8_1->Cnt += (SLOT8_1->Incr*vib/VIB_RATE);
+       else             SLOT8_1->Cnt += SLOT8_1->Incr;
+       if(SLOT8_2->vib) SLOT8_2->Cnt += ((CH[8].fc*48)*vib/VIB_RATE);
+       else             SLOT8_2->Cnt += (CH[8].fc*48);
+
+       tone8 = OP_OUT(SLOT8_2,whitenoise,0 );
+
+       /* SD */
+       if( env_sd < EG_ENT-1 )
+               outd[0] += OP_OUT(SLOT7_1,env_sd, 0)*8;
+       /* TAM */
+       if( env_tam < EG_ENT-1 )
+               outd[0] += OP_OUT(SLOT8_1,env_tam, 0)*2;
+       /* TOP-CY */
+       if( env_top < EG_ENT-1 )
+               outd[0] += OP_OUT(SLOT7_2,env_top,tone8)*2;
+       /* HH */
+       if( env_hh  < EG_ENT-1 )
+               outd[0] += OP_OUT(SLOT7_2,env_hh,tone8)*2;
+}
+
+/* ----------- initialize time tabls ----------- */
+static void init_timetables( FM_OPL *OPL , int ARRATE , int DRRATE )
+{
+       int i;
+       double rate;
+
+       /* make attack rate & decay rate tables */
+       for (i = 0;i < 4;i++) OPL->AR_TABLE[i] = OPL->DR_TABLE[i] = 0;
+       for (i = 4;i <= 60;i++){
+               rate  = OPL->freqbase;                                          /* frequency rate */
+               if( i < 60 ) rate *= 1.0+(i&3)*0.25;            /* b0-1 : x1 , x1.25 , x1.5 , x1.75 */
+               rate *= 1<<((i>>2)-1);                                          /* b2-5 : shift bit */
+               rate *= (double)(EG_ENT<<ENV_BITS);
+               OPL->AR_TABLE[i] = rate / ARRATE;
+               OPL->DR_TABLE[i] = rate / DRRATE;
+       }
+       for (i = 60;i < 76;i++)
+       {
+               OPL->AR_TABLE[i] = EG_AED-1;
+               OPL->DR_TABLE[i] = OPL->DR_TABLE[60];
+       }
+#if 0
+       for (i = 0;i < 64 ;i++){        /* make for overflow area */
+               LOG(LOG_WAR,("rate %2d , ar %f ms , dr %f ms \n",i,
+                       ((double)(EG_ENT<<ENV_BITS) / OPL->AR_TABLE[i]) * (1000.0 / OPL->rate),
+                       ((double)(EG_ENT<<ENV_BITS) / OPL->DR_TABLE[i]) * (1000.0 / OPL->rate) ));
+       }
+#endif
+}
+
+/* ---------- generic table initialize ---------- */
+static int OPLOpenTable( void )
+{
+       int s,t;
+       double rate;
+       int i,j;
+       double pom;
+
+       /* allocate dynamic tables */
+       if( (TL_TABLE = malloc(TL_MAX*2*sizeof(INT32))) == NULL)
+               return 0;
+       if( (SIN_TABLE = malloc(SIN_ENT*4 *sizeof(INT32 *))) == NULL)
+       {
+               free(TL_TABLE);
+               return 0;
+       }
+       if( (AMS_TABLE = malloc(AMS_ENT*2 *sizeof(INT32))) == NULL)
+       {
+               free(TL_TABLE);
+               free(SIN_TABLE);
+               return 0;
+       }
+       if( (VIB_TABLE = malloc(VIB_ENT*2 *sizeof(INT32))) == NULL)
+       {
+               free(TL_TABLE);
+               free(SIN_TABLE);
+               free(AMS_TABLE);
+               return 0;
+       }
+       /* make total level table */
+       for (t = 0;t < EG_ENT-1 ;t++){
+               rate = ((1<<TL_BITS)-1)/pow(10,EG_STEP*t/20);   /* dB -> voltage */
+               TL_TABLE[       t] =  (int)rate;
+               TL_TABLE[TL_MAX+t] = -TL_TABLE[t];
+/*             LOG(LOG_INF,("TotalLevel(%3d) = %x\n",t,TL_TABLE[t]));*/
+       }
+       /* fill volume off area */
+       for ( t = EG_ENT-1; t < TL_MAX ;t++){
+               TL_TABLE[t] = TL_TABLE[TL_MAX+t] = 0;
+       }
+
+       /* make sinwave table (total level offet) */
+       /* degree 0 = degree 180                   = off */
+       SIN_TABLE[0] = SIN_TABLE[SIN_ENT/2]         = &TL_TABLE[EG_ENT-1];
+       for (s = 1;s <= SIN_ENT/4;s++){
+               pom = sin(2*PI*s/SIN_ENT); /* sin     */
+               pom = 20*log10(1/pom);     /* decibel */
+               j = pom / EG_STEP;         /* TL_TABLE steps */
+
+        /* degree 0   -  90    , degree 180 -  90 : plus section */
+               SIN_TABLE[          s] = SIN_TABLE[SIN_ENT/2-s] = &TL_TABLE[j];
+        /* degree 180 - 270    , degree 360 - 270 : minus section */
+               SIN_TABLE[SIN_ENT/2+s] = SIN_TABLE[SIN_ENT  -s] = &TL_TABLE[TL_MAX+j];
+/*             LOG(LOG_INF,("sin(%3d) = %f:%f db\n",s,pom,(double)j * EG_STEP));*/
+       }
+       for (s = 0;s < SIN_ENT;s++)
+       {
+               SIN_TABLE[SIN_ENT*1+s] = s<(SIN_ENT/2) ? SIN_TABLE[s] : &TL_TABLE[EG_ENT];
+               SIN_TABLE[SIN_ENT*2+s] = SIN_TABLE[s % (SIN_ENT/2)];
+               SIN_TABLE[SIN_ENT*3+s] = (s/(SIN_ENT/4))&1 ? &TL_TABLE[EG_ENT] : SIN_TABLE[SIN_ENT*2+s];
+       }
+
+       /* envelope counter -> envelope output table */
+       for (i=0; i<EG_ENT; i++)
+       {
+               /* ATTACK curve */
+               pom = pow( ((double)(EG_ENT-1-i)/EG_ENT) , 8 ) * EG_ENT;
+               /* if( pom >= EG_ENT ) pom = EG_ENT-1; */
+               ENV_CURVE[i] = (int)pom;
+               /* DECAY ,RELEASE curve */
+               ENV_CURVE[(EG_DST>>ENV_BITS)+i]= i;
+       }
+       /* off */
+       ENV_CURVE[EG_OFF>>ENV_BITS]= EG_ENT-1;
+       /* make LFO ams table */
+       for (i=0; i<AMS_ENT; i++)
+       {
+               pom = (1.0+sin(2*PI*i/AMS_ENT))/2; /* sin */
+               AMS_TABLE[i]         = (1.0/EG_STEP)*pom; /* 1dB   */
+               AMS_TABLE[AMS_ENT+i] = (4.8/EG_STEP)*pom; /* 4.8dB */
+       }
+       /* make LFO vibrate table */
+       for (i=0; i<VIB_ENT; i++)
+       {
+               /* 100cent = 1seminote = 6% ?? */
+               pom = (double)VIB_RATE*0.06*sin(2*PI*i/VIB_ENT); /* +-100sect step */
+               VIB_TABLE[i]         = VIB_RATE + (pom*0.07); /* +- 7cent */
+               VIB_TABLE[VIB_ENT+i] = VIB_RATE + (pom*0.14); /* +-14cent */
+               /* LOG(LOG_INF,("vib %d=%d\n",i,VIB_TABLE[VIB_ENT+i])); */
+       }
+       return 1;
+}
+
+
+static void OPLCloseTable( void )
+{
+       free(TL_TABLE);
+       free(SIN_TABLE);
+       free(AMS_TABLE);
+       free(VIB_TABLE);
+}
+
+/* CSM Key Controll */
+INLINE void CSMKeyControll(OPL_CH *CH)
+{
+       OPL_SLOT *slot1 = &CH->SLOT[SLOT1];
+       OPL_SLOT *slot2 = &CH->SLOT[SLOT2];
+       /* all key off */
+       OPL_KEYOFF(slot1);
+       OPL_KEYOFF(slot2);
+       /* total level latch */
+       slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl);
+       slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl);
+       /* key on */
+       CH->op1_out[0] = CH->op1_out[1] = 0;
+       OPL_KEYON(slot1);
+       OPL_KEYON(slot2);
+}
+
+/* ---------- opl initialize ---------- */
+static void OPL_initalize(FM_OPL *OPL)
+{
+       int fn;
+
+       /* frequency base */
+       OPL->freqbase = (OPL->rate) ? ((double)OPL->clock / OPL->rate) / 72  : 0;
+       /* Timer base time */
+       OPL->TimerBase = 1.0/((double)OPL->clock / 72.0 );
+       /* make time tables */
+       init_timetables( OPL , OPL_ARRATE , OPL_DRRATE );
+       /* make fnumber -> increment counter table */
+       for( fn=0 ; fn < 1024 ; fn++ )
+       {
+               OPL->FN_TABLE[fn] = OPL->freqbase * fn * FREQ_RATE * (1<<7) / 2;
+       }
+       /* LFO freq.table */
+       OPL->amsIncr = OPL->rate ? (double)AMS_ENT*(1<<AMS_SHIFT) / OPL->rate * 3.7 * ((double)OPL->clock/3600000) : 0;
+       OPL->vibIncr = OPL->rate ? (double)VIB_ENT*(1<<VIB_SHIFT) / OPL->rate * 6.4 * ((double)OPL->clock/3600000) : 0;
+}
+
+/* ---------- write a OPL registers ---------- */
+static void OPLWriteReg(FM_OPL *OPL, int r, int v)
+{
+       OPL_CH *CH;
+       int slot;
+       int block_fnum;
+
+       switch(r&0xe0)
+       {
+       case 0x00: /* 00-1f:controll */
+               switch(r&0x1f)
+               {
+               case 0x01:
+                       /* wave selector enable */
+                       if(OPL->type&OPL_TYPE_WAVESEL)
+                       {
+                               OPL->wavesel = v&0x20;
+                               if(!OPL->wavesel)
+                               {
+                                       /* preset compatible mode */
+                                       int c;
+                                       for(c=0;c<OPL->max_ch;c++)
+                                       {
+                                               OPL->P_CH[c].SLOT[SLOT1].wavetable = &SIN_TABLE[0];
+                                               OPL->P_CH[c].SLOT[SLOT2].wavetable = &SIN_TABLE[0];
+                                       }
+                               }
+                       }
+                       return;
+               case 0x02:      /* Timer 1 */
+                       OPL->T[0] = (256-v)*4;
+                       break;
+               case 0x03:      /* Timer 2 */
+                       OPL->T[1] = (256-v)*16;
+                       return;
+               case 0x04:      /* IRQ clear / mask and Timer enable */
+                       if(v&0x80)
+                       {       /* IRQ flag clear */
+                               OPL_STATUS_RESET(OPL,0x7f);
+                       }
+                       else
+                       {       /* set IRQ mask ,timer enable*/
+                               UINT8 st1 = v&1;
+                               UINT8 st2 = (v>>1)&1;
+                               /* IRQRST,T1MSK,t2MSK,EOSMSK,BRMSK,x,ST2,ST1 */
+                               OPL_STATUS_RESET(OPL,v&0x78);
+                               OPL_STATUSMASK_SET(OPL,((~v)&0x78)|0x01);
+                               /* timer 2 */
+                               if(OPL->st[1] != st2)
+                               {
+                                       double interval = st2 ? (double)OPL->T[1]*OPL->TimerBase : 0.0;
+                                       OPL->st[1] = st2;
+                                       if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+1,interval);
+                               }
+                               /* timer 1 */
+                               if(OPL->st[0] != st1)
+                               {
+                                       double interval = st1 ? (double)OPL->T[0]*OPL->TimerBase : 0.0;
+                                       OPL->st[0] = st1;
+                                       if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+0,interval);
+                               }
+                       }
+                       return;
+#if BUILD_Y8950
+               case 0x06:              /* Key Board OUT */
+                       if(OPL->type&OPL_TYPE_KEYBOARD)
+                       {
+                               if(OPL->keyboardhandler_w)
+                                       OPL->keyboardhandler_w(OPL->keyboard_param,v);
+                               else
+                                       LOG(LOG_WAR,("OPL:write unmapped KEYBOARD port\n"));
+                       }
+                       return;
+               case 0x07:      /* DELTA-T controll : START,REC,MEMDATA,REPT,SPOFF,x,x,RST */
+                       if(OPL->type&OPL_TYPE_ADPCM)
+                               YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v);
+                       return;
+               case 0x08:      /* MODE,DELTA-T : CSM,NOTESEL,x,x,smpl,da/ad,64k,rom */
+                       OPL->mode = v;
+                       v&=0x1f;        /* for DELTA-T unit */
+               case 0x09:              /* START ADD */
+               case 0x0a:
+               case 0x0b:              /* STOP ADD  */
+               case 0x0c:
+               case 0x0d:              /* PRESCALE   */
+               case 0x0e:
+               case 0x0f:              /* ADPCM data */
+               case 0x10:              /* DELTA-N    */
+               case 0x11:              /* DELTA-N    */
+               case 0x12:              /* EG-CTRL    */
+                       if(OPL->type&OPL_TYPE_ADPCM)
+                               YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v);
+                       return;
+#if 0
+               case 0x15:              /* DAC data    */
+               case 0x16:
+               case 0x17:              /* SHIFT    */
+                       return;
+               case 0x18:              /* I/O CTRL (Direction) */
+                       if(OPL->type&OPL_TYPE_IO)
+                               OPL->portDirection = v&0x0f;
+                       return;
+               case 0x19:              /* I/O DATA */
+                       if(OPL->type&OPL_TYPE_IO)
+                       {
+                               OPL->portLatch = v;
+                               if(OPL->porthandler_w)
+                                       OPL->porthandler_w(OPL->port_param,v&OPL->portDirection);
+                       }
+                       return;
+               case 0x1a:              /* PCM data */
+                       return;
+#endif
+#endif
+               }
+               break;
+       case 0x20:      /* am,vib,ksr,eg type,mul */
+               slot = slot_array[r&0x1f];
+               if(slot == -1) return;
+               set_mul(OPL,slot,v);
+               return;
+       case 0x40:
+               slot = slot_array[r&0x1f];
+               if(slot == -1) return;
+               set_ksl_tl(OPL,slot,v);
+               return;
+       case 0x60:
+               slot = slot_array[r&0x1f];
+               if(slot == -1) return;
+               set_ar_dr(OPL,slot,v);
+               return;
+       case 0x80:
+               slot = slot_array[r&0x1f];
+               if(slot == -1) return;
+               set_sl_rr(OPL,slot,v);
+               return;
+       case 0xa0:
+               switch(r)
+               {
+               case 0xbd:
+                       /* amsep,vibdep,r,bd,sd,tom,tc,hh */
+                       {
+                       UINT8 rkey = OPL->rythm^v;
+                       OPL->ams_table = &AMS_TABLE[v&0x80 ? AMS_ENT : 0];
+                       OPL->vib_table = &VIB_TABLE[v&0x40 ? VIB_ENT : 0];
+                       OPL->rythm  = v&0x3f;
+                       if(OPL->rythm&0x20)
+                       {
+#if 0
+                               usrintf_showmessage("OPL Rythm mode select");
+#endif
+                               /* BD key on/off */
+                               if(rkey&0x10)
+                               {
+                                       if(v&0x10)
+                                       {
+                                               OPL->P_CH[6].op1_out[0] = OPL->P_CH[6].op1_out[1] = 0;
+                                               OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT1]);
+                                               OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT2]);
+                                       }
+                                       else
+                                       {
+                                               OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1]);
+                                               OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2]);
+                                       }
+                               }
+                               /* SD key on/off */
+                               if(rkey&0x08)
+                               {
+                                       if(v&0x08) OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT2]);
+                                       else       OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2]);
+                               }/* TAM key on/off */
+                               if(rkey&0x04)
+                               {
+                                       if(v&0x04) OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT1]);
+                                       else       OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1]);
+                               }
+                               /* TOP-CY key on/off */
+                               if(rkey&0x02)
+                               {
+                                       if(v&0x02) OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT2]);
+                                       else       OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2]);
+                               }
+                               /* HH key on/off */
+                               if(rkey&0x01)
+                               {
+                                       if(v&0x01) OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT1]);
+                                       else       OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1]);
+                               }
+                       }
+                       }
+                       return;
+               }
+               /* keyon,block,fnum */
+               if( (r&0x0f) > 8) return;
+               CH = &OPL->P_CH[r&0x0f];
+               if(!(r&0x10))
+               {       /* a0-a8 */
+                       block_fnum  = (CH->block_fnum&0x1f00) | v;
+               }
+               else
+               {       /* b0-b8 */
+                       int keyon = (v>>5)&1;
+                       block_fnum = ((v&0x1f)<<8) | (CH->block_fnum&0xff);
+                       if(CH->keyon != keyon)
+                       {
+                               if( (CH->keyon=keyon) )
+                               {
+                                       CH->op1_out[0] = CH->op1_out[1] = 0;
+                                       OPL_KEYON(&CH->SLOT[SLOT1]);
+                                       OPL_KEYON(&CH->SLOT[SLOT2]);
+                               }
+                               else
+                               {
+                                       OPL_KEYOFF(&CH->SLOT[SLOT1]);
+                                       OPL_KEYOFF(&CH->SLOT[SLOT2]);
+                               }
+                       }
+               }
+               /* update */
+               if(CH->block_fnum != block_fnum)
+               {
+                       int blockRv = 7-(block_fnum>>10);
+                       int fnum   = block_fnum&0x3ff;
+                       CH->block_fnum = block_fnum;
+
+                       CH->ksl_base = KSL_TABLE[block_fnum>>6];
+                       CH->fc = OPL->FN_TABLE[fnum]>>blockRv;
+                       CH->kcode = CH->block_fnum>>9;
+                       if( (OPL->mode&0x40) && CH->block_fnum&0x100) CH->kcode |=1;
+                       CALC_FCSLOT(CH,&CH->SLOT[SLOT1]);
+                       CALC_FCSLOT(CH,&CH->SLOT[SLOT2]);
+               }
+               return;
+       case 0xc0:
+               /* FB,C */
+               if( (r&0x0f) > 8) return;
+               CH = &OPL->P_CH[r&0x0f];
+               {
+               int feedback = (v>>1)&7;
+               CH->FB   = feedback ? (8+1) - feedback : 0;
+               CH->CON = v&1;
+               set_algorythm(CH);
+               }
+               return;
+       case 0xe0: /* wave type */
+               slot = slot_array[r&0x1f];
+               if(slot == -1) return;
+               CH = &OPL->P_CH[slot/2];
+               if(OPL->wavesel)
+               {
+                       /* LOG(LOG_INF,("OPL SLOT %d wave select %d\n",slot,v&3)); */
+                       CH->SLOT[slot&1].wavetable = &SIN_TABLE[(v&0x03)*SIN_ENT];
+               }
+               return;
+       }
+}
+
+/* lock/unlock for common table */
+static int OPL_LockTable(void)
+{
+       num_lock++;
+       if(num_lock>1) return 0;
+       /* first time */
+       cur_chip = NULL;
+       /* allocate total level table (128kb space) */
+       if( !OPLOpenTable() )
+       {
+               num_lock--;
+               return -1;
+       }
+       return 0;
+}
+
+static void OPL_UnLockTable(void)
+{
+       if(num_lock) num_lock--;
+       if(num_lock) return;
+       /* last time */
+       cur_chip = NULL;
+       OPLCloseTable();
+}
+
+#if (BUILD_YM3812 || BUILD_YM3526)
+/*******************************************************************************/
+/*             YM3812 local section                                                   */
+/*******************************************************************************/
+
+/* ---------- update one of chip ----------- */
+void YM3812UpdateOne(FM_OPL *OPL, INT16 *buffer, int length)
+{
+    int i;
+       int data;
+       OPLSAMPLE *buf = buffer;
+       UINT32 amsCnt  = OPL->amsCnt;
+       UINT32 vibCnt  = OPL->vibCnt;
+       UINT8 rythm = OPL->rythm&0x20;
+       OPL_CH *CH,*R_CH;
+
+       if( (void *)OPL != cur_chip ){
+               cur_chip = (void *)OPL;
+               /* channel pointers */
+               S_CH = OPL->P_CH;
+               E_CH = &S_CH[9];
+               /* rythm slot */
+               SLOT7_1 = &S_CH[7].SLOT[SLOT1];
+               SLOT7_2 = &S_CH[7].SLOT[SLOT2];
+               SLOT8_1 = &S_CH[8].SLOT[SLOT1];
+               SLOT8_2 = &S_CH[8].SLOT[SLOT2];
+               /* LFO state */
+               amsIncr = OPL->amsIncr;
+               vibIncr = OPL->vibIncr;
+               ams_table = OPL->ams_table;
+               vib_table = OPL->vib_table;
+       }
+       R_CH = rythm ? &S_CH[6] : E_CH;
+    for( i=0; i < length ; i++ )
+       {
+               /*            channel A         channel B         channel C      */
+               /* LFO */
+               ams = ams_table[(amsCnt+=amsIncr)>>AMS_SHIFT];
+               vib = vib_table[(vibCnt+=vibIncr)>>VIB_SHIFT];
+               outd[0] = 0;
+               /* FM part */
+               for(CH=S_CH ; CH < R_CH ; CH++)
+                       OPL_CALC_CH(CH);
+               /* Rythn part */
+               if(rythm)
+                       OPL_CALC_RH(S_CH);
+               /* limit check */
+               data = Limit( outd[0] , OPL_MAXOUT, OPL_MINOUT );
+               /* store to sound buffer */
+               buf[i] = data >> OPL_OUTSB;
+       }
+
+       OPL->amsCnt = amsCnt;
+       OPL->vibCnt = vibCnt;
+#ifdef OPL_OUTPUT_LOG
+       if(opl_dbg_fp)
+       {
+               for(opl_dbg_chip=0;opl_dbg_chip<opl_dbg_maxchip;opl_dbg_chip++)
+                       if( opl_dbg_opl[opl_dbg_chip] == OPL) break;
+               fprintf(opl_dbg_fp,"%c%c%c",0x20+opl_dbg_chip,length&0xff,length/256);
+       }
+#endif
+}
+#endif /* (BUILD_YM3812 || BUILD_YM3526) */
+
+#if BUILD_Y8950
+
+void Y8950UpdateOne(FM_OPL *OPL, INT16 *buffer, int length)
+{
+    int i;
+       int data;
+       OPLSAMPLE *buf = buffer;
+       UINT32 amsCnt  = OPL->amsCnt;
+       UINT32 vibCnt  = OPL->vibCnt;
+       UINT8 rythm = OPL->rythm&0x20;
+       OPL_CH *CH,*R_CH;
+       YM_DELTAT *DELTAT = OPL->deltat;
+
+       /* setup DELTA-T unit */
+       YM_DELTAT_DECODE_PRESET(DELTAT);
+
+       if( (void *)OPL != cur_chip ){
+               cur_chip = (void *)OPL;
+               /* channel pointers */
+               S_CH = OPL->P_CH;
+               E_CH = &S_CH[9];
+               /* rythm slot */
+               SLOT7_1 = &S_CH[7].SLOT[SLOT1];
+               SLOT7_2 = &S_CH[7].SLOT[SLOT2];
+               SLOT8_1 = &S_CH[8].SLOT[SLOT1];
+               SLOT8_2 = &S_CH[8].SLOT[SLOT2];
+               /* LFO state */
+               amsIncr = OPL->amsIncr;
+               vibIncr = OPL->vibIncr;
+               ams_table = OPL->ams_table;
+               vib_table = OPL->vib_table;
+       }
+       R_CH = rythm ? &S_CH[6] : E_CH;
+    for( i=0; i < length ; i++ )
+       {
+               /*            channel A         channel B         channel C      */
+               /* LFO */
+               ams = ams_table[(amsCnt+=amsIncr)>>AMS_SHIFT];
+               vib = vib_table[(vibCnt+=vibIncr)>>VIB_SHIFT];
+               outd[0] = 0;
+               /* deltaT ADPCM */
+               if( DELTAT->portstate )
+                       YM_DELTAT_ADPCM_CALC(DELTAT);
+               /* FM part */
+               for(CH=S_CH ; CH < R_CH ; CH++)
+                       OPL_CALC_CH(CH);
+               /* Rythn part */
+               if(rythm)
+                       OPL_CALC_RH(S_CH);
+               /* limit check */
+               data = Limit( outd[0] , OPL_MAXOUT, OPL_MINOUT );
+               /* store to sound buffer */
+               buf[i] = data >> OPL_OUTSB;
+       }
+       OPL->amsCnt = amsCnt;
+       OPL->vibCnt = vibCnt;
+       /* deltaT START flag */
+       if( !DELTAT->portstate )
+               OPL->status &= 0xfe;
+}
+#endif
+
+/* ---------- reset one of chip ---------- */
+void OPLResetChip(FM_OPL *OPL)
+{
+       int c,s;
+       int i;
+
+       /* reset chip */
+       OPL->mode   = 0;        /* normal mode */
+       OPL_STATUS_RESET(OPL,0x7f);
+       /* reset with register write */
+       OPLWriteReg(OPL,0x01,0); /* wabesel disable */
+       OPLWriteReg(OPL,0x02,0); /* Timer1 */
+       OPLWriteReg(OPL,0x03,0); /* Timer2 */
+       OPLWriteReg(OPL,0x04,0); /* IRQ mask clear */
+       for(i = 0xff ; i >= 0x20 ; i-- ) OPLWriteReg(OPL,i,0);
+       /* reset OPerator paramater */
+       for( c = 0 ; c < OPL->max_ch ; c++ )
+       {
+               OPL_CH *CH = &OPL->P_CH[c];
+               /* OPL->P_CH[c].PAN = OPN_CENTER; */
+               for(s = 0 ; s < 2 ; s++ )
+               {
+                       /* wave table */
+                       CH->SLOT[s].wavetable = &SIN_TABLE[0];
+                       /* CH->SLOT[s].evm = ENV_MOD_RR; */
+                       CH->SLOT[s].evc = EG_OFF;
+                       CH->SLOT[s].eve = EG_OFF+1;
+                       CH->SLOT[s].evs = 0;
+               }
+       }
+#if BUILD_Y8950
+       if(OPL->type&OPL_TYPE_ADPCM)
+       {
+               YM_DELTAT *DELTAT = OPL->deltat;
+
+               DELTAT->freqbase = OPL->freqbase;
+               DELTAT->output_pointer = outd;
+               DELTAT->portshift = 5;
+               DELTAT->output_range = DELTAT_MIXING_LEVEL<<TL_BITS;
+               YM_DELTAT_ADPCM_Reset(DELTAT,0);
+       }
+#endif
+}
+
+/* ----------  Create one of vietual YM3812 ----------       */
+/* 'rate'  is sampling rate and 'bufsiz' is the size of the  */
+FM_OPL *OPLCreate(int type, int clock, int rate)
+{
+       char *ptr;
+       FM_OPL *OPL;
+       int state_size;
+       int max_ch = 9; /* normaly 9 channels */
+
+       if( OPL_LockTable() ==-1) return NULL;
+       /* allocate OPL state space */
+       state_size  = sizeof(FM_OPL);
+       state_size += sizeof(OPL_CH)*max_ch;
+#if BUILD_Y8950
+       if(type&OPL_TYPE_ADPCM) state_size+= sizeof(YM_DELTAT);
+#endif
+       /* allocate memory block */
+       ptr = malloc(state_size);
+       if(ptr==NULL) return NULL;
+       /* clear */
+       memset(ptr,0,state_size);
+       OPL        = (FM_OPL *)ptr; ptr+=sizeof(FM_OPL);
+       OPL->P_CH  = (OPL_CH *)ptr; ptr+=sizeof(OPL_CH)*max_ch;
+#if BUILD_Y8950
+       if(type&OPL_TYPE_ADPCM) OPL->deltat = (YM_DELTAT *)ptr; ptr+=sizeof(YM_DELTAT);
+#endif
+       /* set channel state pointer */
+       OPL->type  = type;
+       OPL->clock = clock;
+       OPL->rate  = rate;
+       OPL->max_ch = max_ch;
+       /* init grobal tables */
+       OPL_initalize(OPL);
+       /* reset chip */
+       OPLResetChip(OPL);
+#ifdef OPL_OUTPUT_LOG
+       if(!opl_dbg_fp)
+       {
+               opl_dbg_fp = fopen("opllog.opl","wb");
+               opl_dbg_maxchip = 0;
+       }
+       if(opl_dbg_fp)
+       {
+               opl_dbg_opl[opl_dbg_maxchip] = OPL;
+               fprintf(opl_dbg_fp,"%c%c%c%c%c%c",0x00+opl_dbg_maxchip,
+                       type,
+                       clock&0xff,
+                       (clock/0x100)&0xff,
+                       (clock/0x10000)&0xff,
+                       (clock/0x1000000)&0xff);
+               opl_dbg_maxchip++;
+       }
+#endif
+       return OPL;
+}
+
+/* ----------  Destroy one of vietual YM3812 ----------       */
+void OPLDestroy(FM_OPL *OPL)
+{
+#ifdef OPL_OUTPUT_LOG
+       if(opl_dbg_fp)
+       {
+               fclose(opl_dbg_fp);
+               opl_dbg_fp = NULL;
+       }
+#endif
+       OPL_UnLockTable();
+       free(OPL);
+}
+
+/* ----------  Option handlers ----------       */
+
+void OPLSetTimerHandler(FM_OPL *OPL,OPL_TIMERHANDLER TimerHandler,int channelOffset)
+{
+       OPL->TimerHandler   = TimerHandler;
+       OPL->TimerParam = channelOffset;
+}
+void OPLSetIRQHandler(FM_OPL *OPL,OPL_IRQHANDLER IRQHandler,int param)
+{
+       OPL->IRQHandler     = IRQHandler;
+       OPL->IRQParam = param;
+}
+void OPLSetUpdateHandler(FM_OPL *OPL,OPL_UPDATEHANDLER UpdateHandler,int param)
+{
+       OPL->UpdateHandler = UpdateHandler;
+       OPL->UpdateParam = param;
+}
+#if BUILD_Y8950
+void OPLSetPortHandler(FM_OPL *OPL,OPL_PORTHANDLER_W PortHandler_w,OPL_PORTHANDLER_R PortHandler_r,int param)
+{
+       OPL->porthandler_w = PortHandler_w;
+       OPL->porthandler_r = PortHandler_r;
+       OPL->port_param = param;
+}
+
+void OPLSetKeyboardHandler(FM_OPL *OPL,OPL_PORTHANDLER_W KeyboardHandler_w,OPL_PORTHANDLER_R KeyboardHandler_r,int param)
+{
+       OPL->keyboardhandler_w = KeyboardHandler_w;
+       OPL->keyboardhandler_r = KeyboardHandler_r;
+       OPL->keyboard_param = param;
+}
+#endif
+/* ---------- YM3812 I/O interface ---------- */
+int OPLWrite(FM_OPL *OPL,int a,int v)
+{
+       if( !(a&1) )
+       {       /* address port */
+               OPL->address = v & 0xff;
+       }
+       else
+       {       /* data port */
+               if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0);
+#ifdef OPL_OUTPUT_LOG
+       if(opl_dbg_fp)
+       {
+               for(opl_dbg_chip=0;opl_dbg_chip<opl_dbg_maxchip;opl_dbg_chip++)
+                       if( opl_dbg_opl[opl_dbg_chip] == OPL) break;
+               fprintf(opl_dbg_fp,"%c%c%c",0x10+opl_dbg_chip,OPL->address,v);
+       }
+#endif
+               OPLWriteReg(OPL,OPL->address,v);
+       }
+       return OPL->status>>7;
+}
+
+unsigned char OPLRead(FM_OPL *OPL,int a)
+{
+       if( !(a&1) )
+       {       /* status port */
+               return OPL->status & (OPL->statusmask|0x80);
+       }
+       /* data port */
+       switch(OPL->address)
+       {
+       case 0x05: /* KeyBoard IN */
+               if(OPL->type&OPL_TYPE_KEYBOARD)
+               {
+                       if(OPL->keyboardhandler_r)
+                               return OPL->keyboardhandler_r(OPL->keyboard_param);
+                       else
+                               LOG(LOG_WAR,("OPL:read unmapped KEYBOARD port\n"));
+               }
+               return 0;
+#if 0
+       case 0x0f: /* ADPCM-DATA  */
+               return 0;
+#endif
+       case 0x19: /* I/O DATA    */
+               if(OPL->type&OPL_TYPE_IO)
+               {
+                       if(OPL->porthandler_r)
+                               return OPL->porthandler_r(OPL->port_param);
+                       else
+                               LOG(LOG_WAR,("OPL:read unmapped I/O port\n"));
+               }
+               return 0;
+       case 0x1a: /* PCM-DATA    */
+               return 0;
+       }
+       return 0;
+}
+
+int OPLTimerOver(FM_OPL *OPL,int c)
+{
+       if( c )
+       {       /* Timer B */
+               OPL_STATUS_SET(OPL,0x20);
+       }
+       else
+       {       /* Timer A */
+               OPL_STATUS_SET(OPL,0x40);
+               /* CSM mode key,TL controll */
+               if( OPL->mode & 0x80 )
+               {       /* CSM mode total level latch and auto key on */
+                       int ch;
+                       if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0);
+                       for(ch=0;ch<9;ch++)
+                               CSMKeyControll( &OPL->P_CH[ch] );
+               }
+       }
+       /* reload timer */
+       if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+c,(double)OPL->T[c]*OPL->TimerBase);
+       return OPL->status>>7;
+}
diff --git a/tools/ioemu/hw/fmopl.h b/tools/ioemu/hw/fmopl.h
new file mode 100644 (file)
index 0000000..a01ff90
--- /dev/null
@@ -0,0 +1,174 @@
+#ifndef __FMOPL_H_
+#define __FMOPL_H_
+
+/* --- select emulation chips --- */
+#define BUILD_YM3812 (HAS_YM3812)
+//#define BUILD_YM3526 (HAS_YM3526)
+//#define BUILD_Y8950  (HAS_Y8950)
+
+/* --- system optimize --- */
+/* select bit size of output : 8 or 16 */
+#define OPL_OUTPUT_BIT 16
+
+/* compiler dependence */
+#ifndef OSD_CPU_H
+#define OSD_CPU_H
+typedef unsigned char  UINT8;   /* unsigned  8bit */
+typedef unsigned short UINT16;  /* unsigned 16bit */
+typedef unsigned int   UINT32;  /* unsigned 32bit */
+typedef signed char            INT8;    /* signed  8bit   */
+typedef signed short   INT16;   /* signed 16bit   */
+typedef signed int             INT32;   /* signed 32bit   */
+#endif
+
+#if (OPL_OUTPUT_BIT==16)
+typedef INT16 OPLSAMPLE;
+#endif
+#if (OPL_OUTPUT_BIT==8)
+typedef unsigned char  OPLSAMPLE;
+#endif
+
+
+#if BUILD_Y8950
+#include "ymdeltat.h"
+#endif
+
+typedef void (*OPL_TIMERHANDLER)(int channel,double interval_Sec);
+typedef void (*OPL_IRQHANDLER)(int param,int irq);
+typedef void (*OPL_UPDATEHANDLER)(int param,int min_interval_us);
+typedef void (*OPL_PORTHANDLER_W)(int param,unsigned char data);
+typedef unsigned char (*OPL_PORTHANDLER_R)(int param);
+
+/* !!!!! here is private section , do not access there member direct !!!!! */
+
+#define OPL_TYPE_WAVESEL   0x01  /* waveform select    */
+#define OPL_TYPE_ADPCM     0x02  /* DELTA-T ADPCM unit */
+#define OPL_TYPE_KEYBOARD  0x04  /* keyboard interface */
+#define OPL_TYPE_IO        0x08  /* I/O port */
+
+/* Saving is necessary for member of the 'R' mark for suspend/resume */
+/* ---------- OPL one of slot  ---------- */
+typedef struct fm_opl_slot {
+       INT32 TL;               /* total level     :TL << 8            */
+       INT32 TLL;              /* adjusted now TL                     */
+       UINT8  KSR;             /* key scale rate  :(shift down bit)   */
+       INT32 *AR;              /* attack rate     :&AR_TABLE[AR<<2]   */
+       INT32 *DR;              /* decay rate      :&DR_TALBE[DR<<2]   */
+       INT32 SL;               /* sustin level    :SL_TALBE[SL]       */
+       INT32 *RR;              /* release rate    :&DR_TABLE[RR<<2]   */
+       UINT8 ksl;              /* keyscale level  :(shift down bits)  */
+       UINT8 ksr;              /* key scale rate  :kcode>>KSR         */
+       UINT32 mul;             /* multiple        :ML_TABLE[ML]       */
+       UINT32 Cnt;             /* frequency count :                   */
+       UINT32 Incr;    /* frequency step  :                   */
+       /* envelope generator state */
+       UINT8 eg_typ;   /* envelope type flag                  */
+       UINT8 evm;              /* envelope phase                      */
+       INT32 evc;              /* envelope counter                    */
+       INT32 eve;              /* envelope counter end point          */
+       INT32 evs;              /* envelope counter step               */
+       INT32 evsa;     /* envelope step for AR :AR[ksr]           */
+       INT32 evsd;     /* envelope step for DR :DR[ksr]           */
+       INT32 evsr;     /* envelope step for RR :RR[ksr]           */
+       /* LFO */
+       UINT8 ams;              /* ams flag                            */
+       UINT8 vib;              /* vibrate flag                        */
+       /* wave selector */
+       INT32 **wavetable;
+}OPL_SLOT;
+
+/* ---------- OPL one of channel  ---------- */
+typedef struct fm_opl_channel {
+       OPL_SLOT SLOT[2];
+       UINT8 CON;                      /* connection type                     */
+       UINT8 FB;                       /* feed back       :(shift down bit)   */
+       INT32 *connect1;        /* slot1 output pointer                */
+       INT32 *connect2;        /* slot2 output pointer                */
+       INT32 op1_out[2];       /* slot1 output for selfeedback        */
+       /* phase generator state */
+       UINT32  block_fnum;     /* block+fnum      :                   */
+       UINT8 kcode;            /* key code        : KeyScaleCode      */
+       UINT32  fc;                     /* Freq. Increment base                */
+       UINT32  ksl_base;       /* KeyScaleLevel Base step             */
+       UINT8 keyon;            /* key on/off flag                     */
+} OPL_CH;
+
+/* OPL state */
+typedef struct fm_opl_f {
+       UINT8 type;                     /* chip type                         */
+       int clock;                      /* master clock  (Hz)                */
+       int rate;                       /* sampling rate (Hz)                */
+       double freqbase;        /* frequency base                    */
+       double TimerBase;       /* Timer base time (==sampling time) */
+       UINT8 address;          /* address register                  */
+       UINT8 status;           /* status flag                       */
+       UINT8 statusmask;       /* status mask                       */
+       UINT32 mode;            /* Reg.08 : CSM , notesel,etc.       */
+       /* Timer */
+       int T[2];                       /* timer counter                     */
+       UINT8 st[2];            /* timer enable                      */
+       /* FM channel slots */
+       OPL_CH *P_CH;           /* pointer of CH                     */
+       int     max_ch;                 /* maximum channel                   */
+       /* Rythm sention */
+       UINT8 rythm;            /* Rythm mode , key flag */
+#if BUILD_Y8950
+       /* Delta-T ADPCM unit (Y8950) */
+       YM_DELTAT *deltat;                      /* DELTA-T ADPCM       */
+#endif
+       /* Keyboard / I/O interface unit (Y8950) */
+       UINT8 portDirection;
+       UINT8 portLatch;
+       OPL_PORTHANDLER_R porthandler_r;
+       OPL_PORTHANDLER_W porthandler_w;
+       int port_param;
+       OPL_PORTHANDLER_R keyboardhandler_r;
+       OPL_PORTHANDLER_W keyboardhandler_w;
+       int keyboard_param;
+       /* time tables */
+       INT32 AR_TABLE[75];     /* atttack rate tables */
+       INT32 DR_TABLE[75];     /* decay rate tables   */
+       UINT32 FN_TABLE[1024];  /* fnumber -> increment counter */
+       /* LFO */
+       INT32 *ams_table;
+       INT32 *vib_table;
+       INT32 amsCnt;
+       INT32 amsIncr;
+       INT32 vibCnt;
+       INT32 vibIncr;
+       /* wave selector enable flag */
+       UINT8 wavesel;
+       /* external event callback handler */
+       OPL_TIMERHANDLER  TimerHandler;         /* TIMER handler   */
+       int TimerParam;                                         /* TIMER parameter */
+       OPL_IRQHANDLER    IRQHandler;           /* IRQ handler    */
+       int IRQParam;                                           /* IRQ parameter  */
+       OPL_UPDATEHANDLER UpdateHandler;        /* stream update handler   */
+       int UpdateParam;                                        /* stream update parameter */
+} FM_OPL;
+
+/* ---------- Generic interface section ---------- */
+#define OPL_TYPE_YM3526 (0)
+#define OPL_TYPE_YM3812 (OPL_TYPE_WAVESEL)
+#define OPL_TYPE_Y8950  (OPL_TYPE_ADPCM|OPL_TYPE_KEYBOARD|OPL_TYPE_IO)
+
+FM_OPL *OPLCreate(int type, int clock, int rate);
+void OPLDestroy(FM_OPL *OPL);
+void OPLSetTimerHandler(FM_OPL *OPL,OPL_TIMERHANDLER TimerHandler,int channelOffset);
+void OPLSetIRQHandler(FM_OPL *OPL,OPL_IRQHANDLER IRQHandler,int param);
+void OPLSetUpdateHandler(FM_OPL *OPL,OPL_UPDATEHANDLER UpdateHandler,int param);
+/* Y8950 port handlers */
+void OPLSetPortHandler(FM_OPL *OPL,OPL_PORTHANDLER_W PortHandler_w,OPL_PORTHANDLER_R PortHandler_r,int param);
+void OPLSetKeyboardHandler(FM_OPL *OPL,OPL_PORTHANDLER_W KeyboardHandler_w,OPL_PORTHANDLER_R KeyboardHandler_r,int param);
+
+void OPLResetChip(FM_OPL *OPL);
+int OPLWrite(FM_OPL *OPL,int a,int v);
+unsigned char OPLRead(FM_OPL *OPL,int a);
+int OPLTimerOver(FM_OPL *OPL,int c);
+
+/* YM3626/YM3812 local section */
+void YM3812UpdateOne(FM_OPL *OPL, INT16 *buffer, int length);
+
+void Y8950UpdateOne(FM_OPL *OPL, INT16 *buffer, int length);
+
+#endif
diff --git a/tools/ioemu/hw/i8254.c b/tools/ioemu/hw/i8254.c
new file mode 100644 (file)
index 0000000..7fb9119
--- /dev/null
@@ -0,0 +1,505 @@
+/*
+ * QEMU 8253/8254 interval timer emulation
+ * 
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+#include "xc.h"
+#include <io/ioreq.h>
+
+//#define DEBUG_PIT
+
+#define RW_STATE_LSB 1
+#define RW_STATE_MSB 2
+#define RW_STATE_WORD0 3
+#define RW_STATE_WORD1 4
+
+typedef struct PITChannelState {
+    int count; /* can be 65536 */
+    uint16_t latched_count;
+    uint8_t count_latched;
+    uint8_t status_latched;
+    uint8_t status;
+    uint8_t read_state;
+    uint8_t write_state;
+    uint8_t write_latch;
+    uint8_t rw_mode;
+    uint8_t mode;
+    uint8_t bcd; /* not supported */
+    uint8_t gate; /* timer start */
+    int64_t count_load_time;
+    /* irq handling */
+    int64_t next_transition_time;
+    QEMUTimer *irq_timer;
+    int irq;
+} PITChannelState;
+
+struct PITState {
+    PITChannelState channels[3];
+};
+
+static PITState pit_state;
+
+static void pit_irq_timer_update(PITChannelState *s, int64_t current_time);
+
+/* currently operate which channel for vmx use */
+int vmx_channel = -1;
+extern FILE *logfile;
+static int pit_get_count(PITChannelState *s)
+{
+    uint64_t d;
+    int counter;
+
+    d = muldiv64(qemu_get_clock(vm_clock) - s->count_load_time, PIT_FREQ, ticks_per_sec);
+    switch(s->mode) {
+    case 0:
+    case 1:
+    case 4:
+    case 5:
+        counter = (s->count - d) & 0xffff;
+        break;
+    case 3:
+        /* XXX: may be incorrect for odd counts */
+        counter = s->count - ((2 * d) % s->count);
+        break;
+    default:
+        counter = s->count - (d % s->count);
+        break;
+    }
+    return counter;
+}
+
+/* get pit output bit */
+static int pit_get_out1(PITChannelState *s, int64_t current_time)
+{
+    uint64_t d;
+    int out;
+
+    d = muldiv64(current_time - s->count_load_time, PIT_FREQ, ticks_per_sec);
+    switch(s->mode) {
+    default:
+    case 0:
+        out = (d >= s->count);
+        break;
+    case 1:
+        out = (d < s->count);
+        break;
+    case 2:
+        if ((d % s->count) == 0 && d != 0)
+            out = 1;
+        else
+            out = 0;
+        break;
+    case 3:
+        out = (d % s->count) < ((s->count + 1) >> 1);
+        break;
+    case 4:
+    case 5:
+        out = (d == s->count);
+        break;
+    }
+    return out;
+}
+
+int pit_get_out(PITState *pit, int channel, int64_t current_time)
+{
+    PITChannelState *s = &pit->channels[channel];
+    return pit_get_out1(s, current_time);
+}
+
+/* return -1 if no transition will occur.  */
+static int64_t pit_get_next_transition_time(PITChannelState *s, 
+                                            int64_t current_time)
+{
+    uint64_t d, next_time, base;
+    int period2;
+
+    d = muldiv64(current_time - s->count_load_time, PIT_FREQ, ticks_per_sec);
+    switch(s->mode) {
+    default:
+    case 0:
+    case 1:
+        if (d < s->count)
+            next_time = s->count;
+        else
+            return -1;
+        break;
+    case 2:
+        base = (d / s->count) * s->count;
+        if ((d - base) == 0 && d != 0)
+            next_time = base + s->count;
+        else
+            next_time = base + s->count + 1;
+        break;
+    case 3:
+        base = (d / s->count) * s->count;
+        period2 = ((s->count + 1) >> 1);
+        if ((d - base) < period2) 
+            next_time = base + period2;
+        else
+            next_time = base + s->count;
+        break;
+    case 4:
+    case 5:
+        if (d < s->count)
+            next_time = s->count;
+        else if (d == s->count)
+            next_time = s->count + 1;
+        else
+            return -1;
+        break;
+    }
+    /* convert to timer units */
+    next_time = s->count_load_time + muldiv64(next_time, ticks_per_sec, PIT_FREQ);
+    /* fix potential rounding problems */
+    /* XXX: better solution: use a clock at PIT_FREQ Hz */
+    if (next_time <= current_time)
+        next_time = current_time + 1;
+    return next_time;
+}
+
+/* val must be 0 or 1 */
+void pit_set_gate(PITState *pit, int channel, int val)
+{
+    PITChannelState *s = &pit->channels[channel];
+
+    switch(s->mode) {
+    default:
+    case 0:
+    case 4:
+        /* XXX: just disable/enable counting */
+        break;
+    case 1:
+    case 5:
+        if (s->gate < val) {
+            /* restart counting on rising edge */
+            s->count_load_time = qemu_get_clock(vm_clock);
+            pit_irq_timer_update(s, s->count_load_time);
+        }
+        break;
+    case 2:
+    case 3:
+        if (s->gate < val) {
+            /* restart counting on rising edge */
+            s->count_load_time = qemu_get_clock(vm_clock);
+            pit_irq_timer_update(s, s->count_load_time);
+        }
+        /* XXX: disable/enable counting */
+        break;
+    }
+    s->gate = val;
+}
+
+int pit_get_gate(PITState *pit, int channel)
+{
+    PITChannelState *s = &pit->channels[channel];
+    return s->gate;
+}
+
+static inline void pit_load_count(PITChannelState *s, int val)
+{
+    extern void *shared_page;
+    ioreq_t *req; 
+    int irq;
+
+    if (val == 0)
+        val = 0x10000;
+    s->count_load_time = qemu_get_clock(vm_clock);
+    s->count = val;
+
+    /* guest init this pit channel for periodic mode. we do not update related
+     * timer so the channel never send intr from device model*/
+    if (vmx_channel != -1 && s->mode == 2) {
+       /* get the pit irq(0)'s vector from pic DM */
+       if ((irq = pic_irq2vec(0)) >= 0) {
+           fprintf(logfile,
+               "VMX_PIT:guest init pit channel %d!\n", vmx_channel);
+           req = &((vcpu_iodata_t *) shared_page)->vp_ioreq;
+
+           req->state = STATE_IORESP_HOOK;
+           /*
+            * info passed to HV as following
+            * -- init count:16 bit, timer vec:8 bit,
+            * PIT channel(0~2):2 bit, rw mode:2 bit
+            */
+           req->u.data = s->count;
+           req->u.data |= (irq << 16);
+           req->u.data |= (vmx_channel << 24);
+           req->u.data |= ((s->rw_mode) << 26);
+           fprintf(logfile, "VMX_PIT:pass info 0x%llx to HV!\n", req->u.data);
+           vmx_channel = -1;
+       }
+    }
+
+/*    pit_irq_timer_update(s, s->count_load_time);*/
+}
+
+/* if already latched, do not latch again */
+static void pit_latch_count(PITChannelState *s)
+{
+    if (!s->count_latched) {
+        s->latched_count = pit_get_count(s);
+        s->count_latched = s->rw_mode;
+    }
+}
+
+static void pit_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+{
+    PITState *pit = opaque;
+    int channel, access;
+    PITChannelState *s;
+
+    addr &= 3;
+    if (addr == 3) {
+        channel = val >> 6;
+        if (channel == 3) {
+            /* read back command */
+            for(channel = 0; channel < 3; channel++) {
+                s = &pit->channels[channel];
+                if (val & (2 << channel)) {
+                    if (!(val & 0x20)) {
+                        pit_latch_count(s);
+                    }
+                    if (!(val & 0x10) && !s->status_latched) {
+                        /* status latch */
+                        /* XXX: add BCD and null count */
+                        s->status =  (pit_get_out1(s, qemu_get_clock(vm_clock)) << 7) |
+                            (s->rw_mode << 4) |
+                            (s->mode << 1) |
+                            s->bcd;
+                        s->status_latched = 1;
+                    }
+                }
+            }
+        } else {
+            s = &pit->channels[channel];
+            access = (val >> 4) & 3;
+            if (access == 0) {
+                pit_latch_count(s);
+            } else {
+                s->rw_mode = access;
+                s->read_state = access;
+                s->write_state = access;
+
+                s->mode = (val >> 1) & 7;
+                s->bcd = val & 1;
+                /* XXX: update irq timer ? */
+            }
+        }
+    } else {
+        s = &pit->channels[addr];
+        vmx_channel = addr;
+        switch(s->write_state) {
+        default:
+        case RW_STATE_LSB:
+            pit_load_count(s, val);
+            break;
+        case RW_STATE_MSB:
+            pit_load_count(s, val << 8);
+            break;
+        case RW_STATE_WORD0:
+            s->write_latch = val;
+            s->write_state = RW_STATE_WORD1;
+            break;
+        case RW_STATE_WORD1:
+            pit_load_count(s, s->write_latch | (val << 8));
+            s->write_state = RW_STATE_WORD0;
+            break;
+        }
+    }
+}
+
+static uint32_t pit_ioport_read(void *opaque, uint32_t addr)
+{
+    PITState *pit = opaque;
+    int ret, count;
+    PITChannelState *s;
+    
+    addr &= 3;
+    s = &pit->channels[addr];
+    if (s->status_latched) {
+        s->status_latched = 0;
+        ret = s->status;
+    } else if (s->count_latched) {
+        switch(s->count_latched) {
+        default:
+        case RW_STATE_LSB:
+            ret = s->latched_count & 0xff;
+            s->count_latched = 0;
+            break;
+        case RW_STATE_MSB:
+            ret = s->latched_count >> 8;
+            s->count_latched = 0;
+            break;
+        case RW_STATE_WORD0:
+            ret = s->latched_count & 0xff;
+            s->count_latched = RW_STATE_MSB;
+            break;
+        }
+    } else {
+        switch(s->read_state) {
+        default:
+        case RW_STATE_LSB:
+            count = pit_get_count(s);
+            ret = count & 0xff;
+            break;
+        case RW_STATE_MSB:
+            count = pit_get_count(s);
+            ret = (count >> 8) & 0xff;
+            break;
+        case RW_STATE_WORD0:
+            count = pit_get_count(s);
+            ret = count & 0xff;
+            s->read_state = RW_STATE_WORD1;
+            break;
+        case RW_STATE_WORD1:
+            count = pit_get_count(s);
+            ret = (count >> 8) & 0xff;
+            s->read_state = RW_STATE_WORD0;
+            break;
+        }
+    }
+    return ret;
+}
+
+static void pit_irq_timer_update(PITChannelState *s, int64_t current_time)
+{
+    int64_t expire_time;
+    int irq_level;
+
+    if (!s->irq_timer)
+        return;
+    expire_time = pit_get_next_transition_time(s, current_time);
+    irq_level = pit_get_out1(s, current_time);
+    pic_set_irq(s->irq, irq_level);
+#ifdef DEBUG_PIT
+    printf("irq_level=%d next_delay=%f\n",
+           irq_level, 
+           (double)(expire_time - current_time) / ticks_per_sec);
+#endif
+    s->next_transition_time = expire_time;
+    if (expire_time != -1)
+        qemu_mod_timer(s->irq_timer, expire_time);
+    else
+        qemu_del_timer(s->irq_timer);
+}
+
+static void pit_irq_timer(void *opaque)
+{
+    PITChannelState *s = opaque;
+
+    pit_irq_timer_update(s, s->next_transition_time);
+}
+
+static void pit_save(QEMUFile *f, void *opaque)
+{
+    PITState *pit = opaque;
+    PITChannelState *s;
+    int i;
+    
+    for(i = 0; i < 3; i++) {
+        s = &pit->channels[i];
+        qemu_put_be32s(f, &s->count);
+        qemu_put_be16s(f, &s->latched_count);
+        qemu_put_8s(f, &s->count_latched);
+        qemu_put_8s(f, &s->status_latched);
+        qemu_put_8s(f, &s->status);
+        qemu_put_8s(f, &s->read_state);
+        qemu_put_8s(f, &s->write_state);
+        qemu_put_8s(f, &s->write_latch);
+        qemu_put_8s(f, &s->rw_mode);
+        qemu_put_8s(f, &s->mode);
+        qemu_put_8s(f, &s->bcd);
+        qemu_put_8s(f, &s->gate);
+        qemu_put_be64s(f, &s->count_load_time);
+        if (s->irq_timer) {
+            qemu_put_be64s(f, &s->next_transition_time);
+            qemu_put_timer(f, s->irq_timer);
+        }
+    }
+}
+
+static int pit_load(QEMUFile *f, void *opaque, int version_id)
+{
+    PITState *pit = opaque;
+    PITChannelState *s;
+    int i;
+    
+    if (version_id != 1)
+        return -EINVAL;
+
+    for(i = 0; i < 3; i++) {
+        s = &pit->channels[i];
+        qemu_get_be32s(f, &s->count);
+        qemu_get_be16s(f, &s->latched_count);
+        qemu_get_8s(f, &s->count_latched);
+        qemu_get_8s(f, &s->status_latched);
+        qemu_get_8s(f, &s->status);
+        qemu_get_8s(f, &s->read_state);
+        qemu_get_8s(f, &s->write_state);
+        qemu_get_8s(f, &s->write_latch);
+        qemu_get_8s(f, &s->rw_mode);
+        qemu_get_8s(f, &s->mode);
+        qemu_get_8s(f, &s->bcd);
+        qemu_get_8s(f, &s->gate);
+        qemu_get_be64s(f, &s->count_load_time);
+        if (s->irq_timer) {
+            qemu_get_be64s(f, &s->next_transition_time);
+            qemu_get_timer(f, s->irq_timer);
+        }
+    }
+    return 0;
+}
+
+static void pit_reset(void *opaque)
+{
+    PITState *pit = opaque;
+    PITChannelState *s;
+    int i;
+
+    for(i = 0;i < 3; i++) {
+        s = &pit->channels[i];
+        s->mode = 3;
+        s->gate = (i != 2);
+        pit_load_count(s, 0);
+    }
+}
+
+PITState *pit_init(int base, int irq)
+{
+    PITState *pit = &pit_state;
+    PITChannelState *s;
+
+    s = &pit->channels[0];
+    /* the timer 0 is connected to an IRQ */
+    s->irq_timer = qemu_new_timer(vm_clock, pit_irq_timer, s);
+    s->irq = irq;
+
+    register_savevm("i8254", base, 1, pit_save, pit_load, pit);
+
+    qemu_register_reset(pit_reset, pit);
+    register_ioport_write(base, 4, 1, pit_ioport_write, pit);
+    register_ioport_read(base, 3, 1, pit_ioport_read, pit);
+
+    pit_reset(pit);
+
+    return pit;
+}
diff --git a/tools/ioemu/hw/i8259.c b/tools/ioemu/hw/i8259.c
new file mode 100644 (file)
index 0000000..859c64b
--- /dev/null
@@ -0,0 +1,528 @@
+/*
+ * QEMU 8259 interrupt controller emulation
+ * 
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+
+/* debug PIC */
+//#define DEBUG_PIC
+
+//#define DEBUG_IRQ_LATENCY
+//#define DEBUG_IRQ_COUNT
+
+typedef struct PicState {
+    uint8_t last_irr; /* edge detection */
+    uint8_t irr; /* interrupt request register */
+    uint8_t imr; /* interrupt mask register */
+    uint8_t isr; /* interrupt service register */
+    uint8_t priority_add; /* highest irq priority */
+    uint8_t irq_base;
+    uint8_t read_reg_select;
+    uint8_t poll;
+    uint8_t special_mask;
+    uint8_t init_state;
+    uint8_t auto_eoi;
+    uint8_t rotate_on_auto_eoi;
+    uint8_t special_fully_nested_mode;
+    uint8_t init4; /* true if 4 byte init */
+    uint8_t elcr; /* PIIX edge/trigger selection*/
+    uint8_t elcr_mask;
+} PicState;
+
+/* 0 is master pic, 1 is slave pic */
+static PicState pics[2];
+
+#if defined(DEBUG_PIC) || defined (DEBUG_IRQ_COUNT)
+static int irq_level[16];
+#endif
+#ifdef DEBUG_IRQ_COUNT
+static uint64_t irq_count[16];
+#endif
+
+/* set irq level. If an edge is detected, then the IRR is set to 1 */
+static inline void pic_set_irq1(PicState *s, int irq, int level)
+{
+    int mask;
+    mask = 1 << irq;
+    if (s->elcr & mask) {
+        /* level triggered */
+        if (level) {
+            s->irr |= mask;
+            s->last_irr |= mask;
+        } else {
+            s->irr &= ~mask;
+            s->last_irr &= ~mask;
+        }
+    } else {
+        /* edge triggered */
+        if (level) {
+            if ((s->last_irr & mask) == 0)
+                s->irr |= mask;
+            s->last_irr |= mask;
+        } else {
+            s->last_irr &= ~mask;
+        }
+    }
+}
+
+/* return the highest priority found in mask (highest = smallest
+   number). Return 8 if no irq */
+static inline int get_priority(PicState *s, int mask)
+{
+    int priority;
+    if (mask == 0)
+        return 8;
+    priority = 0;
+    while ((mask & (1 << ((priority + s->priority_add) & 7))) == 0)
+        priority++;
+    return priority;
+}
+
+/* return the pic wanted interrupt. return -1 if none */
+static int pic_get_irq(PicState *s)
+{
+    int mask, cur_priority, priority;
+
+    mask = s->irr & ~s->imr;
+    priority = get_priority(s, mask);
+    if (priority == 8)
+        return -1;
+    /* compute current priority. If special fully nested mode on the
+       master, the IRQ coming from the slave is not taken into account
+       for the priority computation. */
+    mask = s->isr;
+    if (s->special_fully_nested_mode && s == &pics[0])
+        mask &= ~(1 << 2);
+    cur_priority = get_priority(s, mask);
+    if (priority < cur_priority) {
+        /* higher priority found: an irq should be generated */
+        return (priority + s->priority_add) & 7;
+    } else {
+        return -1;
+    }
+}
+
+/* raise irq to CPU if necessary. must be called every time the active
+   irq may change */
+static void pic_update_irq(void)
+{
+    int irq2, irq;
+
+    /* first look at slave pic */
+    irq2 = pic_get_irq(&pics[1]);
+    if (irq2 >= 0) {
+        /* if irq request by slave pic, signal master PIC */
+        pic_set_irq1(&pics[0], 2, 1);
+        pic_set_irq1(&pics[0], 2, 0);
+    }
+    /* look at requested irq */
+    irq = pic_get_irq(&pics[0]);
+    if (irq >= 0) {
+#if defined(DEBUG_PIC)
+        {
+            int i;
+            for(i = 0; i < 2; i++) {
+                printf("pic%d: imr=%x irr=%x padd=%d\n", 
+                       i, pics[i].imr, pics[i].irr, pics[i].priority_add);
+                
+            }
+        }
+        printf("pic: cpu_interrupt\n");
+#endif
+        cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HARD);
+    }
+}
+
+#ifdef DEBUG_IRQ_LATENCY
+int64_t irq_time[16];
+#endif
+
+void pic_set_irq(int irq, int level)
+{
+#if defined(DEBUG_PIC) || defined(DEBUG_IRQ_COUNT)
+    if (level != irq_level[irq]) {
+#if defined(DEBUG_PIC)
+        printf("pic_set_irq: irq=%d level=%d\n", irq, level);
+#endif
+        irq_level[irq] = level;
+#ifdef DEBUG_IRQ_COUNT
+       if (level == 1)
+           irq_count[irq]++;
+#endif
+    }
+#endif
+#ifdef DEBUG_IRQ_LATENCY
+    if (level) {
+        irq_time[irq] = qemu_get_clock(vm_clock);
+    }
+#endif
+    pic_set_irq1(&pics[irq >> 3], irq & 7, level);
+    pic_update_irq();
+}
+
+/* acknowledge interrupt 'irq' */
+static inline void pic_intack(PicState *s, int irq)
+{
+    if (s->auto_eoi) {
+        if (s->rotate_on_auto_eoi)
+            s->priority_add = (irq + 1) & 7;
+    } else {
+        s->isr |= (1 << irq);
+    }
+    /* We don't clear a level sensitive interrupt here */
+    if (!(s->elcr & (1 << irq)))
+        s->irr &= ~(1 << irq);
+}
+
+int cpu_get_pic_interrupt(CPUState *env)
+{
+    int irq, irq2, intno;
+
+    /* read the irq from the PIC */
+
+    irq = pic_get_irq(&pics[0]);
+    if (irq >= 0) {
+        pic_intack(&pics[0], irq);
+        if (irq == 2) {
+            irq2 = pic_get_irq(&pics[1]);
+            if (irq2 >= 0) {
+                pic_intack(&pics[1], irq2);
+            } else {
+                /* spurious IRQ on slave controller */
+                irq2 = 7;
+            }
+            intno = pics[1].irq_base + irq2;
+            irq = irq2 + 8;
+        } else {
+            intno = pics[0].irq_base + irq;
+        }
+    } else {
+        /* spurious IRQ on host controller */
+        irq = 7;
+        intno = pics[0].irq_base + irq;
+    }
+    pic_update_irq();
+        
+#ifdef DEBUG_IRQ_LATENCY
+    printf("IRQ%d latency=%0.3fus\n", 
+           irq, 
+           (double)(qemu_get_clock(vm_clock) - irq_time[irq]) * 1000000.0 / ticks_per_sec);
+#endif
+#if defined(DEBUG_PIC)
+    printf("pic_interrupt: irq=%d\n", irq);
+#endif
+    return intno;
+}
+
+int pic_irq2vec(int irq)
+{
+    int vector = -1;
+
+    if (irq >= 8 && irq <= 15) {
+       if (pics[1].irq_base != 0xFF)
+               vector = pics[1].irq_base + irq;
+    } else if (irq != 2 && irq <= 7) {
+       if (pics[0].irq_base != 0xFF)
+               vector = pics[0].irq_base + irq;
+    } 
+    return vector;
+}
+
+static void pic_reset(void *opaque)
+{
+    PicState *s = opaque;
+    int tmp;
+
+    tmp = s->elcr_mask;
+    memset(s, 0, sizeof(PicState));
+    s->elcr_mask = tmp;
+}
+
+static void pic_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+{
+    PicState *s = opaque;
+    int priority, cmd, irq;
+
+#ifdef DEBUG_PIC
+    printf("pic_write: addr=0x%02x val=0x%02x\n", addr, val);
+#endif
+    addr &= 1;
+    if (addr == 0) {
+        if (val & 0x10) {
+            /* init */
+            pic_reset(s);
+            /* deassert a pending interrupt */
+            cpu_reset_interrupt(cpu_single_env, CPU_INTERRUPT_HARD);
+
+            s->init_state = 1;
+            s->init4 = val & 1;
+            if (val & 0x02)
+                hw_error("single mode not supported");
+            if (val & 0x08)
+                hw_error("level sensitive irq not supported");
+        } else if (val & 0x08) {
+            if (val & 0x04)
+                s->poll = 1;
+            if (val & 0x02)
+                s->read_reg_select = val & 1;
+            if (val & 0x40)
+                s->special_mask = (val >> 5) & 1;
+        } else {
+            cmd = val >> 5;
+            switch(cmd) {
+            case 0:
+            case 4:
+                s->rotate_on_auto_eoi = cmd >> 2;
+                break;
+            case 1: /* end of interrupt */
+            case 5:
+                priority = get_priority(s, s->isr);
+                if (priority != 8) {
+                    irq = (priority + s->priority_add) & 7;
+                    s->isr &= ~(1 << irq);
+                    if (cmd == 5)
+                        s->priority_add = (irq + 1) & 7;
+                    pic_update_irq();
+                }
+                break;
+            case 3:
+                irq = val & 7;
+                s->isr &= ~(1 << irq);
+                pic_update_irq();
+                break;
+            case 6:
+                s->priority_add = (val + 1) & 7;
+                pic_update_irq();
+                break;
+            case 7:
+                irq = val & 7;
+                s->isr &= ~(1 << irq);
+                s->priority_add = (irq + 1) & 7;
+                pic_update_irq();
+                break;
+            default:
+                /* no operation */
+                break;
+            }
+        }
+    } else {
+        switch(s->init_state) {
+        case 0:
+            /* normal mode */
+            s->imr = val;
+            pic_update_irq();
+            break;
+        case 1:
+            s->irq_base = val & 0xf8;
+            s->init_state = 2;
+            break;
+        case 2:
+            if (s->init4) {
+                s->init_state = 3;
+            } else {
+                s->init_state = 0;
+            }
+            break;
+        case 3:
+            s->special_fully_nested_mode = (val >> 4) & 1;
+            s->auto_eoi = (val >> 1) & 1;
+            s->init_state = 0;
+            break;
+        }
+    }
+}
+
+static uint32_t pic_poll_read (PicState *s, uint32_t addr1)
+{
+    int ret;
+
+    ret = pic_get_irq(s);
+    if (ret >= 0) {
+        if (addr1 >> 7) {
+            pics[0].isr &= ~(1 << 2);
+            pics[0].irr &= ~(1 << 2);
+        }
+        s->irr &= ~(1 << ret);
+        s->isr &= ~(1 << ret);
+        if (addr1 >> 7 || ret != 2)
+            pic_update_irq();
+    } else {
+        ret = 0x07;
+        pic_update_irq();
+    }
+
+    return ret;
+}
+
+static uint32_t pic_ioport_read(void *opaque, uint32_t addr1)
+{
+    PicState *s = opaque;
+    unsigned int addr;
+    int ret;
+
+    addr = addr1;
+    addr &= 1;
+    if (s->poll) {
+        ret = pic_poll_read(s, addr1);
+        s->poll = 0;
+    } else {
+        if (addr == 0) {
+            if (s->read_reg_select)
+                ret = s->isr;
+            else
+                ret = s->irr;
+        } else {
+            ret = s->imr;
+        }
+    }
+#ifdef DEBUG_PIC
+    printf("pic_read: addr=0x%02x val=0x%02x\n", addr1, ret);
+#endif
+    return ret;
+}
+
+/* memory mapped interrupt status */
+uint32_t pic_intack_read(CPUState *env)
+{
+    int ret;
+
+    ret = pic_poll_read(&pics[0], 0x00);
+    if (ret == 2)
+        ret = pic_poll_read(&pics[1], 0x80) + 8;
+    /* Prepare for ISR read */
+    pics[0].read_reg_select = 1;
+    
+    return ret;
+}
+
+static void elcr_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+{
+    PicState *s = opaque;
+    s->elcr = val & s->elcr_mask;
+}
+
+static uint32_t elcr_ioport_read(void *opaque, uint32_t addr1)
+{
+    PicState *s = opaque;
+    return s->elcr;
+}
+
+static void pic_save(QEMUFile *f, void *opaque)
+{
+    PicState *s = opaque;
+    
+    qemu_put_8s(f, &s->last_irr);
+    qemu_put_8s(f, &s->irr);
+    qemu_put_8s(f, &s->imr);
+    qemu_put_8s(f, &s->isr);
+    qemu_put_8s(f, &s->priority_add);
+    qemu_put_8s(f, &s->irq_base);
+    qemu_put_8s(f, &s->read_reg_select);
+    qemu_put_8s(f, &s->poll);
+    qemu_put_8s(f, &s->special_mask);
+    qemu_put_8s(f, &s->init_state);
+    qemu_put_8s(f, &s->auto_eoi);
+    qemu_put_8s(f, &s->rotate_on_auto_eoi);
+    qemu_put_8s(f, &s->special_fully_nested_mode);
+    qemu_put_8s(f, &s->init4);
+    qemu_put_8s(f, &s->elcr);
+}
+
+static int pic_load(QEMUFile *f, void *opaque, int version_id)
+{
+    PicState *s = opaque;
+    
+    if (version_id != 1)
+        return -EINVAL;
+
+    qemu_get_8s(f, &s->last_irr);
+    qemu_get_8s(f, &s->irr);
+    qemu_get_8s(f, &s->imr);
+    qemu_get_8s(f, &s->isr);
+    qemu_get_8s(f, &s->priority_add);
+    qemu_get_8s(f, &s->irq_base);
+    qemu_get_8s(f, &s->read_reg_select);
+    qemu_get_8s(f, &s->poll);
+    qemu_get_8s(f, &s->special_mask);
+    qemu_get_8s(f, &s->init_state);
+    qemu_get_8s(f, &s->auto_eoi);
+    qemu_get_8s(f, &s->rotate_on_auto_eoi);
+    qemu_get_8s(f, &s->special_fully_nested_mode);
+    qemu_get_8s(f, &s->init4);
+    qemu_get_8s(f, &s->elcr);
+    return 0;
+}
+
+/* XXX: add generic master/slave system */
+static void pic_init1(int io_addr, int elcr_addr, PicState *s)
+{
+    register_ioport_write(io_addr, 2, 1, pic_ioport_write, s);
+    register_ioport_read(io_addr, 2, 1, pic_ioport_read, s);
+    if (elcr_addr >= 0) {
+        register_ioport_write(elcr_addr, 1, 1, elcr_ioport_write, s);
+        register_ioport_read(elcr_addr, 1, 1, elcr_ioport_read, s);
+    }
+    register_savevm("i8259", io_addr, 1, pic_save, pic_load, s);
+    qemu_register_reset(pic_reset, s);
+}
+
+void pic_info(void)
+{
+    int i;
+    PicState *s;
+
+    for(i=0;i<2;i++) {
+        s = &pics[i];
+        term_printf("pic%d: irr=%02x imr=%02x isr=%02x hprio=%d irq_base=%02x rr_sel=%d elcr=%02x fnm=%d\n",
+                    i, s->irr, s->imr, s->isr, s->priority_add, 
+                    s->irq_base, s->read_reg_select, s->elcr, 
+                    s->special_fully_nested_mode);
+    }
+}
+
+void irq_info(void)
+{
+#ifndef DEBUG_IRQ_COUNT
+    term_printf("irq statistic code not compiled.\n");
+#else
+    int i;
+    int64_t count;
+
+    term_printf("IRQ statistics:\n");
+    for (i = 0; i < 16; i++) {
+        count = irq_count[i];
+        if (count > 0)
+            term_printf("%2d: %lld\n", i, count);
+    }
+#endif
+}
+
+void pic_init(void)
+{
+    pic_init1(0x20, 0x4d0, &pics[0]);
+    pic_init1(0xa0, 0x4d1, &pics[1]);
+    pics[0].elcr_mask = 0xf8;
+    pics[1].elcr_mask = 0xde;
+    pics[0].irq_base = 0xff;
+    pics[0].irq_base = 0xff;
+}
+
diff --git a/tools/ioemu/hw/ide.c b/tools/ioemu/hw/ide.c
new file mode 100644 (file)
index 0000000..bc7ebd3
--- /dev/null
@@ -0,0 +1,2318 @@
+/*
+ * QEMU IDE disk and CD-ROM Emulator
+ * 
+ * Copyright (c) 2003 Fabrice Bellard
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+
+/* debug IDE devices */
+//#define DEBUG_IDE
+//#define DEBUG_IDE_ATAPI
+
+/* Bits of HD_STATUS */
+#define ERR_STAT               0x01
+#define INDEX_STAT             0x02
+#define ECC_STAT               0x04    /* Corrected error */
+#define DRQ_STAT               0x08
+#define SEEK_STAT              0x10
+#define SRV_STAT               0x10
+#define WRERR_STAT             0x20
+#define READY_STAT             0x40
+#define BUSY_STAT              0x80
+
+/* Bits for HD_ERROR */
+#define MARK_ERR               0x01    /* Bad address mark */
+#define TRK0_ERR               0x02    /* couldn't find track 0 */
+#define ABRT_ERR               0x04    /* Command aborted */
+#define MCR_ERR                        0x08    /* media change request */
+#define ID_ERR                 0x10    /* ID field not found */
+#define MC_ERR                 0x20    /* media changed */
+#define ECC_ERR                        0x40    /* Uncorrectable ECC error */
+#define BBD_ERR                        0x80    /* pre-EIDE meaning:  block marked bad */
+#define ICRC_ERR               0x80    /* new meaning:  CRC error during transfer */
+
+/* Bits of HD_NSECTOR */
+#define CD                     0x01
+#define IO                     0x02
+#define REL                    0x04
+#define TAG_MASK               0xf8
+
+#define IDE_CMD_RESET           0x04
+#define IDE_CMD_DISABLE_IRQ     0x02
+
+/* ATA/ATAPI Commands pre T13 Spec */
+#define WIN_NOP                                0x00
+/*
+ *     0x01->0x02 Reserved
+ */
+#define CFA_REQ_EXT_ERROR_CODE         0x03 /* CFA Request Extended Error Code */
+/*
+ *     0x04->0x07 Reserved
+ */
+#define WIN_SRST                       0x08 /* ATAPI soft reset command */
+#define WIN_DEVICE_RESET               0x08
+/*
+ *     0x09->0x0F Reserved
+ */
+#define WIN_RECAL                      0x10
+#define WIN_RESTORE                    WIN_RECAL
+/*
+ *     0x10->0x1F Reserved
+ */
+#define WIN_READ                       0x20 /* 28-Bit */
+#define WIN_READ_ONCE                  0x21 /* 28-Bit without retries */
+#define WIN_READ_LONG                  0x22 /* 28-Bit */
+#define WIN_READ_LONG_ONCE             0x23 /* 28-Bit without retries */
+#define WIN_READ_EXT                   0x24 /* 48-Bit */
+#define WIN_READDMA_EXT                        0x25 /* 48-Bit */
+#define WIN_READDMA_QUEUED_EXT         0x26 /* 48-Bit */
+#define WIN_READ_NATIVE_MAX_EXT                0x27 /* 48-Bit */
+/*
+ *     0x28
+ */
+#define WIN_MULTREAD_EXT               0x29 /* 48-Bit */
+/*
+ *     0x2A->0x2F Reserved
+ */
+#define WIN_WRITE                      0x30 /* 28-Bit */
+#define WIN_WRITE_ONCE                 0x31 /* 28-Bit without retries */
+#define WIN_WRITE_LONG                 0x32 /* 28-Bit */
+#define WIN_WRITE_LONG_ONCE            0x33 /* 28-Bit without retries */
+#define WIN_WRITE_EXT                  0x34 /* 48-Bit */
+#define WIN_WRITEDMA_EXT               0x35 /* 48-Bit */
+#define WIN_WRITEDMA_QUEUED_EXT                0x36 /* 48-Bit */
+#define WIN_SET_MAX_EXT                        0x37 /* 48-Bit */
+#define CFA_WRITE_SECT_WO_ERASE                0x38 /* CFA Write Sectors without erase */
+#define WIN_MULTWRITE_EXT              0x39 /* 48-Bit */
+/*
+ *     0x3A->0x3B Reserved
+ */
+#define WIN_WRITE_VERIFY               0x3C /* 28-Bit */
+/*
+ *     0x3D->0x3F Reserved
+ */
+#define WIN_VERIFY                     0x40 /* 28-Bit - Read Verify Sectors */
+#define WIN_VERIFY_ONCE                        0x41 /* 28-Bit - without retries */
+#define WIN_VERIFY_EXT                 0x42 /* 48-Bit */
+/*
+ *     0x43->0x4F Reserved
+ */
+#define WIN_FORMAT                     0x50
+/*
+ *     0x51->0x5F Reserved
+ */
+#define WIN_INIT                       0x60
+/*
+ *     0x61->0x5F Reserved
+ */
+#define WIN_SEEK                       0x70 /* 0x70-0x7F Reserved */
+#define CFA_TRANSLATE_SECTOR           0x87 /* CFA Translate Sector */
+#define WIN_DIAGNOSE                   0x90
+#define WIN_SPECIFY                    0x91 /* set drive geometry translation */
+#define WIN_DOWNLOAD_MICROCODE         0x92
+#define WIN_STANDBYNOW2                        0x94
+#define WIN_STANDBY2                   0x96
+#define WIN_SETIDLE2                   0x97
+#define WIN_CHECKPOWERMODE2            0x98
+#define WIN_SLEEPNOW2                  0x99
+/*
+ *     0x9A VENDOR
+ */
+#define WIN_PACKETCMD                  0xA0 /* Send a packet command. */
+#define WIN_PIDENTIFY                  0xA1 /* identify ATAPI device   */
+#define WIN_QUEUED_SERVICE             0xA2
+#define WIN_SMART                      0xB0 /* self-monitoring and reporting */
+#define CFA_ERASE_SECTORS              0xC0
+#define WIN_MULTREAD                   0xC4 /* read sectors using multiple mode*/
+#define WIN_MULTWRITE                  0xC5 /* write sectors using multiple mode */
+#define WIN_SETMULT                    0xC6 /* enable/disable multiple mode */
+#define WIN_READDMA_QUEUED             0xC7 /* read sectors using Queued DMA transfers */
+#define WIN_READDMA                    0xC8 /* read sectors using DMA transfers */
+#define WIN_READDMA_ONCE               0xC9 /* 28-Bit - without retries */
+#define WIN_WRITEDMA                   0xCA /* write sectors using DMA transfers */
+#define WIN_WRITEDMA_ONCE              0xCB /* 28-Bit - without retries */
+#define WIN_WRITEDMA_QUEUED            0xCC /* write sectors using Queued DMA transfers */
+#define CFA_WRITE_MULTI_WO_ERASE       0xCD /* CFA Write multiple without erase */
+#define WIN_GETMEDIASTATUS             0xDA    
+#define WIN_ACKMEDIACHANGE             0xDB /* ATA-1, ATA-2 vendor */
+#define WIN_POSTBOOT                   0xDC
+#define WIN_PREBOOT                    0xDD
+#define WIN_DOORLOCK                   0xDE /* lock door on removable drives */
+#define WIN_DOORUNLOCK                 0xDF /* unlock door on removable drives */
+#define WIN_STANDBYNOW1                        0xE0
+#define WIN_IDLEIMMEDIATE              0xE1 /* force drive to become "ready" */
+#define WIN_STANDBY                    0xE2 /* Set device in Standby Mode */
+#define WIN_SETIDLE1                   0xE3
+#define WIN_READ_BUFFER                        0xE4 /* force read only 1 sector */
+#define WIN_CHECKPOWERMODE1            0xE5
+#define WIN_SLEEPNOW1                  0xE6
+#define WIN_FLUSH_CACHE                        0xE7
+#define WIN_WRITE_BUFFER               0xE8 /* force write only 1 sector */
+#define WIN_WRITE_SAME                 0xE9 /* read ata-2 to use */
+       /* SET_FEATURES 0x22 or 0xDD */
+#define WIN_FLUSH_CACHE_EXT            0xEA /* 48-Bit */
+#define WIN_IDENTIFY                   0xEC /* ask drive to identify itself    */
+#define WIN_MEDIAEJECT                 0xED
+#define WIN_IDENTIFY_DMA               0xEE /* same as WIN_IDENTIFY, but DMA */
+#define WIN_SETFEATURES                        0xEF /* set special drive features */
+#define EXABYTE_ENABLE_NEST            0xF0
+#define WIN_SECURITY_SET_PASS          0xF1
+#define WIN_SECURITY_UNLOCK            0xF2
+#define WIN_SECURITY_ERASE_PREPARE     0xF3
+#define WIN_SECURITY_ERASE_UNIT                0xF4
+#define WIN_SECURITY_FREEZE_LOCK       0xF5
+#define WIN_SECURITY_DISABLE           0xF6
+#define WIN_READ_NATIVE_MAX            0xF8 /* return the native maximum address */
+#define WIN_SET_MAX                    0xF9
+#define DISABLE_SEAGATE                        0xFB
+
+/* set to 1 set disable mult support */
+#define MAX_MULT_SECTORS 16
+
+/* ATAPI defines */
+
+#define ATAPI_PACKET_SIZE 12
+
+/* The generic packet command opcodes for CD/DVD Logical Units,
+ * From Table 57 of the SFF8090 Ver. 3 (Mt. Fuji) draft standard. */
+#define GPCMD_BLANK                        0xa1
+#define GPCMD_CLOSE_TRACK                  0x5b
+#define GPCMD_FLUSH_CACHE                  0x35
+#define GPCMD_FORMAT_UNIT                  0x04
+#define GPCMD_GET_CONFIGURATION                    0x46
+#define GPCMD_GET_EVENT_STATUS_NOTIFICATION 0x4a
+#define GPCMD_GET_PERFORMANCE              0xac
+#define GPCMD_INQUIRY                      0x12
+#define GPCMD_LOAD_UNLOAD                  0xa6
+#define GPCMD_MECHANISM_STATUS             0xbd
+#define GPCMD_MODE_SELECT_10               0x55
+#define GPCMD_MODE_SENSE_10                0x5a
+#define GPCMD_PAUSE_RESUME                 0x4b
+#define GPCMD_PLAY_AUDIO_10                0x45
+#define GPCMD_PLAY_AUDIO_MSF               0x47
+#define GPCMD_PLAY_AUDIO_TI                0x48
+#define GPCMD_PLAY_CD                      0xbc
+#define GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL  0x1e
+#define GPCMD_READ_10                      0x28
+#define GPCMD_READ_12                      0xa8
+#define GPCMD_READ_CDVD_CAPACITY           0x25
+#define GPCMD_READ_CD                      0xbe
+#define GPCMD_READ_CD_MSF                  0xb9
+#define GPCMD_READ_DISC_INFO               0x51
+#define GPCMD_READ_DVD_STRUCTURE           0xad
+#define GPCMD_READ_FORMAT_CAPACITIES       0x23
+#define GPCMD_READ_HEADER                  0x44
+#define GPCMD_READ_TRACK_RZONE_INFO        0x52
+#define GPCMD_READ_SUBCHANNEL              0x42
+#define GPCMD_READ_TOC_PMA_ATIP                    0x43
+#define GPCMD_REPAIR_RZONE_TRACK           0x58
+#define GPCMD_REPORT_KEY                   0xa4
+#define GPCMD_REQUEST_SENSE                0x03
+#define GPCMD_RESERVE_RZONE_TRACK          0x53
+#define GPCMD_SCAN                         0xba
+#define GPCMD_SEEK                         0x2b
+#define GPCMD_SEND_DVD_STRUCTURE           0xad
+#define GPCMD_SEND_EVENT                   0xa2
+#define GPCMD_SEND_KEY                     0xa3
+#define GPCMD_SEND_OPC                     0x54
+#define GPCMD_SET_READ_AHEAD               0xa7
+#define GPCMD_SET_STREAMING                0xb6
+#define GPCMD_START_STOP_UNIT              0x1b
+#define GPCMD_STOP_PLAY_SCAN               0x4e
+#define GPCMD_TEST_UNIT_READY              0x00
+#define GPCMD_VERIFY_10                            0x2f
+#define GPCMD_WRITE_10                     0x2a
+#define GPCMD_WRITE_AND_VERIFY_10          0x2e
+/* This is listed as optional in ATAPI 2.6, but is (curiously) 
+ * missing from Mt. Fuji, Table 57.  It _is_ mentioned in Mt. Fuji
+ * Table 377 as an MMC command for SCSi devices though...  Most ATAPI
+ * drives support it. */
+#define GPCMD_SET_SPEED                            0xbb
+/* This seems to be a SCSI specific CD-ROM opcode 
+ * to play data at track/index */
+#define GPCMD_PLAYAUDIO_TI                 0x48
+/*
+ * From MS Media Status Notification Support Specification. For
+ * older drives only.
+ */
+#define GPCMD_GET_MEDIA_STATUS             0xda
+
+/* Mode page codes for mode sense/set */
+#define GPMODE_R_W_ERROR_PAGE          0x01
+#define GPMODE_WRITE_PARMS_PAGE                0x05
+#define GPMODE_AUDIO_CTL_PAGE          0x0e
+#define GPMODE_POWER_PAGE              0x1a
+#define GPMODE_FAULT_FAIL_PAGE         0x1c
+#define GPMODE_TO_PROTECT_PAGE         0x1d
+#define GPMODE_CAPABILITIES_PAGE       0x2a
+#define GPMODE_ALL_PAGES               0x3f
+/* Not in Mt. Fuji, but in ATAPI 2.6 -- depricated now in favor
+ * of MODE_SENSE_POWER_PAGE */
+#define GPMODE_CDROM_PAGE              0x0d
+
+#define ATAPI_INT_REASON_CD             0x01 /* 0 = data transfer */
+#define ATAPI_INT_REASON_IO             0x02 /* 1 = transfer to the host */
+#define ATAPI_INT_REASON_REL            0x04
+#define ATAPI_INT_REASON_TAG            0xf8
+
+/* same constants as bochs */
+#define ASC_ILLEGAL_OPCODE                   0x20
+#define ASC_LOGICAL_BLOCK_OOR                0x21
+#define ASC_INV_FIELD_IN_CMD_PACKET          0x24
+#define ASC_MEDIUM_NOT_PRESENT               0x3a
+#define ASC_SAVING_PARAMETERS_NOT_SUPPORTED  0x39
+
+#define SENSE_NONE            0
+#define SENSE_NOT_READY       2
+#define SENSE_ILLEGAL_REQUEST 5
+#define SENSE_UNIT_ATTENTION  6
+
+struct IDEState;
+
+typedef void EndTransferFunc(struct IDEState *);
+
+/* NOTE: IDEState represents in fact one drive */
+typedef struct IDEState {
+    /* ide config */
+    int is_cdrom;
+    int cylinders, heads, sectors;
+    int64_t nb_sectors;
+    int mult_sectors;
+    int irq;
+    openpic_t *openpic;
+    PCIDevice *pci_dev;
+    struct BMDMAState *bmdma;
+    int drive_serial;
+    /* ide regs */
+    uint8_t feature;
+    uint8_t error;
+    uint16_t nsector; /* 0 is 256 to ease computations */
+    uint8_t sector;
+    uint8_t lcyl;
+    uint8_t hcyl;
+    uint8_t select;
+    uint8_t status;
+    /* 0x3f6 command, only meaningful for drive 0 */
+    uint8_t cmd;
+    /* depends on bit 4 in select, only meaningful for drive 0 */
+    struct IDEState *cur_drive; 
+    BlockDriverState *bs;
+    /* ATAPI specific */
+    uint8_t sense_key;
+    uint8_t asc;
+    int packet_transfer_size;
+    int elementary_transfer_size;
+    int io_buffer_index;
+    int lba;
+    int cd_sector_size;
+    int atapi_dma; /* true if dma is requested for the packet cmd */
+    /* ATA DMA state */
+    int io_buffer_size;
+    /* PIO transfer handling */
+    int req_nb_sectors; /* number of sectors per interrupt */
+    EndTransferFunc *end_transfer_func;
+    uint8_t *data_ptr;
+    uint8_t *data_end;
+    uint8_t io_buffer[MAX_MULT_SECTORS*512 + 4];
+} IDEState;
+
+#define BM_STATUS_DMAING 0x01
+#define BM_STATUS_ERROR  0x02
+#define BM_STATUS_INT    0x04
+
+#define BM_CMD_START     0x01
+#define BM_CMD_READ      0x08
+
+typedef int IDEDMAFunc(IDEState *s, 
+                       target_phys_addr_t phys_addr, 
+                       int transfer_size1);
+
+typedef struct BMDMAState {
+    uint8_t cmd;
+    uint8_t status;
+    uint32_t addr;
+    /* current transfer state */
+    IDEState *ide_if;
+    IDEDMAFunc *dma_cb;
+} BMDMAState;
+
+typedef struct PCIIDEState {
+    PCIDevice dev;
+    IDEState ide_if[4];
+    BMDMAState bmdma[2];
+} PCIIDEState;
+
+static void ide_dma_start(IDEState *s, IDEDMAFunc *dma_cb);
+
+static void padstr(char *str, const char *src, int len)
+{
+    int i, v;
+    for(i = 0; i < len; i++) {
+        if (*src)
+            v = *src++;
+        else
+            v = ' ';
+        *(char *)((long)str ^ 1) = v;
+        str++;
+    }
+}
+
+static void padstr8(uint8_t *buf, int buf_size, const char *src)
+{
+    int i;
+    for(i = 0; i < buf_size; i++) {
+        if (*src)
+            buf[i] = *src++;
+        else
+            buf[i] = ' ';
+    }
+}
+
+static void put_le16(uint16_t *p, unsigned int v)
+{
+    *p = cpu_to_le16(v);
+}
+
+static void ide_identify(IDEState *s)
+{
+    uint16_t *p;
+    unsigned int oldsize;
+    char buf[20];
+
+    memset(s->io_buffer, 0, 512);
+    p = (uint16_t *)s->io_buffer;
+    put_le16(p + 0, 0x0040);
+    put_le16(p + 1, s->cylinders); 
+    put_le16(p + 3, s->heads);
+    put_le16(p + 4, 512 * s->sectors); /* XXX: retired, remove ? */
+    put_le16(p + 5, 512); /* XXX: retired, remove ? */
+    put_le16(p + 6, s->sectors); 
+    snprintf(buf, sizeof(buf), "QM%05d", s->drive_serial);
+    padstr((uint8_t *)(p + 10), buf, 20); /* serial number */
+    put_le16(p + 20, 3); /* XXX: retired, remove ? */
+    put_le16(p + 21, 512); /* cache size in sectors */
+    put_le16(p + 22, 4); /* ecc bytes */
+    padstr((uint8_t *)(p + 23), QEMU_VERSION, 8); /* firmware version */
+    padstr((uint8_t *)(p + 27), "QEMU HARDDISK", 40); /* model */
+#if MAX_MULT_SECTORS > 1    
+    put_le16(p + 47, 0x8000 | MAX_MULT_SECTORS);
+#endif
+    put_le16(p + 48, 1); /* dword I/O */
+    put_le16(p + 49, 1 << 9 | 1 << 8); /* DMA and LBA supported */
+    put_le16(p + 51, 0x200); /* PIO transfer cycle */
+    put_le16(p + 52, 0x200); /* DMA transfer cycle */
+    put_le16(p + 53, 1 | 1 << 2); /* words 54-58,88 are valid */
+    put_le16(p + 54, s->cylinders);
+    put_le16(p + 55, s->heads);
+    put_le16(p + 56, s->sectors);
+    oldsize = s->cylinders * s->heads * s->sectors;
+    put_le16(p + 57, oldsize);
+    put_le16(p + 58, oldsize >> 16);
+    if (s->mult_sectors)
+        put_le16(p + 59, 0x100 | s->mult_sectors);
+    put_le16(p + 60, s->nb_sectors);
+    put_le16(p + 61, s->nb_sectors >> 16);
+    put_le16(p + 80, (1 << 1) | (1 << 2));
+    put_le16(p + 82, (1 << 14));
+    put_le16(p + 83, (1 << 14));
+    put_le16(p + 84, (1 << 14));
+    put_le16(p + 85, (1 << 14));
+    put_le16(p + 86, 0);
+    put_le16(p + 87, (1 << 14));
+    put_le16(p + 88, 0x1f | (1 << 13));
+    put_le16(p + 93, 1 | (1 << 14) | 0x2000 | 0x4000);
+}
+
+static void ide_atapi_identify(IDEState *s)
+{
+    uint16_t *p;
+    char buf[20];
+
+    memset(s->io_buffer, 0, 512);
+    p = (uint16_t *)s->io_buffer;
+    /* Removable CDROM, 50us response, 12 byte packets */
+    put_le16(p + 0, (2 << 14) | (5 << 8) | (1 << 7) | (2 << 5) | (0 << 0));
+    snprintf(buf, sizeof(buf), "QM%05d", s->drive_serial);
+    padstr((uint8_t *)(p + 10), buf, 20); /* serial number */
+    put_le16(p + 20, 3); /* buffer type */
+    put_le16(p + 21, 512); /* cache size in sectors */
+    put_le16(p + 22, 4); /* ecc bytes */
+    padstr((uint8_t *)(p + 23), QEMU_VERSION, 8); /* firmware version */
+    padstr((uint8_t *)(p + 27), "QEMU CD-ROM", 40); /* model */
+    put_le16(p + 48, 1); /* dword I/O (XXX: should not be set on CDROM) */
+    put_le16(p + 49, 1 << 9); /* LBA supported, no DMA */
+    put_le16(p + 53, 3); /* words 64-70, 54-58 valid */
+    put_le16(p + 63, 0x103); /* DMA modes XXX: may be incorrect */
+    put_le16(p + 64, 1); /* PIO modes */
+    put_le16(p + 65, 0xb4); /* minimum DMA multiword tx cycle time */
+    put_le16(p + 66, 0xb4); /* recommended DMA multiword tx cycle time */
+    put_le16(p + 67, 0x12c); /* minimum PIO cycle time without flow control */
+    put_le16(p + 68, 0xb4); /* minimum PIO cycle time with IORDY flow control */
+    
+    put_le16(p + 71, 30); /* in ns */
+    put_le16(p + 72, 30); /* in ns */
+
+    put_le16(p + 80, 0x1e); /* support up to ATA/ATAPI-4 */
+}
+
+static void ide_set_signature(IDEState *s)
+{
+    s->select &= 0xf0; /* clear head */
+    /* put signature */
+    s->nsector = 1;
+    s->sector = 1;
+    if (s->is_cdrom) {
+        s->lcyl = 0x14;
+        s->hcyl = 0xeb;
+    } else if (s->bs) {
+        s->lcyl = 0;
+        s->hcyl = 0;
+    } else {
+        s->lcyl = 0xff;
+        s->hcyl = 0xff;
+    }
+}
+
+static inline void ide_abort_command(IDEState *s)
+{
+    s->status = READY_STAT | ERR_STAT;
+    s->error = ABRT_ERR;
+}
+
+static inline void ide_set_irq(IDEState *s)
+{
+    if (!(s->cmd & IDE_CMD_DISABLE_IRQ)) {
+#ifdef TARGET_PPC
+        if (s->openpic) 
+            openpic_set_irq(s->openpic, s->irq, 1);
+        else 
+#endif
+        if (s->irq == 16)
+            pci_set_irq(s->pci_dev, 0, 1);
+        else
+            pic_set_irq(s->irq, 1);
+    }
+}
+
+/* prepare data transfer and tell what to do after */
+static void ide_transfer_start(IDEState *s, uint8_t *buf, int size, 
+                               EndTransferFunc *end_transfer_func)
+{
+    s->end_transfer_func = end_transfer_func;
+    s->data_ptr = buf;
+    s->data_end = buf + size;
+    s->status |= DRQ_STAT;
+}
+
+static void ide_transfer_stop(IDEState *s)
+{
+    s->end_transfer_func = ide_transfer_stop;
+    s->data_ptr = s->io_buffer;
+    s->data_end = s->io_buffer;
+    s->status &= ~DRQ_STAT;
+}
+
+static int64_t ide_get_sector(IDEState *s)
+{
+    int64_t sector_num;
+    if (s->select & 0x40) {
+        /* lba */
+        sector_num = ((s->select & 0x0f) << 24) | (s->hcyl << 16) | 
+            (s->lcyl << 8) | s->sector;
+    } else {
+        sector_num = ((s->hcyl << 8) | s->lcyl) * s->heads * s->sectors +
+            (s->select & 0x0f) * s->sectors + 
+            (s->sector - 1);
+    }
+    return sector_num;
+}
+
+static void ide_set_sector(IDEState *s, int64_t sector_num)
+{
+    unsigned int cyl, r;
+    if (s->select & 0x40) {
+        s->select = (s->select & 0xf0) | (sector_num >> 24);
+        s->hcyl = (sector_num >> 16);
+        s->lcyl = (sector_num >> 8);
+        s->sector = (sector_num);
+    } else {
+        cyl = sector_num / (s->heads * s->sectors);
+        r = sector_num % (s->heads * s->sectors);
+        s->hcyl = cyl >> 8;
+        s->lcyl = cyl;
+        s->select = (s->select & 0xf0) | ((r / s->sectors) & 0x0f);
+        s->sector = (r % s->sectors) + 1;
+    }
+}
+
+static void ide_sector_read(IDEState *s)
+{
+    int64_t sector_num;
+    int ret, n;
+
+    s->status = READY_STAT | SEEK_STAT;
+    s->error = 0; /* not needed by IDE spec, but needed by Windows */
+    sector_num = ide_get_sector(s);
+    n = s->nsector;
+    if (n == 0) {
+        /* no more sector to read from disk */
+        ide_transfer_stop(s);
+    } else {
+#if defined(DEBUG_IDE)
+        printf("read sector=%Ld\n", sector_num);
+#endif
+        if (n > s->req_nb_sectors)
+            n = s->req_nb_sectors;
+        ret = bdrv_read(s->bs, sector_num, s->io_buffer, n);
+        ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_read);
+        ide_set_irq(s);
+        ide_set_sector(s, sector_num + n);
+        s->nsector -= n;
+    }
+}
+
+static int ide_read_dma_cb(IDEState *s, 
+                           target_phys_addr_t phys_addr, 
+                           int transfer_size1)
+{
+    int len, transfer_size, n;
+    int64_t sector_num;
+
+    transfer_size = transfer_size1;
+    while (transfer_size > 0) {
+        len = s->io_buffer_size - s->io_buffer_index;
+        if (len <= 0) {
+            /* transfert next data */
+            n = s->nsector;
+            if (n == 0)
+                break;
+            if (n > MAX_MULT_SECTORS)
+                n = MAX_MULT_SECTORS;
+            sector_num = ide_get_sector(s);
+            bdrv_read(s->bs, sector_num, s->io_buffer, n);
+            s->io_buffer_index = 0;
+            s->io_buffer_size = n * 512;
+            len = s->io_buffer_size;
+            sector_num += n;
+            ide_set_sector(s, sector_num);
+            s->nsector -= n;
+        }
+        if (len > transfer_size)
+            len = transfer_size;
+        cpu_physical_memory_write(phys_addr, 
+                                  s->io_buffer + s->io_buffer_index, len);
+        s->io_buffer_index += len;
+        transfer_size -= len;
+        phys_addr += len;
+    }
+    if (s->io_buffer_index >= s->io_buffer_size && s->nsector == 0) {
+        s->status = READY_STAT | SEEK_STAT;
+        ide_set_irq(s);
+#ifdef DEBUG_IDE_ATAPI
+        printf("dma status=0x%x\n", s->status);
+#endif
+        return 0;
+    }
+    return transfer_size1 - transfer_size;
+}
+
+static void ide_sector_read_dma(IDEState *s)
+{
+    s->status = READY_STAT | SEEK_STAT | DRQ_STAT;
+    s->io_buffer_index = 0;
+    s->io_buffer_size = 0;
+    ide_dma_start(s, ide_read_dma_cb);
+}
+
+static void ide_sector_write(IDEState *s)
+{
+    int64_t sector_num;
+    int ret, n, n1;
+
+    s->status = READY_STAT | SEEK_STAT;
+    sector_num = ide_get_sector(s);
+#if defined(DEBUG_IDE)
+    printf("write sector=%Ld\n", sector_num);
+#endif
+    n = s->nsector;
+    if (n > s->req_nb_sectors)
+        n = s->req_nb_sectors;
+    ret = bdrv_write(s->bs, sector_num, s->io_buffer, n);
+    s->nsector -= n;
+    if (s->nsector == 0) {
+        /* no more sector to write */
+        ide_transfer_stop(s);
+    } else {
+        n1 = s->nsector;
+        if (n1 > s->req_nb_sectors)
+            n1 = s->req_nb_sectors;
+        ide_transfer_start(s, s->io_buffer, 512 * n1, ide_sector_write);
+    }
+    ide_set_sector(s, sector_num + n);
+    ide_set_irq(s);
+}
+
+static int ide_write_dma_cb(IDEState *s, 
+                            target_phys_addr_t phys_addr, 
+                            int transfer_size1)
+{
+    int len, transfer_size, n;
+    int64_t sector_num;
+
+    transfer_size = transfer_size1;
+    for(;;) {
+        len = s->io_buffer_size - s->io_buffer_index;
+        if (len == 0) {
+            n = s->io_buffer_size >> 9;
+            sector_num = ide_get_sector(s);
+            bdrv_write(s->bs, sector_num, s->io_buffer, 
+                       s->io_buffer_size >> 9);
+            sector_num += n;
+            ide_set_sector(s, sector_num);
+            s->nsector -= n;
+            n = s->nsector;
+            if (n == 0) {
+                /* end of transfer */
+                s->status = READY_STAT | SEEK_STAT;
+                ide_set_irq(s);
+                return 0;
+            }
+            if (n > MAX_MULT_SECTORS)
+                n = MAX_MULT_SECTORS;
+            s->io_buffer_index = 0;
+            s->io_buffer_size = n * 512;
+            len = s->io_buffer_size;
+        }
+        if (transfer_size <= 0)
+            break;
+        if (len > transfer_size)
+            len = transfer_size;
+        cpu_physical_memory_read(phys_addr, 
+                                 s->io_buffer + s->io_buffer_index, len);
+        s->io_buffer_index += len;
+        transfer_size -= len;
+        phys_addr += len;
+    }
+    return transfer_size1 - transfer_size;
+}
+
+static void ide_sector_write_dma(IDEState *s)
+{
+    int n;
+    s->status = READY_STAT | SEEK_STAT | DRQ_STAT;
+    n = s->nsector;
+    if (n > MAX_MULT_SECTORS)
+        n = MAX_MULT_SECTORS;
+    s->io_buffer_index = 0;
+    s->io_buffer_size = n * 512;
+    ide_dma_start(s, ide_write_dma_cb);
+}
+
+static void ide_atapi_cmd_ok(IDEState *s)
+{
+    s->error = 0;
+    s->status = READY_STAT;
+    s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
+    ide_set_irq(s);
+}
+
+static void ide_atapi_cmd_error(IDEState *s, int sense_key, int asc)
+{
+#ifdef DEBUG_IDE_ATAPI
+    printf("atapi_cmd_error: sense=0x%x asc=0x%x\n", sense_key, asc);
+#endif
+    s->error = sense_key << 4;
+    s->status = READY_STAT | ERR_STAT;
+    s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
+    s->sense_key = sense_key;
+    s->asc = asc;
+    ide_set_irq(s);
+}
+
+static inline void cpu_to_ube16(uint8_t *buf, int val)
+{
+    buf[0] = val >> 8;
+    buf[1] = val;
+}
+
+static inline void cpu_to_ube32(uint8_t *buf, unsigned int val)
+{
+    buf[0] = val >> 24;
+    buf[1] = val >> 16;
+    buf[2] = val >> 8;
+    buf[3] = val;
+}
+
+static inline int ube16_to_cpu(const uint8_t *buf)
+{
+    return (buf[0] << 8) | buf[1];
+}
+
+static inline int ube32_to_cpu(const uint8_t *buf)
+{
+    return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
+}
+
+static void lba_to_msf(uint8_t *buf, int lba)
+{
+    lba += 150;
+    buf[0] = (lba / 75) / 60;
+    buf[1] = (lba / 75) % 60;
+    buf[2] = lba % 75;
+}
+
+static void cd_read_sector(BlockDriverState *bs, int lba, uint8_t *buf, 
+                           int sector_size)
+{
+    switch(sector_size) {
+    case 2048:
+        bdrv_read(bs, (int64_t)lba << 2, buf, 4);
+        break;
+    case 2352:
+        /* sync bytes */
+        buf[0] = 0x00;
+        memset(buf + 1, 0xff, 11);
+        buf += 12;
+        /* MSF */
+        lba_to_msf(buf, lba);
+        buf[3] = 0x01; /* mode 1 data */
+        buf += 4;
+        /* data */
+        bdrv_read(bs, (int64_t)lba << 2, buf, 4);
+        buf += 2048;
+        /* ECC */
+        memset(buf, 0, 288);
+        break;
+    default:
+        break;
+    }
+}
+
+/* The whole ATAPI transfer logic is handled in this function */
+static void ide_atapi_cmd_reply_end(IDEState *s)
+{
+    int byte_count_limit, size;
+#ifdef DEBUG_IDE_ATAPI
+    printf("reply: tx_size=%d elem_tx_size=%d index=%d\n", 
+           s->packet_transfer_size,
+           s->elementary_transfer_size,
+           s->io_buffer_index);
+#endif
+    if (s->packet_transfer_size <= 0) {
+        /* end of transfer */
+        ide_transfer_stop(s);
+        s->status = READY_STAT;
+        s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
+        ide_set_irq(s);
+#ifdef DEBUG_IDE_ATAPI
+        printf("status=0x%x\n", s->status);
+#endif
+    } else {
+        /* see if a new sector must be read */
+        if (s->lba != -1 && s->io_buffer_index >= s->cd_sector_size) {
+            cd_read_sector(s->bs, s->lba, s->io_buffer, s->cd_sector_size);
+            s->lba++;
+            s->io_buffer_index = 0;
+        }
+        if (s->elementary_transfer_size > 0) {
+            /* there are some data left to transmit in this elementary
+               transfer */
+            size = s->cd_sector_size - s->io_buffer_index;
+            if (size > s->elementary_transfer_size)
+                size = s->elementary_transfer_size;
+            ide_transfer_start(s, s->io_buffer + s->io_buffer_index, 
+                               size, ide_atapi_cmd_reply_end);
+            s->packet_transfer_size -= size;
+            s->elementary_transfer_size -= size;
+            s->io_buffer_index += size;
+        } else {
+            /* a new transfer is needed */
+            s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO;
+            byte_count_limit = s->lcyl | (s->hcyl << 8);
+#ifdef DEBUG_IDE_ATAPI
+            printf("byte_count_limit=%d\n", byte_count_limit);
+#endif
+            if (byte_count_limit == 0xffff)
+                byte_count_limit--;
+            size = s->packet_transfer_size;
+            if (size > byte_count_limit) {
+                /* byte count limit must be even if this case */
+                if (byte_count_limit & 1)
+                    byte_count_limit--;
+                size = byte_count_limit;
+            }
+            s->lcyl = size;
+            s->hcyl = size >> 8;
+            s->elementary_transfer_size = size;
+            /* we cannot transmit more than one sector at a time */
+            if (s->lba != -1) {
+                if (size > (s->cd_sector_size - s->io_buffer_index))
+                    size = (s->cd_sector_size - s->io_buffer_index);
+            }
+            ide_transfer_start(s, s->io_buffer + s->io_buffer_index, 
+                               size, ide_atapi_cmd_reply_end);
+            s->packet_transfer_size -= size;
+            s->elementary_transfer_size -= size;
+            s->io_buffer_index += size;
+            ide_set_irq(s);
+#ifdef DEBUG_IDE_ATAPI
+            printf("status=0x%x\n", s->status);
+#endif
+        }
+    }
+}
+
+/* send a reply of 'size' bytes in s->io_buffer to an ATAPI command */
+static void ide_atapi_cmd_reply(IDEState *s, int size, int max_size)
+{
+    if (size > max_size)
+        size = max_size;
+    s->lba = -1; /* no sector read */
+    s->packet_transfer_size = size;
+    s->elementary_transfer_size = 0;
+    s->io_buffer_index = 0;
+
+    s->status = READY_STAT;
+    ide_atapi_cmd_reply_end(s);
+}
+
+/* start a CD-CDROM read command */
+static void ide_atapi_cmd_read_pio(IDEState *s, int lba, int nb_sectors,
+                                   int sector_size)
+{
+    s->lba = lba;
+    s->packet_transfer_size = nb_sectors * sector_size;
+    s->elementary_transfer_size = 0;
+    s->io_buffer_index = sector_size;
+    s->cd_sector_size = sector_size;
+
+    s->status = READY_STAT;
+    ide_atapi_cmd_reply_end(s);
+}
+
+/* ATAPI DMA support */
+static int ide_atapi_cmd_read_dma_cb(IDEState *s, 
+                                     target_phys_addr_t phys_addr, 
+                                     int transfer_size1)
+{
+    int len, transfer_size;
+    
+    transfer_size = transfer_size1;
+    while (transfer_size > 0) {
+        if (s->packet_transfer_size <= 0)
+            break;
+        len = s->cd_sector_size - s->io_buffer_index;
+        if (len <= 0) {
+            /* transfert next data */
+            cd_read_sector(s->bs, s->lba, s->io_buffer, s->cd_sector_size);
+            s->lba++;
+            s->io_buffer_index = 0;
+            len = s->cd_sector_size;
+        }
+        if (len > transfer_size)
+            len = transfer_size;
+        cpu_physical_memory_write(phys_addr, 
+                                  s->io_buffer + s->io_buffer_index, len);
+        s->packet_transfer_size -= len;
+        s->io_buffer_index += len;
+        transfer_size -= len;
+        phys_addr += len;
+    }
+    if (s->packet_transfer_size <= 0) {
+        s->status = READY_STAT;
+        s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
+        ide_set_irq(s);
+#ifdef DEBUG_IDE_ATAPI
+        printf("dma status=0x%x\n", s->status);
+#endif
+        return 0;
+    }
+    return transfer_size1 - transfer_size;
+}
+
+/* start a CD-CDROM read command with DMA */
+/* XXX: test if DMA is available */
+static void ide_atapi_cmd_read_dma(IDEState *s, int lba, int nb_sectors,
+                                   int sector_size)
+{
+    s->lba = lba;
+    s->packet_transfer_size = nb_sectors * sector_size;
+    s->io_buffer_index = sector_size;
+    s->cd_sector_size = sector_size;
+
+    s->status = READY_STAT | DRQ_STAT;
+    ide_dma_start(s, ide_atapi_cmd_read_dma_cb);
+}
+
+static void ide_atapi_cmd_read(IDEState *s, int lba, int nb_sectors, 
+                               int sector_size)
+{
+#ifdef DEBUG_IDE_ATAPI
+    printf("read: LBA=%d nb_sectors=%d\n", lba, nb_sectors);
+#endif
+    if (s->atapi_dma) {
+        ide_atapi_cmd_read_dma(s, lba, nb_sectors, sector_size);
+    } else {
+        ide_atapi_cmd_read_pio(s, lba, nb_sectors, sector_size);
+    }
+}
+
+/* same toc as bochs. Return -1 if error or the toc length */
+/* XXX: check this */
+static int cdrom_read_toc(IDEState *s, uint8_t *buf, int msf, int start_track)
+{
+    uint8_t *q;
+    int nb_sectors, len;
+    
+    if (start_track > 1 && start_track != 0xaa)
+        return -1;
+    q = buf + 2;
+    *q++ = 1; /* first session */
+    *q++ = 1; /* last session */
+    if (start_track <= 1) {
+        *q++ = 0; /* reserved */
+        *q++ = 0x14; /* ADR, control */
+        *q++ = 1;    /* track number */
+        *q++ = 0; /* reserved */
+        if (msf) {
+            *q++ = 0; /* reserved */
+            *q++ = 0; /* minute */
+            *q++ = 2; /* second */
+            *q++ = 0; /* frame */
+        } else {
+            /* sector 0 */
+            cpu_to_ube32(q, 0);
+            q += 4;
+        }
+    }
+    /* lead out track */
+    *q++ = 0; /* reserved */
+    *q++ = 0x16; /* ADR, control */
+    *q++ = 0xaa; /* track number */
+    *q++ = 0; /* reserved */
+    nb_sectors = s->nb_sectors >> 2;
+    if (msf) {
+        *q++ = 0; /* reserved */
+        lba_to_msf(q, nb_sectors);
+        q += 3;
+    } else {
+        cpu_to_ube32(q, nb_sectors);
+        q += 4;
+    }
+    len = q - buf;
+    cpu_to_ube16(buf, len - 2);
+    return len;
+}
+
+/* mostly same info as PearPc */
+static int cdrom_read_toc_raw(IDEState *s, uint8_t *buf, int msf, 
+                              int session_num)
+{
+    uint8_t *q;
+    int nb_sectors, len;
+    
+    q = buf + 2;
+    *q++ = 1; /* first session */
+    *q++ = 1; /* last session */
+
+    *q++ = 1; /* session number */
+    *q++ = 0x14; /* data track */
+    *q++ = 0; /* track number */
+    *q++ = 0xa0; /* lead-in */
+    *q++ = 0; /* min */
+    *q++ = 0; /* sec */
+    *q++ = 0; /* frame */
+    *q++ = 0;
+    *q++ = 1; /* first track */
+    *q++ = 0x00; /* disk type */
+    *q++ = 0x00;
+    
+    *q++ = 1; /* session number */
+    *q++ = 0x14; /* data track */
+    *q++ = 0; /* track number */
+    *q++ = 0xa1;
+    *q++ = 0; /* min */
+    *q++ = 0; /* sec */
+    *q++ = 0; /* frame */
+    *q++ = 0;
+    *q++ = 1; /* last track */
+    *q++ = 0x00;
+    *q++ = 0x00;
+    
+    *q++ = 1; /* session number */
+    *q++ = 0x14; /* data track */
+    *q++ = 0; /* track number */
+    *q++ = 0xa2; /* lead-out */
+    *q++ = 0; /* min */
+    *q++ = 0; /* sec */
+    *q++ = 0; /* frame */
+    nb_sectors = s->nb_sectors >> 2;
+    if (msf) {
+        *q++ = 0; /* reserved */
+        lba_to_msf(q, nb_sectors);
+        q += 3;
+    } else {
+        cpu_to_ube32(q, nb_sectors);
+        q += 4;
+    }
+
+    *q++ = 1; /* session number */
+    *q++ = 0x14; /* ADR, control */
+    *q++ = 0;    /* track number */
+    *q++ = 1;    /* point */
+    *q++ = 0; /* min */
+    *q++ = 0; /* sec */
+    *q++ = 0; /* frame */
+    *q++ = 0; 
+    *q++ = 0; 
+    *q++ = 0; 
+    *q++ = 0; 
+
+    len = q - buf;
+    cpu_to_ube16(buf, len - 2);
+    return len;
+}
+
+static void ide_atapi_cmd(IDEState *s)
+{
+    const uint8_t *packet;
+    uint8_t *buf;
+    int max_len;
+
+    packet = s->io_buffer;
+    buf = s->io_buffer;
+#ifdef DEBUG_IDE_ATAPI
+    {
+        int i;
+        printf("ATAPI limit=0x%x packet:", s->lcyl | (s->hcyl << 8));
+        for(i = 0; i < ATAPI_PACKET_SIZE; i++) {
+            printf(" %02x", packet[i]);
+        }
+        printf("\n");
+    }
+#endif
+    switch(s->io_buffer[0]) {
+    case GPCMD_TEST_UNIT_READY:
+        if (bdrv_is_inserted(s->bs)) {
+            ide_atapi_cmd_ok(s);
+        } else {
+            ide_atapi_cmd_error(s, SENSE_NOT_READY, 
+                                ASC_MEDIUM_NOT_PRESENT);
+        }
+        break;
+    case GPCMD_MODE_SENSE_10:
+        {
+            int action, code;
+            max_len = ube16_to_cpu(packet + 7);
+            action = packet[2] >> 6;
+            code = packet[2] & 0x3f;
+            switch(action) {
+            case 0: /* current values */
+                switch(code) {
+                case 0x01: /* error recovery */
+                    cpu_to_ube16(&buf[0], 16 + 6);
+                    buf[2] = 0x70;
+                    buf[3] = 0;
+                    buf[4] = 0;
+                    buf[5] = 0;
+                    buf[6] = 0;
+                    buf[7] = 0;
+
+                    buf[8] = 0x01;
+                    buf[9] = 0x06;
+                    buf[10] = 0x00;
+                    buf[11] = 0x05;
+                    buf[12] = 0x00;
+                    buf[13] = 0x00;
+                    buf[14] = 0x00;
+                    buf[15] = 0x00;
+                    ide_atapi_cmd_reply(s, 16, max_len);
+                    break;
+                case 0x2a:
+                    cpu_to_ube16(&buf[0], 28 + 6);
+                    buf[2] = 0x70;
+                    buf[3] = 0;
+                    buf[4] = 0;
+                    buf[5] = 0;
+                    buf[6] = 0;
+                    buf[7] = 0;
+
+                    buf[8] = 0x2a;
+                    buf[9] = 0x12;
+                    buf[10] = 0x00;
+                    buf[11] = 0x00;
+                    
+                    buf[12] = 0x70;
+                    buf[13] = 3 << 5;
+                    buf[14] = (1 << 0) | (1 << 3) | (1 << 5);
+                    if (bdrv_is_locked(s->bs))
+                        buf[6] |= 1 << 1;
+                    buf[15] = 0x00;
+                    cpu_to_ube16(&buf[16], 706);
+                    buf[18] = 0;
+                    buf[19] = 2;
+                    cpu_to_ube16(&buf[20], 512);
+                    cpu_to_ube16(&buf[22], 706);
+                    buf[24] = 0;
+                    buf[25] = 0;
+                    buf[26] = 0;
+                    buf[27] = 0;
+                    ide_atapi_cmd_reply(s, 28, max_len);
+                    break;
+                default:
+                    goto error_cmd;
+                }
+                break;
+            case 1: /* changeable values */
+                goto error_cmd;
+            case 2: /* default values */
+                goto error_cmd;
+            default:
+            case 3: /* saved values */
+                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
+                                    ASC_SAVING_PARAMETERS_NOT_SUPPORTED);
+                break;
+            }
+        }
+        break;
+    case GPCMD_REQUEST_SENSE:
+        max_len = packet[4];
+        memset(buf, 0, 18);
+        buf[0] = 0x70 | (1 << 7);
+        buf[2] = s->sense_key;
+        buf[7] = 10;
+        buf[12] = s->asc;
+        ide_atapi_cmd_reply(s, 18, max_len);
+        break;
+    case GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
+        if (bdrv_is_inserted(s->bs)) {
+            bdrv_set_locked(s->bs, packet[4] & 1);
+            ide_atapi_cmd_ok(s);
+        } else {
+            ide_atapi_cmd_error(s, SENSE_NOT_READY, 
+                                ASC_MEDIUM_NOT_PRESENT);
+        }
+        break;
+    case GPCMD_READ_10:
+    case GPCMD_READ_12:
+        {
+            int nb_sectors, lba;
+
+            if (!bdrv_is_inserted(s->bs)) {
+                ide_atapi_cmd_error(s, SENSE_NOT_READY, 
+                                    ASC_MEDIUM_NOT_PRESENT);
+                break;
+            }
+            if (packet[0] == GPCMD_READ_10)
+                nb_sectors = ube16_to_cpu(packet + 7);
+            else
+                nb_sectors = ube32_to_cpu(packet + 6);
+            lba = ube32_to_cpu(packet + 2);
+            if (nb_sectors == 0) {
+                ide_atapi_cmd_ok(s);
+                break;
+            }
+            if (((int64_t)(lba + nb_sectors) << 2) > s->nb_sectors) {
+                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
+                                    ASC_LOGICAL_BLOCK_OOR);
+                break;
+            }
+            ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
+        }
+        break;
+    case GPCMD_READ_CD:
+        {
+            int nb_sectors, lba, transfer_request;
+
+            if (!bdrv_is_inserted(s->bs)) {
+                ide_atapi_cmd_error(s, SENSE_NOT_READY, 
+                                    ASC_MEDIUM_NOT_PRESENT);
+                break;
+            }
+            nb_sectors = (packet[6] << 16) | (packet[7] << 8) | packet[8];
+            lba = ube32_to_cpu(packet + 2);
+            if (nb_sectors == 0) {
+                ide_atapi_cmd_ok(s);
+                break;
+            }
+            if (((int64_t)(lba + nb_sectors) << 2) > s->nb_sectors) {
+                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
+                                    ASC_LOGICAL_BLOCK_OOR);
+                break;
+            }
+            transfer_request = packet[9];
+            switch(transfer_request & 0xf8) {
+            case 0x00:
+                /* nothing */
+                ide_atapi_cmd_ok(s);
+                break;
+            case 0x10:
+                /* normal read */
+                ide_atapi_cmd_read(s, lba, nb_sectors, 2048);
+                break;
+            case 0xf8:
+                /* read all data */
+                ide_atapi_cmd_read(s, lba, nb_sectors, 2352);
+                break;
+            default:
+                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
+                                    ASC_INV_FIELD_IN_CMD_PACKET);
+                break;
+            }
+        }
+        break;
+    case GPCMD_SEEK:
+        {
+            int lba;
+            if (!bdrv_is_inserted(s->bs)) {
+                ide_atapi_cmd_error(s, SENSE_NOT_READY, 
+                                    ASC_MEDIUM_NOT_PRESENT);
+                break;
+            }
+            lba = ube32_to_cpu(packet + 2);
+            if (((int64_t)lba << 2) > s->nb_sectors) {
+                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
+                                    ASC_LOGICAL_BLOCK_OOR);
+                break;
+            }
+            ide_atapi_cmd_ok(s);
+        }
+        break;
+    case GPCMD_START_STOP_UNIT:
+        {
+            int start, eject;
+            start = packet[4] & 1;
+            eject = (packet[4] >> 1) & 1;
+            
+            if (eject && !start) {
+                /* eject the disk */
+                bdrv_close(s->bs);
+            }
+            ide_atapi_cmd_ok(s);
+        }
+        break;
+    case GPCMD_MECHANISM_STATUS:
+        {
+            max_len = ube16_to_cpu(packet + 8);
+            cpu_to_ube16(buf, 0);
+            /* no current LBA */
+            buf[2] = 0;
+            buf[3] = 0;
+            buf[4] = 0;
+            buf[5] = 1;
+            cpu_to_ube16(buf + 6, 0);
+            ide_atapi_cmd_reply(s, 8, max_len);
+        }
+        break;
+    case GPCMD_READ_TOC_PMA_ATIP:
+        {
+            int format, msf, start_track, len;
+
+            if (!bdrv_is_inserted(s->bs)) {
+                ide_atapi_cmd_error(s, SENSE_NOT_READY, 
+                                    ASC_MEDIUM_NOT_PRESENT);
+                break;
+            }
+            max_len = ube16_to_cpu(packet + 7);
+            format = packet[9] >> 6;
+            msf = (packet[1] >> 1) & 1;
+            start_track = packet[6];
+            switch(format) {
+            case 0:
+                len = cdrom_read_toc(s, buf, msf, start_track);
+                if (len < 0)
+                    goto error_cmd;
+                ide_atapi_cmd_reply(s, len, max_len);
+                break;
+            case 1:
+                /* multi session : only a single session defined */
+                memset(buf, 0, 12);
+                buf[1] = 0x0a;
+                buf[2] = 0x01;
+                buf[3] = 0x01;
+                ide_atapi_cmd_reply(s, 12, max_len);
+                break;
+            case 2:
+                len = cdrom_read_toc_raw(s, buf, msf, start_track);
+                if (len < 0)
+                    goto error_cmd;
+                ide_atapi_cmd_reply(s, len, max_len);
+                break;
+            default:
+            error_cmd:
+                ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
+                                    ASC_INV_FIELD_IN_CMD_PACKET);
+                break;
+            }
+        }
+        break;
+    case GPCMD_READ_CDVD_CAPACITY:
+        if (!bdrv_is_inserted(s->bs)) {
+            ide_atapi_cmd_error(s, SENSE_NOT_READY, 
+                                ASC_MEDIUM_NOT_PRESENT);
+            break;
+        }
+        /* NOTE: it is really the number of sectors minus 1 */
+        cpu_to_ube32(buf, (s->nb_sectors >> 2) - 1);
+        cpu_to_ube32(buf + 4, 2048);
+        ide_atapi_cmd_reply(s, 8, 8);
+        break;
+    case GPCMD_INQUIRY:
+        max_len = packet[4];
+        buf[0] = 0x05; /* CD-ROM */
+        buf[1] = 0x80; /* removable */
+        buf[2] = 0x00; /* ISO */
+        buf[3] = 0x21; /* ATAPI-2 (XXX: put ATAPI-4 ?) */
+        buf[4] = 31; /* additionnal length */
+        buf[5] = 0; /* reserved */
+        buf[6] = 0; /* reserved */
+        buf[7] = 0; /* reserved */
+        padstr8(buf + 8, 8, "QEMU");
+        padstr8(buf + 16, 16, "QEMU CD-ROM");
+        padstr8(buf + 32, 4, QEMU_VERSION);
+        ide_atapi_cmd_reply(s, 36, max_len);
+        break;
+    default:
+        ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, 
+                            ASC_ILLEGAL_OPCODE);
+        break;
+    }
+}
+
+/* called when the inserted state of the media has changed */
+static void cdrom_change_cb(void *opaque)
+{
+    IDEState *s = opaque;
+    int64_t nb_sectors;
+
+    /* XXX: send interrupt too */
+    bdrv_get_geometry(s->bs, &nb_sectors);
+    s->nb_sectors = nb_sectors;
+}
+
+static void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+{
+    IDEState *ide_if = opaque;
+    IDEState *s;
+    int unit, n;
+
+#ifdef DEBUG_IDE
+    printf("IDE: write addr=0x%x val=0x%02x\n", addr, val);
+#endif
+    addr &= 7;
+    switch(addr) {
+    case 0:
+        break;
+    case 1:
+        /* NOTE: data is written to the two drives */
+        ide_if[0].feature = val;
+        ide_if[1].feature = val;
+        break;
+    case 2:
+        if (val == 0)
+            val = 256;
+        ide_if[0].nsector = val;
+        ide_if[1].nsector = val;
+        break;
+    case 3:
+        ide_if[0].sector = val;
+        ide_if[1].sector = val;
+        break;
+    case 4:
+        ide_if[0].lcyl = val;
+        ide_if[1].lcyl = val;
+        break;
+    case 5:
+        ide_if[0].hcyl = val;
+        ide_if[1].hcyl = val;
+        break;
+    case 6:
+        ide_if[0].select = (val & ~0x10) | 0xa0;
+        ide_if[1].select = (val | 0x10) | 0xa0;
+        /* select drive */
+        unit = (val >> 4) & 1;
+        s = ide_if + unit;
+        ide_if->cur_drive = s;
+        break;
+    default:
+    case 7:
+        /* command */
+#if defined(DEBUG_IDE)
+        printf("ide: CMD=%02x\n", val);
+#endif
+        s = ide_if->cur_drive;
+        /* ignore commands to non existant slave */
+        if (s != ide_if && !s->bs) 
+            break;
+        switch(val) {
+        case WIN_IDENTIFY:
+            if (s->bs && !s->is_cdrom) {
+                ide_identify(s);
+                s->status = READY_STAT | SEEK_STAT;
+                ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
+            } else {
+                if (s->is_cdrom) {
+                    ide_set_signature(s);
+                }
+                ide_abort_command(s);
+            }
+            ide_set_irq(s);
+            break;
+        case WIN_SPECIFY:
+        case WIN_RECAL:
+            s->error = 0;
+            s->status = READY_STAT | SEEK_STAT;
+            ide_set_irq(s);
+            break;
+        case WIN_SETMULT:
+            if (s->nsector > MAX_MULT_SECTORS || 
+                s->nsector == 0 ||
+                (s->nsector & (s->nsector - 1)) != 0) {
+                ide_abort_command(s);
+            } else {
+                s->mult_sectors = s->nsector;
+                s->status = READY_STAT;
+            }
+            ide_set_irq(s);
+            break;
+        case WIN_VERIFY:
+        case WIN_VERIFY_ONCE:
+            /* do sector number check ? */
+            s->status = READY_STAT;
+            ide_set_irq(s);
+            break;
+        case WIN_READ:
+        case WIN_READ_ONCE:
+            if (!s->bs) 
+                goto abort_cmd;
+            s->req_nb_sectors = 1;
+            ide_sector_read(s);
+            break;
+        case WIN_WRITE:
+        case WIN_WRITE_ONCE:
+            s->error = 0;
+            s->status = SEEK_STAT | READY_STAT;
+            s->req_nb_sectors = 1;
+            ide_transfer_start(s, s->io_buffer, 512, ide_sector_write);
+            break;
+        case WIN_MULTREAD:
+            if (!s->mult_sectors)
+                goto abort_cmd;
+            s->req_nb_sectors = s->mult_sectors;
+            ide_sector_read(s);
+            break;
+        case WIN_MULTWRITE:
+            if (!s->mult_sectors)
+                goto abort_cmd;
+            s->error = 0;
+            s->status = SEEK_STAT | READY_STAT;
+            s->req_nb_sectors = s->mult_sectors;
+            n = s->nsector;
+            if (n > s->req_nb_sectors)
+                n = s->req_nb_sectors;
+            ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_write);
+            break;
+        case WIN_READDMA:
+        case WIN_READDMA_ONCE:
+            if (!s->bs) 
+                goto abort_cmd;
+            ide_sector_read_dma(s);
+            break;
+        case WIN_WRITEDMA:
+        case WIN_WRITEDMA_ONCE:
+            if (!s->bs) 
+                goto abort_cmd;
+            ide_sector_write_dma(s);
+            break;
+        case WIN_READ_NATIVE_MAX:
+            ide_set_sector(s, s->nb_sectors - 1);
+            s->status = READY_STAT;
+            ide_set_irq(s);
+            break;
+        case WIN_CHECKPOWERMODE1:
+            s->nsector = 0xff; /* device active or idle */
+            s->status = READY_STAT;
+            ide_set_irq(s);
+            break;
+        case WIN_SETFEATURES:
+            if (!s->bs)
+                goto abort_cmd;
+            /* XXX: valid for CDROM ? */
+            switch(s->feature) {
+            case 0x02: /* write cache enable */
+            case 0x03: /* set transfer mode */
+            case 0x82: /* write cache disable */
+            case 0xaa: /* read look-ahead enable */
+            case 0x55: /* read look-ahead disable */
+                s->status = READY_STAT | SEEK_STAT;
+                ide_set_irq(s);
+                break;
+            default:
+                goto abort_cmd;
+            }
+            break;
+       case WIN_STANDBYNOW1:
+           s->status = READY_STAT;
+            ide_set_irq(s);
+            break;
+            /* ATAPI commands */
+        case WIN_PIDENTIFY:
+            if (s->is_cdrom) {
+                ide_atapi_identify(s);
+                s->status = READY_STAT;
+                ide_transfer_start(s, s->io_buffer, 512, ide_transfer_stop);
+            } else {
+                ide_abort_command(s);
+            }
+            ide_set_irq(s);
+            break;
+        case WIN_SRST:
+            if (!s->is_cdrom)
+                goto abort_cmd;
+            ide_set_signature(s);
+            s->status = 0x00; /* NOTE: READY is _not_ set */
+            s->error = 0x01;
+            break;
+        case WIN_PACKETCMD:
+            if (!s->is_cdrom)
+                goto abort_cmd;
+            /* overlapping commands not supported */
+            if (s->feature & 0x02)
+                goto abort_cmd;
+            s->atapi_dma = s->feature & 1;
+            s->nsector = 1;
+            ide_transfer_start(s, s->io_buffer, ATAPI_PACKET_SIZE, 
+                               ide_atapi_cmd);
+            break;
+        default:
+        abort_cmd:
+            ide_abort_command(s);
+            ide_set_irq(s);
+            break;
+        }
+    }
+}
+
+static uint32_t ide_ioport_read(void *opaque, uint32_t addr1)
+{
+    IDEState *ide_if = opaque;
+    IDEState *s = ide_if->cur_drive;
+    uint32_t addr;
+    int ret;
+
+    addr = addr1 & 7;
+    switch(addr) {
+    case 0:
+        ret = 0xff;
+        break;
+    case 1:
+        if (!ide_if[0].bs && !ide_if[1].bs)
+            ret = 0;
+        else
+            ret = s->error;
+        break;
+    case 2:
+        if (!ide_if[0].bs && !ide_if[1].bs)
+            ret = 0;
+        else
+            ret = s->nsector & 0xff;
+        break;
+    case 3:
+        if (!ide_if[0].bs && !ide_if[1].bs)
+            ret = 0;
+        else
+            ret = s->sector;
+        break;
+    case 4:
+        if (!ide_if[0].bs && !ide_if[1].bs)
+            ret = 0;
+        else
+            ret = s->lcyl;
+        break;
+    case 5:
+        if (!ide_if[0].bs && !ide_if[1].bs)
+            ret = 0;
+        else
+            ret = s->hcyl;
+        break;
+    case 6:
+        if (!ide_if[0].bs && !ide_if[1].bs)
+            ret = 0;
+        else
+            ret = s->select;
+        break;
+    default:
+    case 7:
+        if ((!ide_if[0].bs && !ide_if[1].bs) ||
+            (s != ide_if && !s->bs))
+            ret = 0;
+        else
+            ret = s->status;
+#ifdef TARGET_PPC
+        if (s->openpic) 
+            openpic_set_irq(s->openpic, s->irq, 0);
+        else 
+#endif
+        if (s->irq == 16)
+            pci_set_irq(s->pci_dev, 0, 0);
+        else
+            pic_set_irq(s->irq, 0);
+        break;
+    }
+#ifdef DEBUG_IDE
+    printf("ide: read addr=0x%x val=%02x\n", addr1, ret);
+#endif
+    return ret;
+}
+
+static uint32_t ide_status_read(void *opaque, uint32_t addr)
+{
+    IDEState *ide_if = opaque;
+    IDEState *s = ide_if->cur_drive;
+    int ret;
+
+    if ((!ide_if[0].bs && !ide_if[1].bs) ||
+        (s != ide_if && !s->bs))
+        ret = 0;
+    else
+        ret = s->status;
+#ifdef DEBUG_IDE
+    printf("ide: read status addr=0x%x val=%02x\n", addr, ret);
+#endif
+    return ret;
+}
+
+static void ide_cmd_write(void *opaque, uint32_t addr, uint32_t val)
+{
+    IDEState *ide_if = opaque;
+    IDEState *s;
+    int i;
+
+#ifdef DEBUG_IDE
+    printf("ide: write control addr=0x%x val=%02x\n", addr, val);
+#endif
+    /* common for both drives */
+    if (!(ide_if[0].cmd & IDE_CMD_RESET) &&
+        (val & IDE_CMD_RESET)) {
+        /* reset low to high */
+        for(i = 0;i < 2; i++) {
+            s = &ide_if[i];
+            s->status = BUSY_STAT | SEEK_STAT;
+            s->error = 0x01;
+        }
+    } else if ((ide_if[0].cmd & IDE_CMD_RESET) &&
+               !(val & IDE_CMD_RESET)) {
+        /* high to low */
+        for(i = 0;i < 2; i++) {
+            s = &ide_if[i];
+            if (s->is_cdrom)
+                s->status = 0x00; /* NOTE: READY is _not_ set */
+            else
+                s->status = READY_STAT | SEEK_STAT;
+            ide_set_signature(s);
+        }
+    }
+
+    ide_if[0].cmd = val;
+    ide_if[1].cmd = val;
+}
+
+static void ide_data_writew(void *opaque, uint32_t addr, uint32_t val)
+{
+    IDEState *s = ((IDEState *)opaque)->cur_drive;
+    uint8_t *p;
+
+    p = s->data_ptr;
+    *(uint16_t *)p = le16_to_cpu(val);
+    p += 2;
+    s->data_ptr = p;
+    if (p >= s->data_end)
+        s->end_transfer_func(s);
+}
+
+static uint32_t ide_data_readw(void *opaque, uint32_t addr)
+{
+    IDEState *s = ((IDEState *)opaque)->cur_drive;
+    uint8_t *p;
+    int ret;
+    p = s->data_ptr;
+    ret = cpu_to_le16(*(uint16_t *)p);
+    p += 2;
+    s->data_ptr = p;
+    if (p >= s->data_end)
+        s->end_transfer_func(s);
+    return ret;
+}
+
+static void ide_data_writel(void *opaque, uint32_t addr, uint32_t val)
+{
+    IDEState *s = ((IDEState *)opaque)->cur_drive;
+    uint8_t *p;
+
+    p = s->data_ptr;
+    *(uint32_t *)p = le32_to_cpu(val);
+    p += 4;
+    s->data_ptr = p;
+    if (p >= s->data_end)
+        s->end_transfer_func(s);
+}
+
+static uint32_t ide_data_readl(void *opaque, uint32_t addr)
+{
+    IDEState *s = ((IDEState *)opaque)->cur_drive;
+    uint8_t *p;
+    int ret;
+    
+    p = s->data_ptr;
+    ret = cpu_to_le32(*(uint32_t *)p);
+    p += 4;
+    s->data_ptr = p;
+    if (p >= s->data_end)
+        s->end_transfer_func(s);
+    return ret;
+}
+
+static void ide_dummy_transfer_stop(IDEState *s)
+{
+    s->data_ptr = s->io_buffer;
+    s->data_end = s->io_buffer;
+    s->io_buffer[0] = 0xff;
+    s->io_buffer[1] = 0xff;
+    s->io_buffer[2] = 0xff;
+    s->io_buffer[3] = 0xff;
+}
+
+static void ide_reset(IDEState *s)
+{
+    s->mult_sectors = MAX_MULT_SECTORS;
+    s->cur_drive = s;
+    s->select = 0xa0;
+    s->status = READY_STAT;
+    ide_set_signature(s);
+    /* init the transfer handler so that 0xffff is returned on data
+       accesses */
+    s->end_transfer_func = ide_dummy_transfer_stop;
+    ide_dummy_transfer_stop(s);
+}
+
+struct partition {
+       uint8_t boot_ind;               /* 0x80 - active */
+       uint8_t head;           /* starting head */
+       uint8_t sector;         /* starting sector */
+       uint8_t cyl;            /* starting cylinder */
+       uint8_t sys_ind;                /* What partition type */
+       uint8_t end_head;               /* end head */
+       uint8_t end_sector;     /* end sector */
+       uint8_t end_cyl;                /* end cylinder */
+       uint32_t start_sect;    /* starting sector counting from 0 */
+       uint32_t nr_sects;              /* nr of sectors in partition */
+} __attribute__((packed));
+
+/* try to guess the IDE geometry from the MSDOS partition table */
+static void ide_guess_geometry(IDEState *s)
+{
+    uint8_t buf[512];
+    int ret, i;
+    struct partition *p;
+    uint32_t nr_sects;
+
+    if (s->cylinders != 0)
+        return;
+    ret = bdrv_read(s->bs, 0, buf, 1);
+    if (ret < 0)
+        return;
+    /* test msdos magic */
+    if (buf[510] != 0x55 || buf[511] != 0xaa)
+        return;
+    for(i = 0; i < 4; i++) {
+        p = ((struct partition *)(buf + 0x1be)) + i;
+        nr_sects = le32_to_cpu(p->nr_sects);
+        if (nr_sects && p->end_head) {
+            /* We make the assumption that the partition terminates on
+               a cylinder boundary */
+            s->heads = p->end_head + 1;
+            s->sectors = p->end_sector & 63;
+            s->cylinders = s->nb_sectors / (s->heads * s->sectors);
+#if 0
+            printf("guessed partition: CHS=%d %d %d\n", 
+                   s->cylinders, s->heads, s->sectors);
+#endif
+        }
+    }
+}
+
+static void ide_init2(IDEState *ide_state, int irq,
+                      BlockDriverState *hd0, BlockDriverState *hd1)
+{
+    IDEState *s;
+    static int drive_serial = 1;
+    int i, cylinders, heads, secs;
+    int64_t nb_sectors;
+
+    for(i = 0; i < 2; i++) {
+        s = ide_state + i;
+        if (i == 0)
+            s->bs = hd0;
+        else
+            s->bs = hd1;
+        if (s->bs) {
+            bdrv_get_geometry(s->bs, &nb_sectors);
+            s->nb_sectors = nb_sectors;
+            /* if a geometry hint is available, use it */
+            bdrv_get_geometry_hint(s->bs, &cylinders, &heads, &secs);
+            if (cylinders != 0) {
+                s->cylinders = cylinders;
+                s->heads = heads;
+                s->sectors = secs;
+            } else {
+                ide_guess_geometry(s);
+                if (s->cylinders == 0) {
+                    /* if no geometry, use a LBA compatible one */
+                    cylinders = nb_sectors / (16 * 63);
+                    if (cylinders > 16383)
+                        cylinders = 16383;
+                    else if (cylinders < 2)
+                        cylinders = 2;
+                    s->cylinders = cylinders;
+                    s->heads = 16;
+                    s->sectors = 63;
+                }
+                bdrv_set_geometry_hint(s->bs, s->cylinders, s->heads, s->sectors);
+            }
+            if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM) {
+                s->is_cdrom = 1;
+                bdrv_set_change_cb(s->bs, cdrom_change_cb, s);
+            }
+        }
+        s->drive_serial = drive_serial++;
+        s->irq = irq;
+        ide_reset(s);
+    }
+}
+
+static void ide_init_ioport(IDEState *ide_state, int iobase, int iobase2)
+{
+    register_ioport_write(iobase, 8, 1, ide_ioport_write, ide_state);
+    register_ioport_read(iobase, 8, 1, ide_ioport_read, ide_state);
+    if (iobase2) {
+        register_ioport_read(iobase2, 1, 1, ide_status_read, ide_state);
+        register_ioport_write(iobase2, 1, 1, ide_cmd_write, ide_state);
+    }
+    
+    /* data ports */
+    register_ioport_write(iobase, 2, 2, ide_data_writew, ide_state);
+    register_ioport_read(iobase, 2, 2, ide_data_readw, ide_state);
+    register_ioport_write(iobase, 4, 4, ide_data_writel, ide_state);
+    register_ioport_read(iobase, 4, 4, ide_data_readl, ide_state);
+}
+
+/***********************************************************/
+/* ISA IDE definitions */
+
+void isa_ide_init(int iobase, int iobase2, int irq,
+                  BlockDriverState *hd0, BlockDriverState *hd1)
+{
+    IDEState *ide_state;
+
+    ide_state = qemu_mallocz(sizeof(IDEState) * 2);
+    if (!ide_state)
+        return;
+    
+    ide_init2(ide_state, irq, hd0, hd1);
+    ide_init_ioport(ide_state, iobase, iobase2);
+}
+
+/***********************************************************/
+/* PCI IDE definitions */
+
+static void ide_map(PCIDevice *pci_dev, int region_num, 
+                    uint32_t addr, uint32_t size, int type)
+{
+    PCIIDEState *d = (PCIIDEState *)pci_dev;
+    IDEState *ide_state;
+
+    if (region_num <= 3) {
+        ide_state = &d->ide_if[(region_num >> 1) * 2];
+        if (region_num & 1) {
+            register_ioport_read(addr + 2, 1, 1, ide_status_read, ide_state);
+            register_ioport_write(addr + 2, 1, 1, ide_cmd_write, ide_state);
+        } else {
+            register_ioport_write(addr, 8, 1, ide_ioport_write, ide_state);
+            register_ioport_read(addr, 8, 1, ide_ioport_read, ide_state);
+
+            /* data ports */
+            register_ioport_write(addr, 2, 2, ide_data_writew, ide_state);
+            register_ioport_read(addr, 2, 2, ide_data_readw, ide_state);
+            register_ioport_write(addr, 4, 4, ide_data_writel, ide_state);
+            register_ioport_read(addr, 4, 4, ide_data_readl, ide_state);
+        }
+    }
+}
+
+/* XXX: full callback usage to prepare non blocking I/Os support -
+   error handling */
+static void ide_dma_loop(BMDMAState *bm)
+{
+    struct {
+        uint32_t addr;
+        uint32_t size;
+    } prd;
+    target_phys_addr_t cur_addr;
+    int len, i, len1;
+
+    cur_addr = bm->addr;
+    /* at most one page to avoid hanging if erroneous parameters */
+    for(i = 0; i < 512; i++) {
+        cpu_physical_memory_read(cur_addr, (uint8_t *)&prd, 8);
+        prd.addr = le32_to_cpu(prd.addr);
+        prd.size = le32_to_cpu(prd.size);
+#ifdef DEBUG_IDE
+        printf("ide: dma: prd: %08x: addr=0x%08x size=0x%08x\n", 
+               (int)cur_addr, prd.addr, prd.size);
+#endif
+        len = prd.size & 0xfffe;
+        if (len == 0)
+            len = 0x10000;
+        while (len > 0) {
+            len1 = bm->dma_cb(bm->ide_if, prd.addr, len);
+            if (len1 == 0)
+                goto the_end;
+            prd.addr += len1;
+            len -= len1;
+        }
+        /* end of transfer */
+        if (prd.size & 0x80000000)
+            break;
+        cur_addr += 8;
+    }
+    /* end of transfer */
+ the_end:
+    bm->status &= ~BM_STATUS_DMAING;
+    bm->status |= BM_STATUS_INT;
+    bm->dma_cb = NULL;
+    bm->ide_if = NULL;
+}
+
+static void ide_dma_start(IDEState *s, IDEDMAFunc *dma_cb)
+{
+    BMDMAState *bm = s->bmdma;
+    if(!bm)
+        return;
+    bm->ide_if = s;
+    bm->dma_cb = dma_cb;
+    if (bm->status & BM_STATUS_DMAING) {
+        ide_dma_loop(bm);
+    }
+}
+
+static uint32_t bmdma_cmd_readb(void *opaque, uint32_t addr)
+{
+    BMDMAState *bm = opaque;
+    uint32_t val;
+    val = bm->cmd;
+#ifdef DEBUG_IDE
+    printf("%s: 0x%08x\n", __func__, val);
+#endif
+    return val;
+}
+
+static void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val)
+{
+    BMDMAState *bm = opaque;
+#ifdef DEBUG_IDE
+    printf("%s: 0x%08x\n", __func__, val);
+#endif
+    if (!(val & BM_CMD_START)) {
+        /* XXX: do it better */
+        bm->status &= ~BM_STATUS_DMAING;
+        bm->cmd = val & 0x09;
+    } else {
+        bm->status |= BM_STATUS_DMAING;
+        bm->cmd = val & 0x09;
+        /* start dma transfer if possible */
+        if (bm->dma_cb)
+            ide_dma_loop(bm);
+    }
+}
+
+static uint32_t bmdma_status_readb(void *opaque, uint32_t addr)
+{
+    BMDMAState *bm = opaque;
+    uint32_t val;
+    val = bm->status;
+#ifdef DEBUG_IDE
+    printf("%s: 0x%08x\n", __func__, val);
+#endif
+    return val;
+}
+
+static void bmdma_status_writeb(void *opaque, uint32_t addr, uint32_t val)
+{
+    BMDMAState *bm = opaque;
+#ifdef DEBUG_IDE
+    printf("%s: 0x%08x\n", __func__, val);
+#endif
+    bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
+}
+
+static uint32_t bmdma_addr_readl(void *opaque, uint32_t addr)
+{
+    BMDMAState *bm = opaque;
+    uint32_t val;
+    val = bm->addr;
+#ifdef DEBUG_IDE
+    printf("%s: 0x%08x\n", __func__, val);
+#endif
+    return val;
+}
+
+static void bmdma_addr_writel(void *opaque, uint32_t addr, uint32_t val)
+{
+    BMDMAState *bm = opaque;
+#ifdef DEBUG_IDE
+    printf("%s: 0x%08x\n", __func__, val);
+#endif
+    bm->addr = val & ~3;
+}
+
+static void bmdma_map(PCIDevice *pci_dev, int region_num, 
+                    uint32_t addr, uint32_t size, int type)
+{
+    PCIIDEState *d = (PCIIDEState *)pci_dev;
+    int i;
+
+    for(i = 0;i < 2; i++) {
+        BMDMAState *bm = &d->bmdma[i];
+        d->ide_if[2 * i].bmdma = bm;
+        d->ide_if[2 * i + 1].bmdma = bm;
+        
+        register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm);
+        register_ioport_read(addr, 1, 1, bmdma_cmd_readb, bm);
+
+        register_ioport_write(addr + 2, 1, 1, bmdma_status_writeb, bm);
+        register_ioport_read(addr + 2, 1, 1, bmdma_status_readb, bm);
+
+        register_ioport_write(addr + 4, 4, 4, bmdma_addr_writel, bm);
+        register_ioport_read(addr + 4, 4, 4, bmdma_addr_readl, bm);
+        addr += 8;
+    }
+}
+
+/* hd_table must contain 4 block drivers */
+void pci_ide_init(PCIBus *bus, BlockDriverState **hd_table)
+{
+    PCIIDEState *d;
+    uint8_t *pci_conf;
+    int i;
+
+    d = (PCIIDEState *)pci_register_device(bus, "IDE", sizeof(PCIIDEState),
+                                           -1, 
+                                           NULL, NULL);
+    pci_conf = d->dev.config;
+    pci_conf[0x00] = 0x86; // Intel
+    pci_conf[0x01] = 0x80;
+    pci_conf[0x02] = 0x00; // fake
+    pci_conf[0x03] = 0x01; // fake
+    pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE
+    pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage
+    pci_conf[0x0e] = 0x80; // header_type = PCI_multifunction, generic
+
+    pci_conf[0x2c] = 0x86; // subsys vendor
+    pci_conf[0x2d] = 0x80; // subsys vendor
+    pci_conf[0x2e] = 0x00; // fake
+    pci_conf[0x2f] = 0x01; // fake
+
+    pci_register_io_region((PCIDevice *)d, 0, 0x8, 
+                           PCI_ADDRESS_SPACE_IO, ide_map);
+    pci_register_io_region((PCIDevice *)d, 1, 0x4, 
+                           PCI_ADDRESS_SPACE_IO, ide_map);
+    pci_register_io_region((PCIDevice *)d, 2, 0x8, 
+                           PCI_ADDRESS_SPACE_IO, ide_map);
+    pci_register_io_region((PCIDevice *)d, 3, 0x4, 
+                           PCI_ADDRESS_SPACE_IO, ide_map);
+    pci_register_io_region((PCIDevice *)d, 4, 0x10, 
+                           PCI_ADDRESS_SPACE_IO, bmdma_map);
+
+    pci_conf[0x3d] = 0x01; // interrupt on pin 1
+
+    for(i = 0; i < 4; i++)
+        d->ide_if[i].pci_dev = (PCIDevice *)d;
+    ide_init2(&d->ide_if[0], 16, hd_table[0], hd_table[1]);
+    ide_init2(&d->ide_if[2], 16, hd_table[2], hd_table[3]);
+}
+
+/* hd_table must contain 4 block drivers */
+/* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */
+void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table)
+{
+    PCIIDEState *d;
+    uint8_t *pci_conf;
+    
+    /* register a function 1 of PIIX3 */
+    d = (PCIIDEState *)pci_register_device(bus, "PIIX3 IDE", 
+                                           sizeof(PCIIDEState),
+                                           ((PCIDevice *)piix3_state)->devfn + 1, 
+                                           NULL, NULL);
+    pci_conf = d->dev.config;
+    pci_conf[0x00] = 0x86; // Intel
+    pci_conf[0x01] = 0x80;
+    pci_conf[0x02] = 0x10;
+    pci_conf[0x03] = 0x70;
+    pci_conf[0x0a] = 0x01; // class_sub = PCI_IDE
+    pci_conf[0x0b] = 0x01; // class_base = PCI_mass_storage
+    pci_conf[0x0e] = 0x00; // header_type
+
+    pci_register_io_region((PCIDevice *)d, 4, 0x10, 
+                           PCI_ADDRESS_SPACE_IO, bmdma_map);
+
+    ide_init2(&d->ide_if[0], 14, hd_table[0], hd_table[1]);
+    ide_init2(&d->ide_if[2], 15, hd_table[2], hd_table[3]);
+    ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
+    ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
+}
+
+/***********************************************************/
+/* MacIO based PowerPC IDE */
+
+/* PowerMac IDE memory IO */
+static void pmac_ide_writeb (void *opaque,
+                             target_phys_addr_t addr, uint32_t val)
+{
+    addr = (addr & 0xFFF) >> 4; 
+    switch (addr) {
+    case 1 ... 7:
+        ide_ioport_write(opaque, addr, val);
+        break;
+    case 8:
+    case 22:
+        ide_cmd_write(opaque, 0, val);
+        break;
+    default:
+        break;
+    }
+}
+
+static uint32_t pmac_ide_readb (void *opaque,target_phys_addr_t addr)
+{
+    uint8_t retval;
+
+    addr = (addr & 0xFFF) >> 4;
+    switch (addr) {
+    case 1 ... 7:
+        retval = ide_ioport_read(opaque, addr);
+        break;
+    case 8:
+    case 22:
+        retval = ide_status_read(opaque, 0);
+        break;
+    default:
+        retval = 0xFF;
+        break;
+    }
+    return retval;
+}
+
+static void pmac_ide_writew (void *opaque,
+                             target_phys_addr_t addr, uint32_t val)
+{
+    addr = (addr & 0xFFF) >> 4; 
+#ifdef TARGET_WORDS_BIGENDIAN
+    val = bswap16(val);
+#endif
+    if (addr == 0) {
+        ide_data_writew(opaque, 0, val);
+    }
+}
+
+static uint32_t pmac_ide_readw (void *opaque,target_phys_addr_t addr)
+{
+    uint16_t retval;
+
+    addr = (addr & 0xFFF) >> 4; 
+    if (addr == 0) {
+        retval = ide_data_readw(opaque, 0);
+    } else {
+        retval = 0xFFFF;
+    }
+#ifdef TARGET_WORDS_BIGENDIAN
+    retval = bswap16(retval);
+#endif
+    return retval;
+}
+
+static void pmac_ide_writel (void *opaque,
+                             target_phys_addr_t addr, uint32_t val)
+{
+    addr = (addr & 0xFFF) >> 4; 
+#ifdef TARGET_WORDS_BIGENDIAN
+    val = bswap32(val);
+#endif
+    if (addr == 0) {
+        ide_data_writel(opaque, 0, val);
+    }
+}
+
+static uint32_t pmac_ide_readl (void *opaque,target_phys_addr_t addr)
+{
+    uint32_t retval;
+
+    addr = (addr & 0xFFF) >> 4; 
+    if (addr == 0) {
+        retval = ide_data_readl(opaque, 0);
+    } else {
+        retval = 0xFFFFFFFF;
+    }
+#ifdef TARGET_WORDS_BIGENDIAN
+    retval = bswap32(retval);
+#endif
+    return retval;
+}
+
+static CPUWriteMemoryFunc *pmac_ide_write[] = {
+    pmac_ide_writeb,
+    pmac_ide_writew,
+    pmac_ide_writel,
+};
+
+static CPUReadMemoryFunc *pmac_ide_read[] = {
+    pmac_ide_readb,
+    pmac_ide_readw,
+    pmac_ide_readl,
+};
+
+/* hd_table must contain 4 block drivers */
+/* PowerMac uses memory mapped registers, not I/O. Return the memory
+   I/O index to access the ide. */
+int pmac_ide_init (BlockDriverState **hd_table,
+                   openpic_t *openpic, int irq)
+{
+    IDEState *ide_if;
+    int pmac_ide_memory;
+
+    ide_if = qemu_mallocz(sizeof(IDEState) * 2);
+    ide_init2(&ide_if[0], irq, hd_table[0], hd_table[1]);
+    ide_if[0].openpic = openpic;
+    ide_if[1].openpic = openpic;
+    
+    pmac_ide_memory = cpu_register_io_memory(0, pmac_ide_read,
+                                             pmac_ide_write, &ide_if[0]);
+    return pmac_ide_memory;
+}
diff --git a/tools/ioemu/hw/iommu.c b/tools/ioemu/hw/iommu.c
new file mode 100644 (file)
index 0000000..a9249c4
--- /dev/null
@@ -0,0 +1,218 @@
+/*
+ * QEMU SPARC iommu emulation
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+
+/* debug iommu */
+//#define DEBUG_IOMMU
+
+/* The IOMMU registers occupy three pages in IO space. */
+struct iommu_regs {
+       /* First page */
+       volatile unsigned long control;    /* IOMMU control */
+       volatile unsigned long base;       /* Physical base of iopte page table */
+       volatile unsigned long _unused1[3];
+       volatile unsigned long tlbflush;   /* write only */
+       volatile unsigned long pageflush;  /* write only */
+       volatile unsigned long _unused2[1017];
+       /* Second page */
+       volatile unsigned long afsr;       /* Async-fault status register */
+       volatile unsigned long afar;       /* Async-fault physical address */
+       volatile unsigned long _unused3[2];
+       volatile unsigned long sbuscfg0;   /* SBUS configuration registers, per-slot */
+       volatile unsigned long sbuscfg1;
+       volatile unsigned long sbuscfg2;
+       volatile unsigned long sbuscfg3;
+       volatile unsigned long mfsr;       /* Memory-fault status register */
+       volatile unsigned long mfar;       /* Memory-fault physical address */
+       volatile unsigned long _unused4[1014];
+       /* Third page */
+       volatile unsigned long mid;        /* IOMMU module-id */
+};
+
+#define IOMMU_CTRL_IMPL     0xf0000000 /* Implementation */
+#define IOMMU_CTRL_VERS     0x0f000000 /* Version */
+#define IOMMU_CTRL_RNGE     0x0000001c /* Mapping RANGE */
+#define IOMMU_RNGE_16MB     0x00000000 /* 0xff000000 -> 0xffffffff */
+#define IOMMU_RNGE_32MB     0x00000004 /* 0xfe000000 -> 0xffffffff */
+#define IOMMU_RNGE_64MB     0x00000008 /* 0xfc000000 -> 0xffffffff */
+#define IOMMU_RNGE_128MB    0x0000000c /* 0xf8000000 -> 0xffffffff */
+#define IOMMU_RNGE_256MB    0x00000010 /* 0xf0000000 -> 0xffffffff */
+#define IOMMU_RNGE_512MB    0x00000014 /* 0xe0000000 -> 0xffffffff */
+#define IOMMU_RNGE_1GB      0x00000018 /* 0xc0000000 -> 0xffffffff */
+#define IOMMU_RNGE_2GB      0x0000001c /* 0x80000000 -> 0xffffffff */
+#define IOMMU_CTRL_ENAB     0x00000001 /* IOMMU Enable */
+
+#define IOMMU_AFSR_ERR      0x80000000 /* LE, TO, or BE asserted */
+#define IOMMU_AFSR_LE       0x40000000 /* SBUS reports error after transaction */
+#define IOMMU_AFSR_TO       0x20000000 /* Write access took more than 12.8 us. */
+#define IOMMU_AFSR_BE       0x10000000 /* Write access received error acknowledge */
+#define IOMMU_AFSR_SIZE     0x0e000000 /* Size of transaction causing error */
+#define IOMMU_AFSR_S        0x01000000 /* Sparc was in supervisor mode */
+#define IOMMU_AFSR_RESV     0x00f00000 /* Reserver, forced to 0x8 by hardware */
+#define IOMMU_AFSR_ME       0x00080000 /* Multiple errors occurred */
+#define IOMMU_AFSR_RD       0x00040000 /* A read operation was in progress */
+#define IOMMU_AFSR_FAV      0x00020000 /* IOMMU afar has valid contents */
+
+#define IOMMU_SBCFG_SAB30   0x00010000 /* Phys-address bit 30 when bypass enabled */
+#define IOMMU_SBCFG_BA16    0x00000004 /* Slave supports 16 byte bursts */
+#define IOMMU_SBCFG_BA8     0x00000002 /* Slave supports 8 byte bursts */
+#define IOMMU_SBCFG_BYPASS  0x00000001 /* Bypass IOMMU, treat all addresses
+                                         produced by this device as pure
+                                         physical. */
+
+#define IOMMU_MFSR_ERR      0x80000000 /* One or more of PERR1 or PERR0 */
+#define IOMMU_MFSR_S        0x01000000 /* Sparc was in supervisor mode */
+#define IOMMU_MFSR_CPU      0x00800000 /* CPU transaction caused parity error */
+#define IOMMU_MFSR_ME       0x00080000 /* Multiple parity errors occurred */
+#define IOMMU_MFSR_PERR     0x00006000 /* high bit indicates parity error occurred
+                                         on the even word of the access, low bit
+                                         indicated odd word caused the parity error */
+#define IOMMU_MFSR_BM       0x00001000 /* Error occurred while in boot mode */
+#define IOMMU_MFSR_C        0x00000800 /* Address causing error was marked cacheable */
+#define IOMMU_MFSR_RTYP     0x000000f0 /* Memory request transaction type */
+
+#define IOMMU_MID_SBAE      0x001f0000 /* SBus arbitration enable */
+#define IOMMU_MID_SE        0x00100000 /* Enables SCSI/ETHERNET arbitration */
+#define IOMMU_MID_SB3       0x00080000 /* Enable SBUS device 3 arbitration */
+#define IOMMU_MID_SB2       0x00040000 /* Enable SBUS device 2 arbitration */
+#define IOMMU_MID_SB1       0x00020000 /* Enable SBUS device 1 arbitration */
+#define IOMMU_MID_SB0       0x00010000 /* Enable SBUS device 0 arbitration */
+#define IOMMU_MID_MID       0x0000000f /* Module-id, hardcoded to 0x8 */
+
+/* The format of an iopte in the page tables */
+#define IOPTE_PAGE          0x07ffff00 /* Physical page number (PA[30:12]) */
+#define IOPTE_CACHE         0x00000080 /* Cached (in vme IOCACHE or Viking/MXCC) */
+#define IOPTE_WRITE         0x00000004 /* Writeable */
+#define IOPTE_VALID         0x00000002 /* IOPTE is valid */
+#define IOPTE_WAZ           0x00000001 /* Write as zeros */
+
+#define PAGE_SHIFT      12
+#define PAGE_SIZE       (1 << PAGE_SHIFT)
+#define PAGE_MASK      (PAGE_SIZE - 1)
+
+typedef struct IOMMUState {
+    uint32_t addr;
+    uint32_t regs[sizeof(struct iommu_regs)];
+    uint32_t iostart;
+} IOMMUState;
+
+static IOMMUState *ps;
+
+static uint32_t iommu_mem_readw(void *opaque, target_phys_addr_t addr)
+{
+    IOMMUState *s = opaque;
+    uint32_t saddr;
+
+    saddr = (addr - s->addr) >> 2;
+    switch (saddr) {
+    default:
+       return s->regs[saddr];
+       break;
+    }
+    return 0;
+}
+
+static void iommu_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
+{
+    IOMMUState *s = opaque;
+    uint32_t saddr;
+
+    saddr = (addr - s->addr) >> 2;
+    switch (saddr) {
+    case 0:
+       switch (val & IOMMU_CTRL_RNGE) {
+       case IOMMU_RNGE_16MB:
+           s->iostart = 0xff000000;
+           break;
+       case IOMMU_RNGE_32MB:
+           s->iostart = 0xfe000000;
+           break;
+       case IOMMU_RNGE_64MB:
+           s->iostart = 0xfc000000;
+           break;
+       case IOMMU_RNGE_128MB:
+           s->iostart = 0xf8000000;
+           break;
+       case IOMMU_RNGE_256MB:
+           s->iostart = 0xf0000000;
+           break;
+       case IOMMU_RNGE_512MB:
+           s->iostart = 0xe0000000;
+           break;
+       case IOMMU_RNGE_1GB:
+           s->iostart = 0xc0000000;
+           break;
+       default:
+       case IOMMU_RNGE_2GB:
+           s->iostart = 0x80000000;
+           break;
+       }
+       /* Fall through */
+    default:
+       s->regs[saddr] = val;
+       break;
+    }
+}
+
+static CPUReadMemoryFunc *iommu_mem_read[3] = {
+    iommu_mem_readw,
+    iommu_mem_readw,
+    iommu_mem_readw,
+};
+
+static CPUWriteMemoryFunc *iommu_mem_write[3] = {
+    iommu_mem_writew,
+    iommu_mem_writew,
+    iommu_mem_writew,
+};
+
+uint32_t iommu_translate(uint32_t addr)
+{
+    uint32_t *iopte = (void *)(ps->regs[1] << 4), pa;
+
+    iopte += ((addr - ps->iostart) >> PAGE_SHIFT);
+    cpu_physical_memory_rw((uint32_t)iopte, (void *) &pa, 4, 0);
+    bswap32s(&pa);
+    pa = (pa & IOPTE_PAGE) << 4;               /* Loose higher bits of 36 */
+    return pa + (addr & PAGE_MASK);
+}
+
+void iommu_init(uint32_t addr)
+{
+    IOMMUState *s;
+    int iommu_io_memory;
+
+    s = qemu_mallocz(sizeof(IOMMUState));
+    if (!s)
+        return;
+
+    s->addr = addr;
+
+    iommu_io_memory = cpu_register_io_memory(0, iommu_mem_read, iommu_mem_write, s);
+    cpu_register_physical_memory(addr, sizeof(struct iommu_regs),
+                                 iommu_io_memory);
+    
+    ps = s;
+}
+
diff --git a/tools/ioemu/hw/lance.c b/tools/ioemu/hw/lance.c
new file mode 100644 (file)
index 0000000..25ad8c4
--- /dev/null
@@ -0,0 +1,468 @@
+/*
+ * QEMU Lance emulation
+ * 
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+
+/* debug LANCE card */
+//#define DEBUG_LANCE
+
+#ifndef LANCE_LOG_TX_BUFFERS
+#define LANCE_LOG_TX_BUFFERS 4
+#define LANCE_LOG_RX_BUFFERS 4
+#endif
+
+#define CRC_POLYNOMIAL_BE 0x04c11db7UL  /* Ethernet CRC, big endian */
+#define CRC_POLYNOMIAL_LE 0xedb88320UL  /* Ethernet CRC, little endian */
+
+
+#define LE_CSR0 0
+#define LE_CSR1 1
+#define LE_CSR2 2
+#define LE_CSR3 3
+#define LE_MAXREG (LE_CSR3 + 1)
+
+#define LE_RDP  0
+#define LE_RAP  1
+
+#define LE_MO_PROM      0x8000  /* Enable promiscuous mode */
+
+#define        LE_C0_ERR       0x8000  /* Error: set if BAB, SQE, MISS or ME is set */
+#define        LE_C0_BABL      0x4000  /* BAB:  Babble: tx timeout. */
+#define        LE_C0_CERR      0x2000  /* SQE:  Signal quality error */
+#define        LE_C0_MISS      0x1000  /* MISS: Missed a packet */
+#define        LE_C0_MERR      0x0800  /* ME:   Memory error */
+#define        LE_C0_RINT      0x0400  /* Received interrupt */
+#define        LE_C0_TINT      0x0200  /* Transmitter Interrupt */
+#define        LE_C0_IDON      0x0100  /* IFIN: Init finished. */
+#define        LE_C0_INTR      0x0080  /* Interrupt or error */
+#define        LE_C0_INEA      0x0040  /* Interrupt enable */
+#define        LE_C0_RXON      0x0020  /* Receiver on */
+#define        LE_C0_TXON      0x0010  /* Transmitter on */
+#define        LE_C0_TDMD      0x0008  /* Transmitter demand */
+#define        LE_C0_STOP      0x0004  /* Stop the card */
+#define        LE_C0_STRT      0x0002  /* Start the card */
+#define        LE_C0_INIT      0x0001  /* Init the card */
+
+#define        LE_C3_BSWP      0x4     /* SWAP */
+#define        LE_C3_ACON      0x2     /* ALE Control */
+#define        LE_C3_BCON      0x1     /* Byte control */
+
+/* Receive message descriptor 1 */
+#define LE_R1_OWN       0x80    /* Who owns the entry */
+#define LE_R1_ERR       0x40    /* Error: if FRA, OFL, CRC or BUF is set */
+#define LE_R1_FRA       0x20    /* FRA: Frame error */
+#define LE_R1_OFL       0x10    /* OFL: Frame overflow */
+#define LE_R1_CRC       0x08    /* CRC error */
+#define LE_R1_BUF       0x04    /* BUF: Buffer error */
+#define LE_R1_SOP       0x02    /* Start of packet */
+#define LE_R1_EOP       0x01    /* End of packet */
+#define LE_R1_POK       0x03    /* Packet is complete: SOP + EOP */
+
+#define LE_T1_OWN       0x80    /* Lance owns the packet */
+#define LE_T1_ERR       0x40    /* Error summary */
+#define LE_T1_EMORE     0x10    /* Error: more than one retry needed */
+#define LE_T1_EONE      0x08    /* Error: one retry needed */
+#define LE_T1_EDEF      0x04    /* Error: deferred */
+#define LE_T1_SOP       0x02    /* Start of packet */
+#define LE_T1_EOP       0x01    /* End of packet */
+#define LE_T1_POK      0x03    /* Packet is complete: SOP + EOP */
+
+#define LE_T3_BUF       0x8000  /* Buffer error */
+#define LE_T3_UFL       0x4000  /* Error underflow */
+#define LE_T3_LCOL      0x1000  /* Error late collision */
+#define LE_T3_CLOS      0x0800  /* Error carrier loss */
+#define LE_T3_RTY       0x0400  /* Error retry */
+#define LE_T3_TDR       0x03ff  /* Time Domain Reflectometry counter */
+
+#define TX_RING_SIZE                   (1 << (LANCE_LOG_TX_BUFFERS))
+#define TX_RING_MOD_MASK               (TX_RING_SIZE - 1)
+#define TX_RING_LEN_BITS               ((LANCE_LOG_TX_BUFFERS) << 29)
+
+#define RX_RING_SIZE                   (1 << (LANCE_LOG_RX_BUFFERS))
+#define RX_RING_MOD_MASK               (RX_RING_SIZE - 1)
+#define RX_RING_LEN_BITS               ((LANCE_LOG_RX_BUFFERS) << 29)
+
+#define PKT_BUF_SZ             1544
+#define RX_BUFF_SIZE            PKT_BUF_SZ
+#define TX_BUFF_SIZE            PKT_BUF_SZ
+
+struct lance_rx_desc {
+       unsigned short rmd0;        /* low address of packet */
+       unsigned char  rmd1_bits;   /* descriptor bits */
+       unsigned char  rmd1_hadr;   /* high address of packet */
+       short    length;            /* This length is 2s complement (negative)!
+                                    * Buffer length
+                                    */
+       unsigned short mblength;    /* This is the actual number of bytes received */
+};
+
+struct lance_tx_desc {
+       unsigned short tmd0;        /* low address of packet */
+       unsigned char  tmd1_bits;   /* descriptor bits */
+       unsigned char  tmd1_hadr;   /* high address of packet */
+       short length;               /* Length is 2s complement (negative)! */
+       unsigned short misc;
+};
+
+/* The LANCE initialization block, described in databook. */
+/* On the Sparc, this block should be on a DMA region     */
+struct lance_init_block {
+       unsigned short mode;            /* Pre-set mode (reg. 15) */
+       unsigned char phys_addr[6];     /* Physical ethernet address */
+       unsigned filter[2];             /* Multicast filter. */
+
+       /* Receive and transmit ring base, along with extra bits. */
+       unsigned short rx_ptr;          /* receive descriptor addr */
+       unsigned short rx_len;          /* receive len and high addr */
+       unsigned short tx_ptr;          /* transmit descriptor addr */
+       unsigned short tx_len;          /* transmit len and high addr */
+    
+       /* The Tx and Rx ring entries must aligned on 8-byte boundaries. */
+       struct lance_rx_desc brx_ring[RX_RING_SIZE];
+       struct lance_tx_desc btx_ring[TX_RING_SIZE];
+    
+       char   tx_buf [TX_RING_SIZE][TX_BUFF_SIZE];
+       char   pad[2];                  /* align rx_buf for copy_and_sum(). */
+       char   rx_buf [RX_RING_SIZE][RX_BUFF_SIZE];
+};
+
+#define LEDMA_REGS 4
+#if 0
+/* Structure to describe the current status of DMA registers on the Sparc */
+struct sparc_dma_registers {
+    uint32_t cond_reg; /* DMA condition register */
+    uint32_t st_addr;  /* Start address of this transfer */
+    uint32_t cnt;      /* How many bytes to transfer */
+    uint32_t dma_test; /* DMA test register */
+};
+#endif
+
+typedef struct LEDMAState {
+    uint32_t addr;
+    uint32_t regs[LEDMA_REGS];
+} LEDMAState;
+
+typedef struct LANCEState {
+    uint32_t paddr;
+    NetDriverState *nd;
+    uint32_t leptr;
+    uint16_t addr;
+    uint16_t regs[LE_MAXREG];
+    uint8_t phys[6]; /* mac address */
+    int irq;
+    LEDMAState *ledma;
+} LANCEState;
+
+static unsigned int rxptr, txptr;
+
+static void lance_send(void *opaque);
+
+static void lance_reset(LANCEState *s)
+{
+    memcpy(s->phys, s->nd->macaddr, 6);
+    rxptr = 0;
+    txptr = 0;
+    s->regs[LE_CSR0] = LE_C0_STOP;
+}
+
+static uint32_t lance_mem_readw(void *opaque, target_phys_addr_t addr)
+{
+    LANCEState *s = opaque;
+    uint32_t saddr;
+
+    saddr = addr - s->paddr;
+    switch (saddr >> 1) {
+    case LE_RDP:
+       return s->regs[s->addr];
+    case LE_RAP:
+       return s->addr;
+    default:
+       break;
+    }
+    return 0;
+}
+
+static void lance_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
+{
+    LANCEState *s = opaque;
+    uint32_t saddr;
+    uint16_t reg;
+
+    saddr = addr - s->paddr;
+    switch (saddr >> 1) {
+    case LE_RDP:
+       switch(s->addr) {
+       case LE_CSR0:
+           if (val & LE_C0_STOP) {
+               s->regs[LE_CSR0] = LE_C0_STOP;
+               break;
+           }
+
+           reg = s->regs[LE_CSR0];
+
+           // 1 = clear for some bits
+           reg &= ~(val & 0x7f00);
+
+           // generated bits
+           reg &= ~(LE_C0_ERR | LE_C0_INTR);
+           if (reg & 0x7100)
+               reg |= LE_C0_ERR;
+           if (reg & 0x7f00)
+               reg |= LE_C0_INTR;
+
+           // direct bit
+           reg &= ~LE_C0_INEA;
+           reg |= val & LE_C0_INEA;
+
+           // exclusive bits
+           if (val & LE_C0_INIT) {
+               reg |= LE_C0_IDON | LE_C0_INIT;
+               reg &= ~LE_C0_STOP;
+           }
+           else if (val & LE_C0_STRT) {
+               reg |= LE_C0_STRT | LE_C0_RXON | LE_C0_TXON;
+               reg &= ~LE_C0_STOP;
+           }
+
+           s->regs[LE_CSR0] = reg;
+
+           // trigger bits
+           //if (val & LE_C0_TDMD)
+
+           if ((s->regs[LE_CSR0] & LE_C0_INTR) && (s->regs[LE_CSR0] & LE_C0_INEA))
+               pic_set_irq(s->irq, 1);
+           break;
+       case LE_CSR1:
+           s->leptr = (s->leptr & 0xffff0000) | (val & 0xffff);
+           s->regs[s->addr] = val;
+           break;
+       case LE_CSR2:
+           s->leptr = (s->leptr & 0xffff) | ((val & 0xffff) << 16);
+           s->regs[s->addr] = val;
+           break;
+       case LE_CSR3:
+           s->regs[s->addr] = val;
+           break;
+       }
+       break;
+    case LE_RAP:
+       if (val < LE_MAXREG)
+           s->addr = val;
+       break;
+    default:
+       break;
+    }
+    lance_send(s);
+}
+
+static CPUReadMemoryFunc *lance_mem_read[3] = {
+    lance_mem_readw,
+    lance_mem_readw,
+    lance_mem_readw,
+};
+
+static CPUWriteMemoryFunc *lance_mem_write[3] = {
+    lance_mem_writew,
+    lance_mem_writew,
+    lance_mem_writew,
+};
+
+
+/* return the max buffer size if the LANCE can receive more data */
+static int lance_can_receive(void *opaque)
+{
+    LANCEState *s = opaque;
+    void *dmaptr = (void *) (s->leptr + s->ledma->regs[3]);
+    struct lance_init_block *ib;
+    int i;
+    uint16_t temp;
+
+    if ((s->regs[LE_CSR0] & LE_C0_STOP) == LE_C0_STOP)
+       return 0;
+
+    ib = (void *) iommu_translate(dmaptr);
+
+    for (i = 0; i < RX_RING_SIZE; i++) {
+       cpu_physical_memory_read(&ib->brx_ring[i].rmd1_bits, (void *) &temp, 1);
+       temp &= 0xff;
+       if (temp == (LE_R1_OWN)) {
+#ifdef DEBUG_LANCE
+           fprintf(stderr, "lance: can receive %d\n", RX_BUFF_SIZE);
+#endif
+           return RX_BUFF_SIZE;
+       }
+    }
+#ifdef DEBUG_LANCE
+    fprintf(stderr, "lance: cannot receive\n");
+#endif
+    return 0;
+}
+
+#define MIN_BUF_SIZE 60
+
+static void lance_receive(void *opaque, const uint8_t *buf, int size)
+{
+    LANCEState *s = opaque;
+    void *dmaptr = (void *) (s->leptr + s->ledma->regs[3]);
+    struct lance_init_block *ib;
+    unsigned int i, old_rxptr, j;
+    uint16_t temp;
+
+    if ((s->regs[LE_CSR0] & LE_C0_STOP) == LE_C0_STOP)
+       return;
+
+    ib = (void *) iommu_translate(dmaptr);
+
+    old_rxptr = rxptr;
+    for (i = rxptr; i != ((old_rxptr - 1) & RX_RING_MOD_MASK); i = (i + 1) & RX_RING_MOD_MASK) {
+       cpu_physical_memory_read(&ib->brx_ring[i].rmd1_bits, (void *) &temp, 1);
+       if (temp == (LE_R1_OWN)) {
+           rxptr = (rxptr + 1) & RX_RING_MOD_MASK;
+           temp = size;
+           bswap16s(&temp);
+           cpu_physical_memory_write(&ib->brx_ring[i].mblength, (void *) &temp, 2);
+#if 0
+           cpu_physical_memory_write(&ib->rx_buf[i], buf, size);
+#else
+           for (j = 0; j < size; j++) {
+               cpu_physical_memory_write(((void *)&ib->rx_buf[i]) + j, &buf[j], 1);
+           }
+#endif
+           temp = LE_R1_POK;
+           cpu_physical_memory_write(&ib->brx_ring[i].rmd1_bits, (void *) &temp, 1);
+           s->regs[LE_CSR0] |= LE_C0_RINT | LE_C0_INTR;
+           if ((s->regs[LE_CSR0] & LE_C0_INTR) && (s->regs[LE_CSR0] & LE_C0_INEA))
+               pic_set_irq(s->irq, 1);
+#ifdef DEBUG_LANCE
+           fprintf(stderr, "lance: got packet, len %d\n", size);
+#endif
+           return;
+       }
+    }
+}
+
+static void lance_send(void *opaque)
+{
+    LANCEState *s = opaque;
+    void *dmaptr = (void *) (s->leptr + s->ledma->regs[3]);
+    struct lance_init_block *ib;
+    unsigned int i, old_txptr, j;
+    uint16_t temp;
+    char pkt_buf[PKT_BUF_SZ];
+
+    if ((s->regs[LE_CSR0] & LE_C0_STOP) == LE_C0_STOP)
+       return;
+
+    ib = (void *) iommu_translate(dmaptr);
+
+    old_txptr = txptr;
+    for (i = txptr; i != ((old_txptr - 1) & TX_RING_MOD_MASK); i = (i + 1) & TX_RING_MOD_MASK) {
+       cpu_physical_memory_read(&ib->btx_ring[i].tmd1_bits, (void *) &temp, 1);
+       if (temp == (LE_T1_POK|LE_T1_OWN)) {
+           cpu_physical_memory_read(&ib->btx_ring[i].length, (void *) &temp, 2);
+           bswap16s(&temp);
+           temp = (~temp) + 1;
+#if 0
+           cpu_physical_memory_read(&ib->tx_buf[i], pkt_buf, temp);
+#else
+           for (j = 0; j < temp; j++) {
+               cpu_physical_memory_read(((void *)&ib->tx_buf[i]) + j, &pkt_buf[j], 1);
+           }
+#endif
+
+#ifdef DEBUG_LANCE
+           fprintf(stderr, "lance: sending packet, len %d\n", temp);
+#endif
+           qemu_send_packet(s->nd, pkt_buf, temp);
+           temp = LE_T1_POK;
+           cpu_physical_memory_write(&ib->btx_ring[i].tmd1_bits, (void *) &temp, 1);
+           txptr = (txptr + 1) & TX_RING_MOD_MASK;
+           s->regs[LE_CSR0] |= LE_C0_TINT | LE_C0_INTR;
+       }
+    }
+}
+
+static uint32_t ledma_mem_readl(void *opaque, target_phys_addr_t addr)
+{
+    LEDMAState *s = opaque;
+    uint32_t saddr;
+
+    saddr = (addr - s->addr) >> 2;
+    if (saddr < LEDMA_REGS)
+       return s->regs[saddr];
+    else
+       return 0;
+}
+
+static void ledma_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
+{
+    LEDMAState *s = opaque;
+    uint32_t saddr;
+
+    saddr = (addr - s->addr) >> 2;
+    if (saddr < LEDMA_REGS)
+       s->regs[saddr] = val;
+}
+
+static CPUReadMemoryFunc *ledma_mem_read[3] = {
+    ledma_mem_readl,
+    ledma_mem_readl,
+    ledma_mem_readl,
+};
+
+static CPUWriteMemoryFunc *ledma_mem_write[3] = {
+    ledma_mem_writel,
+    ledma_mem_writel,
+    ledma_mem_writel,
+};
+
+void lance_init(NetDriverState *nd, int irq, uint32_t leaddr, uint32_t ledaddr)
+{
+    LANCEState *s;
+    LEDMAState *led;
+    int lance_io_memory, ledma_io_memory;
+
+    s = qemu_mallocz(sizeof(LANCEState));
+    if (!s)
+        return;
+
+    s->paddr = leaddr;
+    s->nd = nd;
+    s->irq = irq;
+
+    lance_io_memory = cpu_register_io_memory(0, lance_mem_read, lance_mem_write, s);
+    cpu_register_physical_memory(leaddr, 8, lance_io_memory);
+
+    led = qemu_mallocz(sizeof(LEDMAState));
+    if (!led)
+        return;
+
+    s->ledma = led;
+    led->addr = ledaddr;
+    ledma_io_memory = cpu_register_io_memory(0, ledma_mem_read, ledma_mem_write, led);
+    cpu_register_physical_memory(ledaddr, 16, ledma_io_memory);
+
+    lance_reset(s);
+    qemu_add_read_packet(nd, lance_can_receive, lance_receive, s);
+}
+
diff --git a/tools/ioemu/hw/m48t08.c b/tools/ioemu/hw/m48t08.c
new file mode 100644 (file)
index 0000000..46ec665
--- /dev/null
@@ -0,0 +1,391 @@
+/*
+ * QEMU M48T08 NVRAM emulation for Sparc platform
+ * 
+ * Copyright (c) 2003-2004 Jocelyn Mayer
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+#include "m48t08.h"
+
+//#define DEBUG_NVRAM
+
+#if defined(DEBUG_NVRAM)
+#define NVRAM_PRINTF(fmt, args...) do { printf(fmt , ##args); } while (0)
+#else
+#define NVRAM_PRINTF(fmt, args...) do { } while (0)
+#endif
+
+#define NVRAM_MAX_MEM 0xfff0
+
+struct m48t08_t {
+    /* Hardware parameters */
+    int mem_index;
+    uint32_t mem_base;
+    uint16_t size;
+    /* RTC management */
+    time_t   time_offset;
+    time_t   stop_time;
+    /* NVRAM storage */
+    uint8_t  lock;
+    uint16_t addr;
+    uint8_t *buffer;
+};
+
+/* Fake timer functions */
+/* Generic helpers for BCD */
+static inline uint8_t toBCD (uint8_t value)
+{
+    return (((value / 10) % 10) << 4) | (value % 10);
+}
+
+static inline uint8_t fromBCD (uint8_t BCD)
+{
+    return ((BCD >> 4) * 10) + (BCD & 0x0F);
+}
+
+/* RTC management helpers */
+static void get_time (m48t08_t *NVRAM, struct tm *tm)
+{
+    time_t t;
+
+    t = time(NULL) + NVRAM->time_offset;
+#ifdef _WIN32
+    memcpy(tm,localtime(&t),sizeof(*tm));
+#else
+    localtime_r (&t, tm) ;
+#endif
+}
+
+static void set_time (m48t08_t *NVRAM, struct tm *tm)
+{
+    time_t now, new_time;
+    
+    new_time = mktime(tm);
+    now = time(NULL);
+    NVRAM->time_offset = new_time - now;
+}
+
+/* Direct access to NVRAM */
+void m48t08_write (m48t08_t *NVRAM, uint32_t val)
+{
+    struct tm tm;
+    int tmp;
+
+    if (NVRAM->addr > NVRAM_MAX_MEM && NVRAM->addr < 0x2000)
+       NVRAM_PRINTF("%s: 0x%08x => 0x%08x\n", __func__, NVRAM->addr, val);
+    switch (NVRAM->addr) {
+    case 0x1FF8:
+        /* control */
+       NVRAM->buffer[0x1FF8] = (val & ~0xA0) | 0x90;
+        break;
+    case 0x1FF9:
+        /* seconds (BCD) */
+       tmp = fromBCD(val & 0x7F);
+       if (tmp >= 0 && tmp <= 59) {
+           get_time(NVRAM, &tm);
+           tm.tm_sec = tmp;
+           set_time(NVRAM, &tm);
+       }
+       if ((val & 0x80) ^ (NVRAM->buffer[0x1FF9] & 0x80)) {
+           if (val & 0x80) {
+               NVRAM->stop_time = time(NULL);
+           } else {
+               NVRAM->time_offset += NVRAM->stop_time - time(NULL);
+               NVRAM->stop_time = 0;
+           }
+       }
+       NVRAM->buffer[0x1FF9] = val & 0x80;
+        break;
+    case 0x1FFA:
+        /* minutes (BCD) */
+       tmp = fromBCD(val & 0x7F);
+       if (tmp >= 0 && tmp <= 59) {
+           get_time(NVRAM, &tm);
+           tm.tm_min = tmp;
+           set_time(NVRAM, &tm);
+       }
+        break;
+    case 0x1FFB:
+        /* hours (BCD) */
+       tmp = fromBCD(val & 0x3F);
+       if (tmp >= 0 && tmp <= 23) {
+           get_time(NVRAM, &tm);
+           tm.tm_hour = tmp;
+           set_time(NVRAM, &tm);
+       }
+        break;
+    case 0x1FFC:
+        /* day of the week / century */
+       tmp = fromBCD(val & 0x07);
+       get_time(NVRAM, &tm);
+       tm.tm_wday = tmp;
+       set_time(NVRAM, &tm);
+        NVRAM->buffer[0x1FFC] = val & 0x40;
+        break;
+    case 0x1FFD:
+        /* date */
+       tmp = fromBCD(val & 0x1F);
+       if (tmp != 0) {
+           get_time(NVRAM, &tm);
+           tm.tm_mday = tmp;
+           set_time(NVRAM, &tm);
+       }
+        break;
+    case 0x1FFE:
+        /* month */
+       tmp = fromBCD(val & 0x1F);
+       if (tmp >= 1 && tmp <= 12) {
+           get_time(NVRAM, &tm);
+           tm.tm_mon = tmp - 1;
+           set_time(NVRAM, &tm);
+       }
+        break;
+    case 0x1FFF:
+        /* year */
+       tmp = fromBCD(val);
+       if (tmp >= 0 && tmp <= 99) {
+           get_time(NVRAM, &tm);
+           tm.tm_year = fromBCD(val);
+           set_time(NVRAM, &tm);
+       }
+        break;
+    default:
+        /* Check lock registers state */
+        if (NVRAM->addr >= 0x20 && NVRAM->addr <= 0x2F && (NVRAM->lock & 1))
+            break;
+        if (NVRAM->addr >= 0x30 && NVRAM->addr <= 0x3F && (NVRAM->lock & 2))
+            break;
+        if (NVRAM->addr < NVRAM_MAX_MEM ||
+           (NVRAM->addr > 0x1FFF && NVRAM->addr < NVRAM->size)) {
+            NVRAM->buffer[NVRAM->addr] = val & 0xFF;
+       }
+        break;
+    }
+}
+
+uint32_t m48t08_read (m48t08_t *NVRAM)
+{
+    struct tm tm;
+    uint32_t retval = 0xFF;
+
+    switch (NVRAM->addr) {
+    case 0x1FF8:
+        /* control */
+       goto do_read;
+    case 0x1FF9:
+        /* seconds (BCD) */
+        get_time(NVRAM, &tm);
+        retval = (NVRAM->buffer[0x1FF9] & 0x80) | toBCD(tm.tm_sec);
+        break;
+    case 0x1FFA:
+        /* minutes (BCD) */
+        get_time(NVRAM, &tm);
+        retval = toBCD(tm.tm_min);
+        break;
+    case 0x1FFB:
+        /* hours (BCD) */
+        get_time(NVRAM, &tm);
+        retval = toBCD(tm.tm_hour);
+        break;
+    case 0x1FFC:
+        /* day of the week / century */
+        get_time(NVRAM, &tm);
+        retval = NVRAM->buffer[0x1FFC] | tm.tm_wday;
+        break;
+    case 0x1FFD:
+        /* date */
+        get_time(NVRAM, &tm);
+        retval = toBCD(tm.tm_mday);
+        break;
+    case 0x1FFE:
+        /* month */
+        get_time(NVRAM, &tm);
+        retval = toBCD(tm.tm_mon + 1);
+        break;
+    case 0x1FFF:
+        /* year */
+        get_time(NVRAM, &tm);
+        retval = toBCD(tm.tm_year);
+        break;
+    default:
+        /* Check lock registers state */
+        if (NVRAM->addr >= 0x20 && NVRAM->addr <= 0x2F && (NVRAM->lock & 1))
+            break;
+        if (NVRAM->addr >= 0x30 && NVRAM->addr <= 0x3F && (NVRAM->lock & 2))
+            break;
+        if (NVRAM->addr < NVRAM_MAX_MEM ||
+           (NVRAM->addr > 0x1FFF && NVRAM->addr < NVRAM->size)) {
+       do_read:
+            retval = NVRAM->buffer[NVRAM->addr];
+       }
+        break;
+    }
+    if (NVRAM->addr > NVRAM_MAX_MEM + 1 && NVRAM->addr < 0x2000)
+       NVRAM_PRINTF("0x%08x <= 0x%08x\n", NVRAM->addr, retval);
+
+    return retval;
+}
+
+void m48t08_set_addr (m48t08_t *NVRAM, uint32_t addr)
+{
+    NVRAM->addr = addr;
+}
+
+void m48t08_toggle_lock (m48t08_t *NVRAM, int lock)
+{
+    NVRAM->lock ^= 1 << lock;
+}
+
+static void nvram_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
+{
+    m48t08_t *NVRAM = opaque;
+    
+    addr -= NVRAM->mem_base;
+    if (addr < NVRAM_MAX_MEM)
+        NVRAM->buffer[addr] = value;
+}
+
+static void nvram_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
+{
+    m48t08_t *NVRAM = opaque;
+    
+    addr -= NVRAM->mem_base;
+    if (addr < NVRAM_MAX_MEM) {
+        NVRAM->buffer[addr] = value >> 8;
+        NVRAM->buffer[addr + 1] = value;
+    }
+}
+
+static void nvram_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
+{
+    m48t08_t *NVRAM = opaque;
+    
+    addr -= NVRAM->mem_base;
+    if (addr < NVRAM_MAX_MEM) {
+        NVRAM->buffer[addr] = value >> 24;
+        NVRAM->buffer[addr + 1] = value >> 16;
+        NVRAM->buffer[addr + 2] = value >> 8;
+        NVRAM->buffer[addr + 3] = value;
+    }
+}
+
+static uint32_t nvram_readb (void *opaque, target_phys_addr_t addr)
+{
+    m48t08_t *NVRAM = opaque;
+    uint32_t retval = 0;
+    
+    addr -= NVRAM->mem_base;
+    if (addr < NVRAM_MAX_MEM)
+        retval = NVRAM->buffer[addr];
+
+    return retval;
+}
+
+static uint32_t nvram_readw (void *opaque, target_phys_addr_t addr)
+{
+    m48t08_t *NVRAM = opaque;
+    uint32_t retval = 0;
+    
+    addr -= NVRAM->mem_base;
+    if (addr < NVRAM_MAX_MEM) {
+        retval = NVRAM->buffer[addr] << 8;
+        retval |= NVRAM->buffer[addr + 1];
+    }
+
+    return retval;
+}
+
+static uint32_t nvram_readl (void *opaque, target_phys_addr_t addr)
+{
+    m48t08_t *NVRAM = opaque;
+    uint32_t retval = 0;
+    
+    addr -= NVRAM->mem_base;
+    if (addr < NVRAM_MAX_MEM) {
+        retval = NVRAM->buffer[addr] << 24;
+        retval |= NVRAM->buffer[addr + 1] << 16;
+        retval |= NVRAM->buffer[addr + 2] << 8;
+        retval |= NVRAM->buffer[addr + 3];
+    }
+
+    return retval;
+}
+
+static CPUWriteMemoryFunc *nvram_write[] = {
+    &nvram_writeb,
+    &nvram_writew,
+    &nvram_writel,
+};
+
+static CPUReadMemoryFunc *nvram_read[] = {
+    &nvram_readb,
+    &nvram_readw,
+    &nvram_readl,
+};
+
+/* Initialisation routine */
+m48t08_t *m48t08_init(uint32_t mem_base, uint16_t size, uint8_t *macaddr)
+{
+    m48t08_t *s;
+    int i;
+    unsigned char tmp = 0;
+
+    s = qemu_mallocz(sizeof(m48t08_t));
+    if (!s)
+       return NULL;
+    s->buffer = qemu_mallocz(size);
+    if (!s->buffer) {
+        qemu_free(s);
+        return NULL;
+    }
+    s->size = size;
+    s->mem_base = mem_base;
+    s->addr = 0;
+    if (mem_base != 0) {
+        s->mem_index = cpu_register_io_memory(0, nvram_read, nvram_write, s);
+        cpu_register_physical_memory(mem_base, 0x4000, s->mem_index);
+    }
+    s->lock = 0;
+
+    i = 0x1fd8;
+    s->buffer[i++] = 0x01;
+    s->buffer[i++] = 0x80; /* Sun4m OBP */
+    memcpy(&s->buffer[i], macaddr, 6);
+
+    /* Calculate checksum */
+    for (i = 0x1fd8; i < 0x1fe7; i++) {
+       tmp ^= s->buffer[i];
+    }
+    s->buffer[0x1fe7] = tmp;
+    return s;
+}
+
+#if 0
+struct idprom
+{
+        unsigned char   id_format;      /* Format identifier (always 0x01) */
+        unsigned char   id_machtype;    /* Machine type */
+        unsigned char   id_ethaddr[6];  /* Hardware ethernet address */
+        long            id_date;        /* Date of manufacture */
+        unsigned int    id_sernum:24;   /* Unique serial number */
+        unsigned char   id_cksum;       /* Checksum - xor of the data bytes */
+        unsigned char   reserved[16];
+};
+#endif
diff --git a/tools/ioemu/hw/m48t08.h b/tools/ioemu/hw/m48t08.h
new file mode 100644 (file)
index 0000000..9b44bc0
--- /dev/null
@@ -0,0 +1,12 @@
+#if !defined (__M48T08_H__)
+#define __M48T08_H__
+
+typedef struct m48t08_t m48t08_t;
+
+void m48t08_write (m48t08_t *NVRAM, uint32_t val);
+uint32_t m48t08_read (m48t08_t *NVRAM);
+void m48t08_set_addr (m48t08_t *NVRAM, uint32_t addr);
+void m48t08_toggle_lock (m48t08_t *NVRAM, int lock);
+m48t08_t *m48t08_init(uint32_t mem_base, uint16_t size, uint8_t *macaddr);
+
+#endif /* !defined (__M48T08_H__) */
diff --git a/tools/ioemu/hw/m48t59.c b/tools/ioemu/hw/m48t59.c
new file mode 100644 (file)
index 0000000..5ab5816
--- /dev/null
@@ -0,0 +1,602 @@
+/*
+ * QEMU M48T59 NVRAM emulation for PPC PREP platform
+ * 
+ * Copyright (c) 2003-2004 Jocelyn Mayer
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+#include "m48t59.h"
+
+//#define DEBUG_NVRAM
+
+#if defined(DEBUG_NVRAM)
+#define NVRAM_PRINTF(fmt, args...) do { printf(fmt , ##args); } while (0)
+#else
+#define NVRAM_PRINTF(fmt, args...) do { } while (0)
+#endif
+
+struct m48t59_t {
+    /* Hardware parameters */
+    int      IRQ;
+    int mem_index;
+    uint32_t mem_base;
+    uint32_t io_base;
+    uint16_t size;
+    /* RTC management */
+    time_t   time_offset;
+    time_t   stop_time;
+    /* Alarm & watchdog */
+    time_t   alarm;
+    struct QEMUTimer *alrm_timer;
+    struct QEMUTimer *wd_timer;
+    /* NVRAM storage */
+    uint8_t  lock;
+    uint16_t addr;
+    uint8_t *buffer;
+};
+
+/* Fake timer functions */
+/* Generic helpers for BCD */
+static inline uint8_t toBCD (uint8_t value)
+{
+    return (((value / 10) % 10) << 4) | (value % 10);
+}
+
+static inline uint8_t fromBCD (uint8_t BCD)
+{
+    return ((BCD >> 4) * 10) + (BCD & 0x0F);
+}
+
+/* RTC management helpers */
+static void get_time (m48t59_t *NVRAM, struct tm *tm)
+{
+    time_t t;
+
+    t = time(NULL) + NVRAM->time_offset;
+#ifdef _WIN32
+    memcpy(tm,localtime(&t),sizeof(*tm));
+#else
+    localtime_r (&t, tm) ;
+#endif
+}
+
+static void set_time (m48t59_t *NVRAM, struct tm *tm)
+{
+    time_t now, new_time;
+    
+    new_time = mktime(tm);
+    now = time(NULL);
+    NVRAM->time_offset = new_time - now;
+}
+
+/* Alarm management */
+static void alarm_cb (void *opaque)
+{
+    struct tm tm, tm_now;
+    uint64_t next_time;
+    m48t59_t *NVRAM = opaque;
+
+    pic_set_irq(NVRAM->IRQ, 1);
+    if ((NVRAM->buffer[0x1FF5] & 0x80) == 0 && 
+       (NVRAM->buffer[0x1FF4] & 0x80) == 0 &&
+       (NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
+       (NVRAM->buffer[0x1FF2] & 0x80) == 0) {
+       /* Repeat once a month */
+       get_time(NVRAM, &tm_now);
+       memcpy(&tm, &tm_now, sizeof(struct tm));
+       tm.tm_mon++;
+       if (tm.tm_mon == 13) {
+           tm.tm_mon = 1;
+           tm.tm_year++;
+       }
+       next_time = mktime(&tm);
+    } else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&
+              (NVRAM->buffer[0x1FF4] & 0x80) == 0 &&
+              (NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
+              (NVRAM->buffer[0x1FF2] & 0x80) == 0) {
+       /* Repeat once a day */
+       next_time = 24 * 60 * 60 + mktime(&tm_now);
+    } else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&
+              (NVRAM->buffer[0x1FF4] & 0x80) != 0 &&
+              (NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
+              (NVRAM->buffer[0x1FF2] & 0x80) == 0) {
+       /* Repeat once an hour */
+       next_time = 60 * 60 + mktime(&tm_now);
+    } else if ((NVRAM->buffer[0x1FF5] & 0x80) != 0 &&
+              (NVRAM->buffer[0x1FF4] & 0x80) != 0 &&
+              (NVRAM->buffer[0x1FF3] & 0x80) != 0 &&
+              (NVRAM->buffer[0x1FF2] & 0x80) == 0) {
+       /* Repeat once a minute */
+       next_time = 60 + mktime(&tm_now);
+    } else {
+       /* Repeat once a second */
+       next_time = 1 + mktime(&tm_now);
+    }
+    qemu_mod_timer(NVRAM->alrm_timer, next_time * 1000);
+    pic_set_irq(NVRAM->IRQ, 0);
+}
+
+
+static void get_alarm (m48t59_t *NVRAM, struct tm *tm)
+{
+#ifdef _WIN32
+    memcpy(tm,localtime(&NVRAM->alarm),sizeof(*tm));
+#else
+    localtime_r (&NVRAM->alarm, tm);
+#endif
+}
+
+static void set_alarm (m48t59_t *NVRAM, struct tm *tm)
+{
+    NVRAM->alarm = mktime(tm);
+    if (NVRAM->alrm_timer != NULL) {
+        qemu_del_timer(NVRAM->alrm_timer);
+       NVRAM->alrm_timer = NULL;
+    }
+    if (NVRAM->alarm - time(NULL) > 0)
+       qemu_mod_timer(NVRAM->alrm_timer, NVRAM->alarm * 1000);
+}
+
+/* Watchdog management */
+static void watchdog_cb (void *opaque)
+{
+    m48t59_t *NVRAM = opaque;
+
+    NVRAM->buffer[0x1FF0] |= 0x80;
+    if (NVRAM->buffer[0x1FF7] & 0x80) {
+       NVRAM->buffer[0x1FF7] = 0x00;
+       NVRAM->buffer[0x1FFC] &= ~0x40;
+        /* May it be a hw CPU Reset instead ? */
+        qemu_system_reset_request();
+    } else {
+       pic_set_irq(NVRAM->IRQ, 1);
+       pic_set_irq(NVRAM->IRQ, 0);
+    }
+}
+
+static void set_up_watchdog (m48t59_t *NVRAM, uint8_t value)
+{
+    uint64_t interval; /* in 1/16 seconds */
+
+    if (NVRAM->wd_timer != NULL) {
+        qemu_del_timer(NVRAM->wd_timer);
+       NVRAM->wd_timer = NULL;
+    }
+    NVRAM->buffer[0x1FF0] &= ~0x80;
+    if (value != 0) {
+       interval = (1 << (2 * (value & 0x03))) * ((value >> 2) & 0x1F);
+       qemu_mod_timer(NVRAM->wd_timer, ((uint64_t)time(NULL) * 1000) +
+                      ((interval * 1000) >> 4));
+    }
+}
+
+/* Direct access to NVRAM */
+void m48t59_write (m48t59_t *NVRAM, uint32_t val)
+{
+    struct tm tm;
+    int tmp;
+
+    if (NVRAM->addr > 0x1FF8 && NVRAM->addr < 0x2000)
+       NVRAM_PRINTF("%s: 0x%08x => 0x%08x\n", __func__, NVRAM->addr, val);
+    switch (NVRAM->addr) {
+    case 0x1FF0:
+        /* flags register : read-only */
+        break;
+    case 0x1FF1:
+        /* unused */
+        break;
+    case 0x1FF2:
+        /* alarm seconds */
+       tmp = fromBCD(val & 0x7F);
+       if (tmp >= 0 && tmp <= 59) {
+           get_alarm(NVRAM, &tm);
+           tm.tm_sec = tmp;
+           NVRAM->buffer[0x1FF2] = val;
+           set_alarm(NVRAM, &tm);
+       }
+        break;
+    case 0x1FF3:
+        /* alarm minutes */
+       tmp = fromBCD(val & 0x7F);
+       if (tmp >= 0 && tmp <= 59) {
+           get_alarm(NVRAM, &tm);
+           tm.tm_min = tmp;
+           NVRAM->buffer[0x1FF3] = val;
+           set_alarm(NVRAM, &tm);
+       }
+        break;
+    case 0x1FF4:
+        /* alarm hours */
+       tmp = fromBCD(val & 0x3F);
+       if (tmp >= 0 && tmp <= 23) {
+           get_alarm(NVRAM, &tm);
+           tm.tm_hour = tmp;
+           NVRAM->buffer[0x1FF4] = val;
+           set_alarm(NVRAM, &tm);
+       }
+        break;
+    case 0x1FF5:
+        /* alarm date */
+       tmp = fromBCD(val & 0x1F);
+       if (tmp != 0) {
+           get_alarm(NVRAM, &tm);
+           tm.tm_mday = tmp;
+           NVRAM->buffer[0x1FF5] = val;
+           set_alarm(NVRAM, &tm);
+       }
+        break;
+    case 0x1FF6:
+        /* interrupts */
+       NVRAM->buffer[0x1FF6] = val;
+        break;
+    case 0x1FF7:
+        /* watchdog */
+       NVRAM->buffer[0x1FF7] = val;
+       set_up_watchdog(NVRAM, val);
+        break;
+    case 0x1FF8:
+        /* control */
+       NVRAM->buffer[0x1FF8] = (val & ~0xA0) | 0x90;
+        break;
+    case 0x1FF9:
+        /* seconds (BCD) */
+       tmp = fromBCD(val & 0x7F);
+       if (tmp >= 0 && tmp <= 59) {
+           get_time(NVRAM, &tm);
+           tm.tm_sec = tmp;
+           set_time(NVRAM, &tm);
+       }
+       if ((val & 0x80) ^ (NVRAM->buffer[0x1FF9] & 0x80)) {
+           if (val & 0x80) {
+               NVRAM->stop_time = time(NULL);
+           } else {
+               NVRAM->time_offset += NVRAM->stop_time - time(NULL);
+               NVRAM->stop_time = 0;
+           }
+       }
+       NVRAM->buffer[0x1FF9] = val & 0x80;
+        break;
+    case 0x1FFA:
+        /* minutes (BCD) */
+       tmp = fromBCD(val & 0x7F);
+       if (tmp >= 0 && tmp <= 59) {
+           get_time(NVRAM, &tm);
+           tm.tm_min = tmp;
+           set_time(NVRAM, &tm);
+       }
+        break;
+    case 0x1FFB:
+        /* hours (BCD) */
+       tmp = fromBCD(val & 0x3F);
+       if (tmp >= 0 && tmp <= 23) {
+           get_time(NVRAM, &tm);
+           tm.tm_hour = tmp;
+           set_time(NVRAM, &tm);
+       }
+        break;
+    case 0x1FFC:
+        /* day of the week / century */
+       tmp = fromBCD(val & 0x07);
+       get_time(NVRAM, &tm);
+       tm.tm_wday = tmp;
+       set_time(NVRAM, &tm);
+        NVRAM->buffer[0x1FFC] = val & 0x40;
+        break;
+    case 0x1FFD:
+        /* date */
+       tmp = fromBCD(val & 0x1F);
+       if (tmp != 0) {
+           get_time(NVRAM, &tm);
+           tm.tm_mday = tmp;
+           set_time(NVRAM, &tm);
+       }
+        break;
+    case 0x1FFE:
+        /* month */
+       tmp = fromBCD(val & 0x1F);
+       if (tmp >= 1 && tmp <= 12) {
+           get_time(NVRAM, &tm);
+           tm.tm_mon = tmp - 1;
+           set_time(NVRAM, &tm);
+       }
+        break;
+    case 0x1FFF:
+        /* year */
+       tmp = fromBCD(val);
+       if (tmp >= 0 && tmp <= 99) {
+           get_time(NVRAM, &tm);
+           tm.tm_year = fromBCD(val);
+           set_time(NVRAM, &tm);
+       }
+        break;
+    default:
+        /* Check lock registers state */
+        if (NVRAM->addr >= 0x20 && NVRAM->addr <= 0x2F && (NVRAM->lock & 1))
+            break;
+        if (NVRAM->addr >= 0x30 && NVRAM->addr <= 0x3F && (NVRAM->lock & 2))
+            break;
+        if (NVRAM->addr < 0x1FF0 ||
+           (NVRAM->addr > 0x1FFF && NVRAM->addr < NVRAM->size)) {
+            NVRAM->buffer[NVRAM->addr] = val & 0xFF;
+       }
+        break;
+    }
+}
+
+uint32_t m48t59_read (m48t59_t *NVRAM)
+{
+    struct tm tm;
+    uint32_t retval = 0xFF;
+
+    switch (NVRAM->addr) {
+    case 0x1FF0:
+        /* flags register */
+       goto do_read;
+    case 0x1FF1:
+        /* unused */
+       retval = 0;
+        break;
+    case 0x1FF2:
+        /* alarm seconds */
+       goto do_read;
+    case 0x1FF3:
+        /* alarm minutes */
+       goto do_read;
+    case 0x1FF4:
+        /* alarm hours */
+       goto do_read;
+    case 0x1FF5:
+        /* alarm date */
+       goto do_read;
+    case 0x1FF6:
+        /* interrupts */
+       goto do_read;
+    case 0x1FF7:
+       /* A read resets the watchdog */
+       set_up_watchdog(NVRAM, NVRAM->buffer[0x1FF7]);
+       goto do_read;
+    case 0x1FF8:
+        /* control */
+       goto do_read;
+    case 0x1FF9:
+        /* seconds (BCD) */
+        get_time(NVRAM, &tm);
+        retval = (NVRAM->buffer[0x1FF9] & 0x80) | toBCD(tm.tm_sec);
+        break;
+    case 0x1FFA:
+        /* minutes (BCD) */
+        get_time(NVRAM, &tm);
+        retval = toBCD(tm.tm_min);
+        break;
+    case 0x1FFB:
+        /* hours (BCD) */
+        get_time(NVRAM, &tm);
+        retval = toBCD(tm.tm_hour);
+        break;
+    case 0x1FFC:
+        /* day of the week / century */
+        get_time(NVRAM, &tm);
+        retval = NVRAM->buffer[0x1FFC] | tm.tm_wday;
+        break;
+    case 0x1FFD:
+        /* date */
+        get_time(NVRAM, &tm);
+        retval = toBCD(tm.tm_mday);
+        break;
+    case 0x1FFE:
+        /* month */
+        get_time(NVRAM, &tm);
+        retval = toBCD(tm.tm_mon + 1);
+        break;
+    case 0x1FFF:
+        /* year */
+        get_time(NVRAM, &tm);
+        retval = toBCD(tm.tm_year);
+        break;
+    default:
+        /* Check lock registers state */
+        if (NVRAM->addr >= 0x20 && NVRAM->addr <= 0x2F && (NVRAM->lock & 1))
+            break;
+        if (NVRAM->addr >= 0x30 && NVRAM->addr <= 0x3F && (NVRAM->lock & 2))
+            break;
+        if (NVRAM->addr < 0x1FF0 ||
+           (NVRAM->addr > 0x1FFF && NVRAM->addr < NVRAM->size)) {
+       do_read:
+            retval = NVRAM->buffer[NVRAM->addr];
+       }
+        break;
+    }
+    if (NVRAM->addr > 0x1FF9 && NVRAM->addr < 0x2000)
+       NVRAM_PRINTF("0x%08x <= 0x%08x\n", NVRAM->addr, retval);
+
+    return retval;
+}
+
+void m48t59_set_addr (m48t59_t *NVRAM, uint32_t addr)
+{
+    NVRAM->addr = addr;
+}
+
+void m48t59_toggle_lock (m48t59_t *NVRAM, int lock)
+{
+    NVRAM->lock ^= 1 << lock;
+}
+
+/* IO access to NVRAM */
+static void NVRAM_writeb (void *opaque, uint32_t addr, uint32_t val)
+{
+    m48t59_t *NVRAM = opaque;
+
+    addr -= NVRAM->io_base;
+    NVRAM_PRINTF("0x%08x => 0x%08x\n", addr, val);
+    switch (addr) {
+    case 0:
+        NVRAM->addr &= ~0x00FF;
+        NVRAM->addr |= val;
+        break;
+    case 1:
+        NVRAM->addr &= ~0xFF00;
+        NVRAM->addr |= val << 8;
+        break;
+    case 3:
+        m48t59_write(NVRAM, val);
+        NVRAM->addr = 0x0000;
+        break;
+    default:
+        break;
+    }
+}
+
+static uint32_t NVRAM_readb (void *opaque, uint32_t addr)
+{
+    m48t59_t *NVRAM = opaque;
+    uint32_t retval;
+
+    addr -= NVRAM->io_base;
+    switch (addr) {
+    case 3:
+        retval = m48t59_read(NVRAM);
+        break;
+    default:
+        retval = -1;
+        break;
+    }
+    NVRAM_PRINTF("0x%08x <= 0x%08x\n", addr, retval);
+
+    return retval;
+}
+
+static void nvram_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
+{
+    m48t59_t *NVRAM = opaque;
+    
+    addr -= NVRAM->mem_base;
+    if (addr < 0x1FF0)
+        NVRAM->buffer[addr] = value;
+}
+
+static void nvram_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
+{
+    m48t59_t *NVRAM = opaque;
+    
+    addr -= NVRAM->mem_base;
+    if (addr < 0x1FF0) {
+        NVRAM->buffer[addr] = value >> 8;
+        NVRAM->buffer[addr + 1] = value;
+    }
+}
+
+static void nvram_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
+{
+    m48t59_t *NVRAM = opaque;
+    
+    addr -= NVRAM->mem_base;
+    if (addr < 0x1FF0) {
+        NVRAM->buffer[addr] = value >> 24;
+        NVRAM->buffer[addr + 1] = value >> 16;
+        NVRAM->buffer[addr + 2] = value >> 8;
+        NVRAM->buffer[addr + 3] = value;
+    }
+}
+
+static uint32_t nvram_readb (void *opaque, target_phys_addr_t addr)
+{
+    m48t59_t *NVRAM = opaque;
+    uint32_t retval = 0;
+    
+    addr -= NVRAM->mem_base;
+    if (addr < 0x1FF0)
+        retval = NVRAM->buffer[addr];
+
+    return retval;
+}
+
+static uint32_t nvram_readw (void *opaque, target_phys_addr_t addr)
+{
+    m48t59_t *NVRAM = opaque;
+    uint32_t retval = 0;
+    
+    addr -= NVRAM->mem_base;
+    if (addr < 0x1FF0) {
+        retval = NVRAM->buffer[addr] << 8;
+        retval |= NVRAM->buffer[addr + 1];
+    }
+
+    return retval;
+}
+
+static uint32_t nvram_readl (void *opaque, target_phys_addr_t addr)
+{
+    m48t59_t *NVRAM = opaque;
+    uint32_t retval = 0;
+    
+    addr -= NVRAM->mem_base;
+    if (addr < 0x1FF0) {
+        retval = NVRAM->buffer[addr] << 24;
+        retval |= NVRAM->buffer[addr + 1] << 16;
+        retval |= NVRAM->buffer[addr + 2] << 8;
+        retval |= NVRAM->buffer[addr + 3];
+    }
+
+    return retval;
+}
+
+static CPUWriteMemoryFunc *nvram_write[] = {
+    &nvram_writeb,
+    &nvram_writew,
+    &nvram_writel,
+};
+
+static CPUReadMemoryFunc *nvram_read[] = {
+    &nvram_readb,
+    &nvram_readw,
+    &nvram_readl,
+};
+/* Initialisation routine */
+m48t59_t *m48t59_init (int IRQ, uint32_t mem_base,
+                       uint32_t io_base, uint16_t size)
+{
+    m48t59_t *s;
+
+    s = qemu_mallocz(sizeof(m48t59_t));
+    if (!s)
+       return NULL;
+    s->buffer = qemu_mallocz(size);
+    if (!s->buffer) {
+        qemu_free(s);
+        return NULL;
+    }
+    s->IRQ = IRQ;
+    s->size = size;
+    s->mem_base = mem_base;
+    s->io_base = io_base;
+    s->addr = 0;
+    register_ioport_read(io_base, 0x04, 1, NVRAM_readb, s);
+    register_ioport_write(io_base, 0x04, 1, NVRAM_writeb, s);
+    if (mem_base != 0) {
+        s->mem_index = cpu_register_io_memory(0, nvram_read, nvram_write, s);
+        cpu_register_physical_memory(mem_base, 0x4000, s->mem_index);
+    }
+    s->alrm_timer = qemu_new_timer(vm_clock, &alarm_cb, s);
+    s->wd_timer = qemu_new_timer(vm_clock, &watchdog_cb, s);
+    s->lock = 0;
+
+    return s;
+}
diff --git a/tools/ioemu/hw/m48t59.h b/tools/ioemu/hw/m48t59.h
new file mode 100644 (file)
index 0000000..03d8ea3
--- /dev/null
@@ -0,0 +1,13 @@
+#if !defined (__M48T59_H__)
+#define __M48T59_H__
+
+typedef struct m48t59_t m48t59_t;
+
+void m48t59_write (m48t59_t *NVRAM, uint32_t val);
+uint32_t m48t59_read (m48t59_t *NVRAM);
+void m48t59_set_addr (m48t59_t *NVRAM, uint32_t addr);
+void m48t59_toggle_lock (m48t59_t *NVRAM, int lock);
+m48t59_t *m48t59_init (int IRQ, uint32_t io_base,
+                       uint32_t mem_base, uint16_t size);
+
+#endif /* !defined (__M48T59_H__) */
diff --git a/tools/ioemu/hw/magic-load.c b/tools/ioemu/hw/magic-load.c
new file mode 100644 (file)
index 0000000..06a5f74
--- /dev/null
@@ -0,0 +1,326 @@
+#include "vl.h"
+#include "disas.h"
+
+#define ELF_CLASS   ELFCLASS32
+#define ELF_DATA    ELFDATA2MSB
+#define ELF_ARCH    EM_SPARC
+
+#include "elf.h"
+
+#ifdef BSWAP_NEEDED
+static void bswap_ehdr(Elf32_Ehdr *ehdr)
+{
+    bswap16s(&ehdr->e_type);                   /* Object file type */
+    bswap16s(&ehdr->e_machine);                /* Architecture */
+    bswap32s(&ehdr->e_version);                /* Object file version */
+    bswap32s(&ehdr->e_entry);          /* Entry point virtual address */
+    bswap32s(&ehdr->e_phoff);          /* Program header table file offset */
+    bswap32s(&ehdr->e_shoff);          /* Section header table file offset */
+    bswap32s(&ehdr->e_flags);          /* Processor-specific flags */
+    bswap16s(&ehdr->e_ehsize);         /* ELF header size in bytes */
+    bswap16s(&ehdr->e_phentsize);              /* Program header table entry size */
+    bswap16s(&ehdr->e_phnum);          /* Program header table entry count */
+    bswap16s(&ehdr->e_shentsize);              /* Section header table entry size */
+    bswap16s(&ehdr->e_shnum);          /* Section header table entry count */
+    bswap16s(&ehdr->e_shstrndx);               /* Section header string table index */
+}
+
+static void bswap_phdr(Elf32_Phdr *phdr)
+{
+    bswap32s(&phdr->p_type);                   /* Segment type */
+    bswap32s(&phdr->p_offset);         /* Segment file offset */
+    bswap32s(&phdr->p_vaddr);          /* Segment virtual address */
+    bswap32s(&phdr->p_paddr);          /* Segment physical address */
+    bswap32s(&phdr->p_filesz);         /* Segment size in file */
+    bswap32s(&phdr->p_memsz);          /* Segment size in memory */
+    bswap32s(&phdr->p_flags);          /* Segment flags */
+    bswap32s(&phdr->p_align);          /* Segment alignment */
+}
+
+static void bswap_shdr(Elf32_Shdr *shdr)
+{
+    bswap32s(&shdr->sh_name);
+    bswap32s(&shdr->sh_type);
+    bswap32s(&shdr->sh_flags);
+    bswap32s(&shdr->sh_addr);
+    bswap32s(&shdr->sh_offset);
+    bswap32s(&shdr->sh_size);
+    bswap32s(&shdr->sh_link);
+    bswap32s(&shdr->sh_info);
+    bswap32s(&shdr->sh_addralign);
+    bswap32s(&shdr->sh_entsize);
+}
+
+static void bswap_sym(Elf32_Sym *sym)
+{
+    bswap32s(&sym->st_name);
+    bswap32s(&sym->st_value);
+    bswap32s(&sym->st_size);
+    bswap16s(&sym->st_shndx);
+}
+#else
+#define bswap_ehdr(e) do { } while (0)
+#define bswap_phdr(e) do { } while (0)
+#define bswap_shdr(e) do { } while (0)
+#define bswap_sym(e) do { } while (0)
+#endif
+
+static int find_phdr(struct elfhdr *ehdr, int fd, struct elf_phdr *phdr, uint32_t type)
+{
+    int i, retval;
+
+    retval = lseek(fd, ehdr->e_phoff, SEEK_SET);
+    if (retval < 0)
+       return -1;
+
+    for (i = 0; i < ehdr->e_phnum; i++) {
+       retval = read(fd, phdr, sizeof(*phdr));
+       if (retval < 0)
+           return -1;
+       bswap_phdr(phdr);
+       if (phdr->p_type == type)
+           return 0;
+    }
+    return -1;
+}
+
+static void *find_shdr(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, uint32_t type)
+{
+    int i, retval;
+
+    retval = lseek(fd, ehdr->e_shoff, SEEK_SET);
+    if (retval < 0)
+       return NULL;
+
+    for (i = 0; i < ehdr->e_shnum; i++) {
+       retval = read(fd, shdr, sizeof(*shdr));
+       if (retval < 0)
+           return NULL;
+       bswap_shdr(shdr);
+       if (shdr->sh_type == type)
+           return qemu_malloc(shdr->sh_size);
+    }
+    return NULL;
+}
+
+static int find_strtab(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, struct elf_shdr *symtab)
+{
+    int retval;
+
+    retval = lseek(fd, ehdr->e_shoff + sizeof(struct elf_shdr) * symtab->sh_link, SEEK_SET);
+    if (retval < 0)
+       return -1;
+
+    retval = read(fd, shdr, sizeof(*shdr));
+    if (retval < 0)
+       return -1;
+    bswap_shdr(shdr);
+    if (shdr->sh_type == SHT_STRTAB)
+       return qemu_malloc(shdr->sh_size);;
+    return 0;
+}
+
+static int read_program(int fd, struct elf_phdr *phdr, void *dst)
+{
+    int retval;
+    retval = lseek(fd, 0x4000, SEEK_SET);
+    if (retval < 0)
+       return -1;
+    return read(fd, dst, phdr->p_filesz);
+}
+
+static int read_section(int fd, struct elf_shdr *s, void *dst)
+{
+    int retval;
+
+    retval = lseek(fd, s->sh_offset, SEEK_SET);
+    if (retval < 0)
+       return -1;
+    retval = read(fd, dst, s->sh_size);
+    if (retval < 0)
+       return -1;
+    return 0;
+}
+
+static void *process_section(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, uint32_t type)
+{
+    void *dst;
+
+    dst = find_shdr(ehdr, fd, shdr, type);
+    if (!dst)
+       goto error;
+
+    if (read_section(fd, shdr, dst))
+       goto error;
+    return dst;
+ error:
+    qemu_free(dst);
+    return NULL;
+}
+
+static void *process_strtab(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, struct elf_shdr *symtab)
+{
+    void *dst;
+
+    dst = find_strtab(ehdr, fd, shdr, symtab);
+    if (!dst)
+       goto error;
+
+    if (read_section(fd, shdr, dst))
+       goto error;
+    return dst;
+ error:
+    qemu_free(dst);
+    return NULL;
+}
+
+static void load_symbols(struct elfhdr *ehdr, int fd)
+{
+    struct elf_shdr symtab, strtab;
+    struct elf_sym *syms;
+    int nsyms, i;
+    char *str;
+
+    /* Symbol table */
+    syms = process_section(ehdr, fd, &symtab, SHT_SYMTAB);
+    if (!syms)
+       return;
+
+    nsyms = symtab.sh_size / sizeof(struct elf_sym);
+    for (i = 0; i < nsyms; i++)
+       bswap_sym(&syms[i]);
+
+    /* String table */
+    str = process_strtab(ehdr, fd, &strtab, &symtab);
+    if (!str)
+       goto error_freesyms;
+
+    /* Commit */
+    if (disas_symtab)
+       qemu_free(disas_symtab); /* XXX Merge with old symbols? */
+    if (disas_strtab)
+       qemu_free(disas_strtab);
+    disas_symtab = syms;
+    disas_num_syms = nsyms;
+    disas_strtab = str;
+    return;
+ error_freesyms:
+    qemu_free(syms);
+    return;
+}
+
+int load_elf(const char * filename, uint8_t *addr)
+{
+    struct elfhdr ehdr;
+    struct elf_phdr phdr;
+    int retval, fd;
+
+    fd = open(filename, O_RDONLY | O_BINARY);
+    if (fd < 0)
+       goto error;
+
+    retval = read(fd, &ehdr, sizeof(ehdr));
+    if (retval < 0)
+       goto error;
+
+    bswap_ehdr(&ehdr);
+
+    if (ehdr.e_ident[0] != 0x7f || ehdr.e_ident[1] != 'E'
+       || ehdr.e_ident[2] != 'L' || ehdr.e_ident[3] != 'F'
+       || ehdr.e_machine != EM_SPARC)
+       goto error;
+
+    if (find_phdr(&ehdr, fd, &phdr, PT_LOAD))
+       goto error;
+    retval = read_program(fd, &phdr, addr);
+    if (retval < 0)
+       goto error;
+
+    load_symbols(&ehdr, fd);
+
+    close(fd);
+    return retval;
+ error:
+    close(fd);
+    return -1;
+}
+
+int load_kernel(const char *filename, uint8_t *addr)
+{
+    int fd, size;
+
+    fd = open(filename, O_RDONLY | O_BINARY);
+    if (fd < 0)
+        return -1;
+    /* load 32 bit code */
+    size = read(fd, addr, 16 * 1024 * 1024);
+    if (size < 0)
+        goto fail;
+    close(fd);
+    return size;
+ fail:
+    close(fd);
+    return -1;
+}
+
+typedef struct MAGICState {
+    uint32_t addr;
+    uint32_t saved_addr;
+    int magic_state;
+    char saved_kfn[1024];
+} MAGICState;
+
+static uint32_t magic_mem_readl(void *opaque, target_phys_addr_t addr)
+{
+    int ret;
+    MAGICState *s = opaque;
+
+    if (s->magic_state == 0) {
+        ret = load_elf(s->saved_kfn, (uint8_t *)s->saved_addr);
+       if (ret < 0)
+           ret = load_kernel(s->saved_kfn, (uint8_t *)s->saved_addr);
+        if (ret < 0) {
+            fprintf(stderr, "qemu: could not load kernel '%s'\n", 
+                    s->saved_kfn);
+        }
+       s->magic_state = 1; /* No more magic */
+       tb_flush();
+       return bswap32(ret);
+    }
+    return 0;
+}
+
+static void magic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
+{
+}
+
+
+static CPUReadMemoryFunc *magic_mem_read[3] = {
+    magic_mem_readl,
+    magic_mem_readl,
+    magic_mem_readl,
+};
+
+static CPUWriteMemoryFunc *magic_mem_write[3] = {
+    magic_mem_writel,
+    magic_mem_writel,
+    magic_mem_writel,
+};
+
+void magic_init(const char *kfn, int kloadaddr, uint32_t addr)
+{
+    int magic_io_memory;
+    MAGICState *s;
+
+    s = qemu_mallocz(sizeof(MAGICState));
+    if (!s)
+        return;
+
+    strcpy(s->saved_kfn, kfn);
+    s->saved_addr = kloadaddr;
+    s->magic_state = 0;
+    s->addr = addr;
+    magic_io_memory = cpu_register_io_memory(0, magic_mem_read, magic_mem_write, s);
+    cpu_register_physical_memory(addr, 4, magic_io_memory);
+}
+
diff --git a/tools/ioemu/hw/mc146818rtc.c b/tools/ioemu/hw/mc146818rtc.c
new file mode 100644 (file)
index 0000000..9d4cbed
--- /dev/null
@@ -0,0 +1,463 @@
+/*
+ * QEMU MC146818 RTC emulation
+ * 
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+
+//#define DEBUG_CMOS
+
+#define RTC_SECONDS             0
+#define RTC_SECONDS_ALARM       1
+#define RTC_MINUTES             2
+#define RTC_MINUTES_ALARM       3
+#define RTC_HOURS               4
+#define RTC_HOURS_ALARM         5
+#define RTC_ALARM_DONT_CARE    0xC0
+
+#define RTC_DAY_OF_WEEK         6
+#define RTC_DAY_OF_MONTH        7
+#define RTC_MONTH               8
+#define RTC_YEAR                9
+
+#define RTC_REG_A               10
+#define RTC_REG_B               11
+#define RTC_REG_C               12
+#define RTC_REG_D               13
+
+#define REG_A_UIP 0x80
+
+#define REG_B_SET 0x80
+#define REG_B_PIE 0x40
+#define REG_B_AIE 0x20
+#define REG_B_UIE 0x10
+
+struct RTCState {
+    uint8_t cmos_data[128];
+    uint8_t cmos_index;
+    struct tm current_tm;
+    int irq;
+    /* periodic timer */
+    QEMUTimer *periodic_timer;
+    int64_t next_periodic_time;
+    /* second update */
+    int64_t next_second_time;
+    QEMUTimer *second_timer;
+    QEMUTimer *second_timer2;
+};
+
+static void rtc_set_time(RTCState *s);
+static void rtc_copy_date(RTCState *s);
+
+static void rtc_timer_update(RTCState *s, int64_t current_time)
+{
+    int period_code, period;
+    int64_t cur_clock, next_irq_clock;
+
+    period_code = s->cmos_data[RTC_REG_A] & 0x0f;
+    if (period_code != 0 && 
+        (s->cmos_data[RTC_REG_B] & REG_B_PIE)) {
+        if (period_code <= 2)
+            period_code += 7;
+        /* period in 32 Khz cycles */
+        period = 1 << (period_code - 1);
+        /* compute 32 khz clock */
+        cur_clock = muldiv64(current_time, 32768, ticks_per_sec);
+        next_irq_clock = (cur_clock & ~(period - 1)) + period;
+        s->next_periodic_time = muldiv64(next_irq_clock, ticks_per_sec, 32768) + 1;
+        qemu_mod_timer(s->periodic_timer, s->next_periodic_time);
+    } else {
+        qemu_del_timer(s->periodic_timer);
+    }
+}
+
+static void rtc_periodic_timer(void *opaque)
+{
+    RTCState *s = opaque;
+
+    rtc_timer_update(s, s->next_periodic_time);
+    s->cmos_data[RTC_REG_C] |= 0xc0;
+    pic_set_irq(s->irq, 1);
+}
+
+static void cmos_ioport_write(void *opaque, uint32_t addr, uint32_t data)
+{
+    RTCState *s = opaque;
+
+    if ((addr & 1) == 0) {
+        s->cmos_index = data & 0x7f;
+    } else {
+#ifdef DEBUG_CMOS
+        printf("cmos: write index=0x%02x val=0x%02x\n",
+               s->cmos_index, data);
+#endif        
+        switch(s->cmos_index) {
+        case RTC_SECONDS_ALARM:
+        case RTC_MINUTES_ALARM:
+        case RTC_HOURS_ALARM:
+            /* XXX: not supported */
+            s->cmos_data[s->cmos_index] = data;
+            break;
+        case RTC_SECONDS:
+        case RTC_MINUTES:
+        case RTC_HOURS:
+        case RTC_DAY_OF_WEEK:
+        case RTC_DAY_OF_MONTH:
+        case RTC_MONTH:
+        case RTC_YEAR:
+            s->cmos_data[s->cmos_index] = data;
+            /* if in set mode, do not update the time */
+            if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
+                rtc_set_time(s);
+            }
+            break;
+        case RTC_REG_A:
+            /* UIP bit is read only */
+            s->cmos_data[RTC_REG_A] = (data & ~REG_A_UIP) |
+                (s->cmos_data[RTC_REG_A] & REG_A_UIP);
+            rtc_timer_update(s, qemu_get_clock(vm_clock));
+            break;
+        case RTC_REG_B:
+            if (data & REG_B_SET) {
+                /* set mode: reset UIP mode */
+                s->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
+                data &= ~REG_B_UIE;
+            } else {
+                /* if disabling set mode, update the time */
+                if (s->cmos_data[RTC_REG_B] & REG_B_SET) {
+                    rtc_set_time(s);
+                }
+            }
+            s->cmos_data[RTC_REG_B] = data;
+            rtc_timer_update(s, qemu_get_clock(vm_clock));
+            break;
+        case RTC_REG_C:
+        case RTC_REG_D:
+            /* cannot write to them */
+            break;
+        default:
+            s->cmos_data[s->cmos_index] = data;
+            break;
+        }
+    }
+}
+
+static inline int to_bcd(RTCState *s, int a)
+{
+    if (s->cmos_data[RTC_REG_B] & 0x04) {
+        return a;
+    } else {
+        return ((a / 10) << 4) | (a % 10);
+    }
+}
+
+static inline int from_bcd(RTCState *s, int a)
+{
+    if (s->cmos_data[RTC_REG_B] & 0x04) {
+        return a;
+    } else {
+        return ((a >> 4) * 10) + (a & 0x0f);
+    }
+}
+
+static void rtc_set_time(RTCState *s)
+{
+    struct tm *tm = &s->current_tm;
+
+    tm->tm_sec = from_bcd(s, s->cmos_data[RTC_SECONDS]);
+    tm->tm_min = from_bcd(s, s->cmos_data[RTC_MINUTES]);
+    tm->tm_hour = from_bcd(s, s->cmos_data[RTC_HOURS] & 0x7f);
+    if (!(s->cmos_data[RTC_REG_B] & 0x02) &&
+        (s->cmos_data[RTC_HOURS] & 0x80)) {
+        tm->tm_hour += 12;
+    }
+    tm->tm_wday = from_bcd(s, s->cmos_data[RTC_DAY_OF_WEEK]);
+    tm->tm_mday = from_bcd(s, s->cmos_data[RTC_DAY_OF_MONTH]);
+    tm->tm_mon = from_bcd(s, s->cmos_data[RTC_MONTH]) - 1;
+    tm->tm_year = from_bcd(s, s->cmos_data[RTC_YEAR]) + 100;
+}
+
+static void rtc_copy_date(RTCState *s)
+{
+    const struct tm *tm = &s->current_tm;
+
+    s->cmos_data[RTC_SECONDS] = to_bcd(s, tm->tm_sec);
+    s->cmos_data[RTC_MINUTES] = to_bcd(s, tm->tm_min);
+    if (s->cmos_data[RTC_REG_B] & 0x02) {
+        /* 24 hour format */
+        s->cmos_data[RTC_HOURS] = to_bcd(s, tm->tm_hour);
+    } else {
+        /* 12 hour format */
+        s->cmos_data[RTC_HOURS] = to_bcd(s, tm->tm_hour % 12);
+        if (tm->tm_hour >= 12)
+            s->cmos_data[RTC_HOURS] |= 0x80;
+    }
+    s->cmos_data[RTC_DAY_OF_WEEK] = to_bcd(s, tm->tm_wday);
+    s->cmos_data[RTC_DAY_OF_MONTH] = to_bcd(s, tm->tm_mday);
+    s->cmos_data[RTC_MONTH] = to_bcd(s, tm->tm_mon + 1);
+    s->cmos_data[RTC_YEAR] = to_bcd(s, tm->tm_year % 100);
+}
+
+/* month is between 0 and 11. */
+static int get_days_in_month(int month, int year)
+{
+    static const int days_tab[12] = { 
+        31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 
+    };
+    int d;
+    if ((unsigned )month >= 12)
+        return 31;
+    d = days_tab[month];
+    if (month == 1) {
+        if ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0))
+            d++;
+    }
+    return d;
+}
+
+/* update 'tm' to the next second */
+static void rtc_next_second(struct tm *tm)
+{
+    int days_in_month;
+
+    tm->tm_sec++;
+    if ((unsigned)tm->tm_sec >= 60) {
+        tm->tm_sec = 0;
+        tm->tm_min++;
+        if ((unsigned)tm->tm_min >= 60) {
+            tm->tm_min = 0;
+            tm->tm_hour++;
+            if ((unsigned)tm->tm_hour >= 24) {
+                tm->tm_hour = 0;
+                /* next day */
+                tm->tm_wday++;
+                if ((unsigned)tm->tm_wday >= 7)
+                    tm->tm_wday = 0;
+                days_in_month = get_days_in_month(tm->tm_mon, 
+                                                  tm->tm_year + 1900);
+                tm->tm_mday++;
+                if (tm->tm_mday < 1) {
+                    tm->tm_mday = 1;
+                } else if (tm->tm_mday > days_in_month) {
+                    tm->tm_mday = 1;
+                    tm->tm_mon++;
+                    if (tm->tm_mon >= 12) {
+                        tm->tm_mon = 0;
+                        tm->tm_year++;
+                    }
+                }
+            }
+        }
+    }
+}
+
+
+static void rtc_update_second(void *opaque)
+{
+    RTCState *s = opaque;
+    int64_t delay;
+
+    /* if the oscillator is not in normal operation, we do not update */
+    if ((s->cmos_data[RTC_REG_A] & 0x70) != 0x20) {
+        s->next_second_time += ticks_per_sec;
+        qemu_mod_timer(s->second_timer, s->next_second_time);
+    } else {
+        rtc_next_second(&s->current_tm);
+        
+        if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
+            /* update in progress bit */
+            s->cmos_data[RTC_REG_A] |= REG_A_UIP;
+        }
+        /* should be 244 us = 8 / 32768 seconds, but currently the
+           timers do not have the necessary resolution. */
+        delay = (ticks_per_sec * 1) / 100;
+        if (delay < 1)
+            delay = 1;
+        qemu_mod_timer(s->second_timer2, 
+                       s->next_second_time + delay);
+    }
+}
+
+static void rtc_update_second2(void *opaque)
+{
+    RTCState *s = opaque;
+
+    if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) {
+        rtc_copy_date(s);
+    }
+
+    /* check alarm */
+    if (s->cmos_data[RTC_REG_B] & REG_B_AIE) {
+        if (((s->cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0 ||
+             s->cmos_data[RTC_SECONDS_ALARM] == s->current_tm.tm_sec) &&
+            ((s->cmos_data[RTC_MINUTES_ALARM] & 0xc0) == 0xc0 ||
+             s->cmos_data[RTC_MINUTES_ALARM] == s->current_tm.tm_mon) &&
+            ((s->cmos_data[RTC_HOURS_ALARM] & 0xc0) == 0xc0 ||
+             s->cmos_data[RTC_HOURS_ALARM] == s->current_tm.tm_hour)) {
+
+            s->cmos_data[RTC_REG_C] |= 0xa0; 
+            pic_set_irq(s->irq, 1);
+        }
+    }
+
+    /* update ended interrupt */
+    if (s->cmos_data[RTC_REG_B] & REG_B_UIE) {
+        s->cmos_data[RTC_REG_C] |= 0x90; 
+        pic_set_irq(s->irq, 1);
+    }
+
+    /* clear update in progress bit */
+    s->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
+
+    s->next_second_time += ticks_per_sec;
+    qemu_mod_timer(s->second_timer, s->next_second_time);
+}
+
+static uint32_t cmos_ioport_read(void *opaque, uint32_t addr)
+{
+    RTCState *s = opaque;
+    int ret;
+    if ((addr & 1) == 0) {
+        return 0xff;
+    } else {
+        switch(s->cmos_index) {
+        case RTC_SECONDS:
+        case RTC_MINUTES:
+        case RTC_HOURS:
+        case RTC_DAY_OF_WEEK:
+        case RTC_DAY_OF_MONTH:
+        case RTC_MONTH:
+        case RTC_YEAR:
+            ret = s->cmos_data[s->cmos_index];
+            break;
+        case RTC_REG_A:
+            ret = s->cmos_data[s->cmos_index];
+            break;
+        case RTC_REG_C:
+            ret = s->cmos_data[s->cmos_index];
+            pic_set_irq(s->irq, 0);
+            s->cmos_data[RTC_REG_C] = 0x00; 
+            break;
+        default:
+            ret = s->cmos_data[s->cmos_index];
+            break;
+        }
+#ifdef DEBUG_CMOS
+        printf("cmos: read index=0x%02x val=0x%02x\n",
+               s->cmos_index, ret);
+#endif
+        return ret;
+    }
+}
+
+void rtc_set_memory(RTCState *s, int addr, int val)
+{
+    if (addr >= 0 && addr <= 127)
+        s->cmos_data[addr] = val;
+}
+
+void rtc_set_date(RTCState *s, const struct tm *tm)
+{
+    s->current_tm = *tm;
+    rtc_copy_date(s);
+}
+
+static void rtc_save(QEMUFile *f, void *opaque)
+{
+    RTCState *s = opaque;
+
+    qemu_put_buffer(f, s->cmos_data, 128);
+    qemu_put_8s(f, &s->cmos_index);
+    
+    qemu_put_be32s(f, &s->current_tm.tm_sec);
+    qemu_put_be32s(f, &s->current_tm.tm_min);
+    qemu_put_be32s(f, &s->current_tm.tm_hour);
+    qemu_put_be32s(f, &s->current_tm.tm_wday);
+    qemu_put_be32s(f, &s->current_tm.tm_mday);
+    qemu_put_be32s(f, &s->current_tm.tm_mon);
+    qemu_put_be32s(f, &s->current_tm.tm_year);
+
+    qemu_put_timer(f, s->periodic_timer);
+    qemu_put_be64s(f, &s->next_periodic_time);
+
+    qemu_put_be64s(f, &s->next_second_time);
+    qemu_put_timer(f, s->second_timer);
+    qemu_put_timer(f, s->second_timer2);
+}
+
+static int rtc_load(QEMUFile *f, void *opaque, int version_id)
+{
+    RTCState *s = opaque;
+
+    if (version_id != 1)
+        return -EINVAL;
+
+    qemu_get_buffer(f, s->cmos_data, 128);
+    qemu_get_8s(f, &s->cmos_index);
+
+    qemu_get_be32s(f, &s->current_tm.tm_sec);
+    qemu_get_be32s(f, &s->current_tm.tm_min);
+    qemu_get_be32s(f, &s->current_tm.tm_hour);
+    qemu_get_be32s(f, &s->current_tm.tm_wday);
+    qemu_get_be32s(f, &s->current_tm.tm_mday);
+    qemu_get_be32s(f, &s->current_tm.tm_mon);
+    qemu_get_be32s(f, &s->current_tm.tm_year);
+
+    qemu_get_timer(f, s->periodic_timer);
+    qemu_get_be64s(f, &s->next_periodic_time);
+
+    qemu_get_be64s(f, &s->next_second_time);
+    qemu_get_timer(f, s->second_timer);
+    qemu_get_timer(f, s->second_timer2);
+    return 0;
+}
+
+RTCState *rtc_init(int base, int irq)
+{
+    RTCState *s;
+
+    s = qemu_mallocz(sizeof(RTCState));
+    if (!s)
+        return NULL;
+
+    s->irq = irq;
+    s->cmos_data[RTC_REG_A] = 0x26;
+    s->cmos_data[RTC_REG_B] = 0x02;
+    s->cmos_data[RTC_REG_C] = 0x00;
+    s->cmos_data[RTC_REG_D] = 0x80;
+
+    s->periodic_timer = qemu_new_timer(vm_clock, 
+                                       rtc_periodic_timer, s);
+    s->second_timer = qemu_new_timer(vm_clock, 
+                                     rtc_update_second, s);
+    s->second_timer2 = qemu_new_timer(vm_clock, 
+                                      rtc_update_second2, s);
+
+    s->next_second_time = qemu_get_clock(vm_clock) + (ticks_per_sec * 99) / 100;
+    qemu_mod_timer(s->second_timer2, s->next_second_time);
+
+    register_ioport_write(base, 2, 1, cmos_ioport_write, s);
+    register_ioport_read(base, 2, 1, cmos_ioport_read, s);
+
+    register_savevm("mc146818rtc", base, 1, rtc_save, rtc_load, s);
+    return s;
+}
+
diff --git a/tools/ioemu/hw/ne2000.c b/tools/ioemu/hw/ne2000.c
new file mode 100644 (file)
index 0000000..79d3026
--- /dev/null
@@ -0,0 +1,684 @@
+/*
+ * QEMU NE2000 emulation
+ * 
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+
+/* debug NE2000 card */
+//#define DEBUG_NE2000
+
+#define MAX_ETH_FRAME_SIZE 1514
+
+#define E8390_CMD      0x00  /* The command register (for all pages) */
+/* Page 0 register offsets. */
+#define EN0_CLDALO     0x01    /* Low byte of current local dma addr  RD */
+#define EN0_STARTPG    0x01    /* Starting page of ring bfr WR */
+#define EN0_CLDAHI     0x02    /* High byte of current local dma addr  RD */
+#define EN0_STOPPG     0x02    /* Ending page +1 of ring bfr WR */
+#define EN0_BOUNDARY   0x03    /* Boundary page of ring bfr RD WR */
+#define EN0_TSR                0x04    /* Transmit status reg RD */
+#define EN0_TPSR       0x04    /* Transmit starting page WR */
+#define EN0_NCR                0x05    /* Number of collision reg RD */
+#define EN0_TCNTLO     0x05    /* Low  byte of tx byte count WR */
+#define EN0_FIFO       0x06    /* FIFO RD */
+#define EN0_TCNTHI     0x06    /* High byte of tx byte count WR */
+#define EN0_ISR                0x07    /* Interrupt status reg RD WR */
+#define EN0_CRDALO     0x08    /* low byte of current remote dma address RD */
+#define EN0_RSARLO     0x08    /* Remote start address reg 0 */
+#define EN0_CRDAHI     0x09    /* high byte, current remote dma address RD */
+#define EN0_RSARHI     0x09    /* Remote start address reg 1 */
+#define EN0_RCNTLO     0x0a    /* Remote byte count reg WR */
+#define EN0_RCNTHI     0x0b    /* Remote byte count reg WR */
+#define EN0_RSR                0x0c    /* rx status reg RD */
+#define EN0_RXCR       0x0c    /* RX configuration reg WR */
+#define EN0_TXCR       0x0d    /* TX configuration reg WR */
+#define EN0_COUNTER0   0x0d    /* Rcv alignment error counter RD */
+#define EN0_DCFG       0x0e    /* Data configuration reg WR */
+#define EN0_COUNTER1   0x0e    /* Rcv CRC error counter RD */
+#define EN0_IMR                0x0f    /* Interrupt mask reg WR */
+#define EN0_COUNTER2   0x0f    /* Rcv missed frame error counter RD */
+
+#define EN1_PHYS        0x11
+#define EN1_CURPAG      0x17
+#define EN1_MULT        0x18
+
+/*  Register accessed at EN_CMD, the 8390 base addr.  */
+#define E8390_STOP     0x01    /* Stop and reset the chip */
+#define E8390_START    0x02    /* Start the chip, clear reset */
+#define E8390_TRANS    0x04    /* Transmit a frame */
+#define E8390_RREAD    0x08    /* Remote read */
+#define E8390_RWRITE   0x10    /* Remote write  */
+#define E8390_NODMA    0x20    /* Remote DMA */
+#define E8390_PAGE0    0x00    /* Select page chip registers */
+#define E8390_PAGE1    0x40    /* using the two high-order bits */
+#define E8390_PAGE2    0x80    /* Page 3 is invalid. */
+
+/* Bits in EN0_ISR - Interrupt status register */
+#define ENISR_RX       0x01    /* Receiver, no error */
+#define ENISR_TX       0x02    /* Transmitter, no error */
+#define ENISR_RX_ERR   0x04    /* Receiver, with error */
+#define ENISR_TX_ERR   0x08    /* Transmitter, with error */
+#define ENISR_OVER     0x10    /* Receiver overwrote the ring */
+#define ENISR_COUNTERS 0x20    /* Counters need emptying */
+#define ENISR_RDC      0x40    /* remote dma complete */
+#define ENISR_RESET    0x80    /* Reset completed */
+#define ENISR_ALL      0x3f    /* Interrupts we will enable */
+
+/* Bits in received packet status byte and EN0_RSR*/
+#define ENRSR_RXOK     0x01    /* Received a good packet */
+#define ENRSR_CRC      0x02    /* CRC error */
+#define ENRSR_FAE      0x04    /* frame alignment error */
+#define ENRSR_FO       0x08    /* FIFO overrun */
+#define ENRSR_MPA      0x10    /* missed pkt */
+#define ENRSR_PHY      0x20    /* physical/multicast address */
+#define ENRSR_DIS      0x40    /* receiver disable. set in monitor mode */
+#define ENRSR_DEF      0x80    /* deferring */
+
+/* Transmitted packet status, EN0_TSR. */
+#define ENTSR_PTX 0x01 /* Packet transmitted without error */
+#define ENTSR_ND  0x02 /* The transmit wasn't deferred. */
+#define ENTSR_COL 0x04 /* The transmit collided at least once. */
+#define ENTSR_ABT 0x08  /* The transmit collided 16 times, and was deferred. */
+#define ENTSR_CRS 0x10 /* The carrier sense was lost. */
+#define ENTSR_FU  0x20  /* A "FIFO underrun" occurred during transmit. */
+#define ENTSR_CDH 0x40 /* The collision detect "heartbeat" signal was lost. */
+#define ENTSR_OWC 0x80  /* There was an out-of-window collision. */
+
+#define NE2000_PMEM_SIZE    (32*1024)
+#define NE2000_PMEM_START   (16*1024)
+#define NE2000_PMEM_END     (NE2000_PMEM_SIZE+NE2000_PMEM_START)
+#define NE2000_MEM_SIZE     NE2000_PMEM_END
+
+typedef struct NE2000State {
+    uint8_t cmd;
+    uint32_t start;
+    uint32_t stop;
+    uint8_t boundary;
+    uint8_t tsr;
+    uint8_t tpsr;
+    uint16_t tcnt;
+    uint16_t rcnt;
+    uint32_t rsar;
+    uint8_t rsr;
+    uint8_t isr;
+    uint8_t dcfg;
+    uint8_t imr;
+    uint8_t phys[6]; /* mac address */
+    uint8_t curpag;
+    uint8_t mult[8]; /* multicast mask array */
+    int irq;
+    PCIDevice *pci_dev;
+    NetDriverState *nd;
+    uint8_t mem[NE2000_MEM_SIZE];
+} NE2000State;
+
+static void ne2000_reset(NE2000State *s)
+{
+    int i;
+
+    s->isr = ENISR_RESET;
+    memcpy(s->mem, s->nd->macaddr, 6);
+    s->mem[14] = 0x57;
+    s->mem[15] = 0x57;
+
+    /* duplicate prom data */
+    for(i = 15;i >= 0; i--) {
+        s->mem[2 * i] = s->mem[i];
+        s->mem[2 * i + 1] = s->mem[i];
+    }
+}
+
+static void ne2000_update_irq(NE2000State *s)
+{
+    int isr;
+    isr = s->isr & s->imr;
+#if defined(DEBUG_NE2000)
+    printf("NE2000: Set IRQ line %d to %d (%02x %02x)\n",
+          s->irq, isr ? 1 : 0, s->isr, s->imr);
+#endif
+    if (s->irq == 16) {
+        /* PCI irq */
+        pci_set_irq(s->pci_dev, 0, (isr != 0));
+    } else {
+        /* ISA irq */
+        pic_set_irq(s->irq, (isr != 0));
+    }
+}
+
+/* return the max buffer size if the NE2000 can receive more data */
+static int ne2000_can_receive(void *opaque)
+{
+    NE2000State *s = opaque;
+    int avail, index, boundary;
+    
+    if (s->cmd & E8390_STOP)
+        return 0;
+    index = s->curpag << 8;
+    boundary = s->boundary << 8;
+    if (index < boundary)
+        avail = boundary - index;
+    else
+        avail = (s->stop - s->start) - (index - boundary);
+    if (avail < (MAX_ETH_FRAME_SIZE + 4))
+        return 0;
+    return MAX_ETH_FRAME_SIZE;
+}
+
+#define MIN_BUF_SIZE 60
+
+static void ne2000_receive(void *opaque, const uint8_t *buf, int size)
+{
+    NE2000State *s = opaque;
+    uint8_t *p;
+    int total_len, next, avail, len, index;
+    uint8_t buf1[60];
+    
+#if defined(DEBUG_NE2000)
+    printf("NE2000: received len=%d\n", size);
+#endif
+
+    /* if too small buffer, then expand it */
+    if (size < MIN_BUF_SIZE) {
+        memcpy(buf1, buf, size);
+        memset(buf1 + size, 0, MIN_BUF_SIZE - size);
+        buf = buf1;
+        size = MIN_BUF_SIZE;
+    }
+
+    index = s->curpag << 8;
+    /* 4 bytes for header */
+    total_len = size + 4;
+    /* address for next packet (4 bytes for CRC) */
+    next = index + ((total_len + 4 + 255) & ~0xff);
+    if (next >= s->stop)
+        next -= (s->stop - s->start);
+    /* prepare packet header */
+    p = s->mem + index;
+    s->rsr = ENRSR_RXOK; /* receive status */
+    /* XXX: check this */
+    if (buf[0] & 0x01)
+        s->rsr |= ENRSR_PHY;
+    p[0] = s->rsr;
+    p[1] = next >> 8;
+    p[2] = total_len;
+    p[3] = total_len >> 8;
+    index += 4;
+
+    /* write packet data */
+    while (size > 0) {
+        avail = s->stop - index;
+        len = size;
+        if (len > avail)
+            len = avail;
+        memcpy(s->mem + index, buf, len);
+        buf += len;
+        index += len;
+        if (index == s->stop)
+            index = s->start;
+        size -= len;
+    }
+    s->curpag = next >> 8;
+
+    /* now we can signal we have receive something */
+    s->isr |= ENISR_RX;
+    ne2000_update_irq(s);
+}
+
+static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+{
+    NE2000State *s = opaque;
+    int offset, page;
+
+    addr &= 0xf;
+#ifdef DEBUG_NE2000
+    printf("NE2000: write addr=0x%x val=0x%02x\n", addr, val);
+#endif
+    if (addr == E8390_CMD) {
+        /* control register */
+        s->cmd = val;
+        if (val & E8390_START) {
+            s->isr &= ~ENISR_RESET;
+            /* test specific case: zero length transfert */
+            if ((val & (E8390_RREAD | E8390_RWRITE)) &&
+                s->rcnt == 0) {
+                s->isr |= ENISR_RDC;
+                ne2000_update_irq(s);
+            }
+            if (val & E8390_TRANS) {
+                qemu_send_packet(s->nd, s->mem + (s->tpsr << 8), s->tcnt);
+                /* signal end of transfert */
+                s->tsr = ENTSR_PTX;
+                s->isr |= ENISR_TX;
+                ne2000_update_irq(s);
+            }
+        }
+    } else {
+        page = s->cmd >> 6;
+        offset = addr | (page << 4);
+        switch(offset) {
+        case EN0_STARTPG:
+            s->start = val << 8;
+            break;
+        case EN0_STOPPG:
+            s->stop = val << 8;
+            break;
+        case EN0_BOUNDARY:
+            s->boundary = val;
+            break;
+        case EN0_IMR:
+            s->imr = val;
+            ne2000_update_irq(s);
+            break;
+        case EN0_TPSR:
+            s->tpsr = val;
+            break;
+        case EN0_TCNTLO:
+            s->tcnt = (s->tcnt & 0xff00) | val;
+            break;
+        case EN0_TCNTHI:
+            s->tcnt = (s->tcnt & 0x00ff) | (val << 8);
+            break;
+        case EN0_RSARLO:
+            s->rsar = (s->rsar & 0xff00) | val;
+            break;
+        case EN0_RSARHI:
+            s->rsar = (s->rsar & 0x00ff) | (val << 8);
+            break;
+        case EN0_RCNTLO:
+            s->rcnt = (s->rcnt & 0xff00) | val;
+            break;
+        case EN0_RCNTHI:
+            s->rcnt = (s->rcnt & 0x00ff) | (val << 8);
+            break;
+        case EN0_DCFG:
+            s->dcfg = val;
+            break;
+        case EN0_ISR:
+            s->isr &= ~(val & 0x7f);
+            ne2000_update_irq(s);
+            break;
+        case EN1_PHYS ... EN1_PHYS + 5:
+            s->phys[offset - EN1_PHYS] = val;
+            break;
+        case EN1_CURPAG:
+            s->curpag = val;
+            break;
+        case EN1_MULT ... EN1_MULT + 7:
+            s->mult[offset - EN1_MULT] = val;
+            break;
+        }
+    }
+}
+
+static uint32_t ne2000_ioport_read(void *opaque, uint32_t addr)
+{
+    NE2000State *s = opaque;
+    int offset, page, ret;
+
+    addr &= 0xf;
+    if (addr == E8390_CMD) {
+        ret = s->cmd;
+    } else {
+        page = s->cmd >> 6;
+        offset = addr | (page << 4);
+        switch(offset) {
+        case EN0_TSR:
+            ret = s->tsr;
+            break;
+        case EN0_BOUNDARY:
+            ret = s->boundary;
+            break;
+        case EN0_ISR:
+            ret = s->isr;
+            break;
+       case EN0_RSARLO:
+           ret = s->rsar & 0x00ff;
+           break;
+       case EN0_RSARHI:
+           ret = s->rsar >> 8;
+           break;
+        case EN1_PHYS ... EN1_PHYS + 5:
+            ret = s->phys[offset - EN1_PHYS];
+            break;
+        case EN1_CURPAG:
+            ret = s->curpag;
+            break;
+        case EN1_MULT ... EN1_MULT + 7:
+            ret = s->mult[offset - EN1_MULT];
+            break;
+        case EN0_RSR:
+            ret = s->rsr;
+            break;
+        default:
+            ret = 0x00;
+            break;
+        }
+    }
+#ifdef DEBUG_NE2000
+    printf("NE2000: read addr=0x%x val=%02x\n", addr, ret);
+#endif
+    return ret;
+}
+
+static inline void ne2000_mem_writeb(NE2000State *s, uint32_t addr, 
+                                     uint32_t val)
+{
+    if (addr < 32 || 
+        (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
+        s->mem[addr] = val;
+    }
+}
+
+static inline void ne2000_mem_writew(NE2000State *s, uint32_t addr, 
+                                     uint32_t val)
+{
+    addr &= ~1; /* XXX: check exact behaviour if not even */
+    if (addr < 32 || 
+        (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
+        *(uint16_t *)(s->mem + addr) = cpu_to_le16(val);
+    }
+}
+
+static inline void ne2000_mem_writel(NE2000State *s, uint32_t addr, 
+                                     uint32_t val)
+{
+    addr &= ~1; /* XXX: check exact behaviour if not even */
+    if (addr < 32 || 
+        (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
+        cpu_to_le32wu((uint32_t *)(s->mem + addr), val);
+    }
+}
+
+static inline uint32_t ne2000_mem_readb(NE2000State *s, uint32_t addr)
+{
+    if (addr < 32 || 
+        (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
+        return s->mem[addr];
+    } else {
+        return 0xff;
+    }
+}
+
+static inline uint32_t ne2000_mem_readw(NE2000State *s, uint32_t addr)
+{
+    addr &= ~1; /* XXX: check exact behaviour if not even */
+    if (addr < 32 || 
+        (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
+        return le16_to_cpu(*(uint16_t *)(s->mem + addr));
+    } else {
+        return 0xffff;
+    }
+}
+
+static inline uint32_t ne2000_mem_readl(NE2000State *s, uint32_t addr)
+{
+    addr &= ~1; /* XXX: check exact behaviour if not even */
+    if (addr < 32 || 
+        (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
+        return le32_to_cpupu((uint32_t *)(s->mem + addr));
+    } else {
+        return 0xffffffff;
+    }
+}
+
+static inline void ne2000_dma_update(NE2000State *s, int len)
+{
+    s->rsar += len;
+    /* wrap */
+    /* XXX: check what to do if rsar > stop */
+    if (s->rsar == s->stop)
+        s->rsar = s->start;
+
+    if (s->rcnt <= len) {
+        s->rcnt = 0;
+        /* signal end of transfert */
+        s->isr |= ENISR_RDC;
+        ne2000_update_irq(s);
+    } else {
+        s->rcnt -= len;
+    }
+}
+
+static void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+{
+    NE2000State *s = opaque;
+
+#ifdef DEBUG_NE2000
+    printf("NE2000: asic write val=0x%04x\n", val);
+#endif
+    if (s->rcnt == 0)
+        return;
+    if (s->dcfg & 0x01) {
+        /* 16 bit access */
+        ne2000_mem_writew(s, s->rsar, val);
+        ne2000_dma_update(s, 2);
+    } else {
+        /* 8 bit access */
+        ne2000_mem_writeb(s, s->rsar, val);
+        ne2000_dma_update(s, 1);
+    }
+}
+
+static uint32_t ne2000_asic_ioport_read(void *opaque, uint32_t addr)
+{
+    NE2000State *s = opaque;
+    int ret;
+
+    if (s->dcfg & 0x01) {
+        /* 16 bit access */
+        ret = ne2000_mem_readw(s, s->rsar);
+        ne2000_dma_update(s, 2);
+    } else {
+        /* 8 bit access */
+        ret = ne2000_mem_readb(s, s->rsar);
+        ne2000_dma_update(s, 1);
+    }
+#ifdef DEBUG_NE2000
+    printf("NE2000: asic read val=0x%04x\n", ret);
+#endif
+    return ret;
+}
+
+static void ne2000_asic_ioport_writel(void *opaque, uint32_t addr, uint32_t val)
+{
+    NE2000State *s = opaque;
+
+#ifdef DEBUG_NE2000
+    printf("NE2000: asic writel val=0x%04x\n", val);
+#endif
+    if (s->rcnt == 0)
+        return;
+    /* 32 bit access */
+    ne2000_mem_writel(s, s->rsar, val);
+    ne2000_dma_update(s, 4);
+}
+
+static uint32_t ne2000_asic_ioport_readl(void *opaque, uint32_t addr)
+{
+    NE2000State *s = opaque;
+    int ret;
+
+    /* 32 bit access */
+    ret = ne2000_mem_readl(s, s->rsar);
+    ne2000_dma_update(s, 4);
+#ifdef DEBUG_NE2000
+    printf("NE2000: asic readl val=0x%04x\n", ret);
+#endif
+    return ret;
+}
+
+static void ne2000_reset_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+{
+    /* nothing to do (end of reset pulse) */
+}
+
+static uint32_t ne2000_reset_ioport_read(void *opaque, uint32_t addr)
+{
+    NE2000State *s = opaque;
+    ne2000_reset(s);
+    return 0;
+}
+
+static void ne2000_save(QEMUFile* f,void* opaque)
+{
+       NE2000State* s=(NE2000State*)opaque;
+
+       qemu_put_8s(f, &s->cmd);
+       qemu_put_be32s(f, &s->start);
+       qemu_put_be32s(f, &s->stop);
+       qemu_put_8s(f, &s->boundary);
+       qemu_put_8s(f, &s->tsr);
+       qemu_put_8s(f, &s->tpsr);
+       qemu_put_be16s(f, &s->tcnt);
+       qemu_put_be16s(f, &s->rcnt);
+       qemu_put_be32s(f, &s->rsar);
+       qemu_put_8s(f, &s->rsr);
+       qemu_put_8s(f, &s->isr);
+       qemu_put_8s(f, &s->dcfg);
+       qemu_put_8s(f, &s->imr);
+       qemu_put_buffer(f, s->phys, 6);
+       qemu_put_8s(f, &s->curpag);
+       qemu_put_buffer(f, s->mult, 8);
+       qemu_put_be32s(f, &s->irq);
+       qemu_put_buffer(f, s->mem, NE2000_MEM_SIZE);
+}
+
+static int ne2000_load(QEMUFile* f,void* opaque,int version_id)
+{
+       NE2000State* s=(NE2000State*)opaque;
+
+       if (version_id != 1)
+            return -EINVAL;
+
+       qemu_get_8s(f, &s->cmd);
+       qemu_get_be32s(f, &s->start);
+       qemu_get_be32s(f, &s->stop);
+       qemu_get_8s(f, &s->boundary);
+       qemu_get_8s(f, &s->tsr);
+       qemu_get_8s(f, &s->tpsr);
+       qemu_get_be16s(f, &s->tcnt);
+       qemu_get_be16s(f, &s->rcnt);
+       qemu_get_be32s(f, &s->rsar);
+       qemu_get_8s(f, &s->rsr);
+       qemu_get_8s(f, &s->isr);
+       qemu_get_8s(f, &s->dcfg);
+       qemu_get_8s(f, &s->imr);
+       qemu_get_buffer(f, s->phys, 6);
+       qemu_get_8s(f, &s->curpag);
+       qemu_get_buffer(f, s->mult, 8);
+       qemu_get_be32s(f, &s->irq);
+       qemu_get_buffer(f, s->mem, NE2000_MEM_SIZE);
+
+       return 0;
+}
+
+void isa_ne2000_init(int base, int irq, NetDriverState *nd)
+{
+    NE2000State *s;
+
+    s = qemu_mallocz(sizeof(NE2000State));
+    if (!s)
+        return;
+    
+    register_ioport_write(base, 16, 1, ne2000_ioport_write, s);
+    register_ioport_read(base, 16, 1, ne2000_ioport_read, s);
+
+    register_ioport_write(base + 0x10, 1, 1, ne2000_asic_ioport_write, s);
+    register_ioport_read(base + 0x10, 1, 1, ne2000_asic_ioport_read, s);
+    register_ioport_write(base + 0x10, 2, 2, ne2000_asic_ioport_write, s);
+    register_ioport_read(base + 0x10, 2, 2, ne2000_asic_ioport_read, s);
+
+    register_ioport_write(base + 0x1f, 1, 1, ne2000_reset_ioport_write, s);
+    register_ioport_read(base + 0x1f, 1, 1, ne2000_reset_ioport_read, s);
+    s->irq = irq;
+    s->nd = nd;
+
+    ne2000_reset(s);
+
+    qemu_add_read_packet(nd, ne2000_can_receive, ne2000_receive, s);
+
+    register_savevm("ne2000", 0, 1, ne2000_save, ne2000_load, s);
+
+}
+
+/***********************************************************/
+/* PCI NE2000 definitions */
+
+typedef struct PCINE2000State {
+    PCIDevice dev;
+    NE2000State ne2000;
+} PCINE2000State;
+
+static void ne2000_map(PCIDevice *pci_dev, int region_num, 
+                       uint32_t addr, uint32_t size, int type)
+{
+    PCINE2000State *d = (PCINE2000State *)pci_dev;
+    NE2000State *s = &d->ne2000;
+
+    register_ioport_write(addr, 16, 1, ne2000_ioport_write, s);
+    register_ioport_read(addr, 16, 1, ne2000_ioport_read, s);
+
+    register_ioport_write(addr + 0x10, 1, 1, ne2000_asic_ioport_write, s);
+    register_ioport_read(addr + 0x10, 1, 1, ne2000_asic_ioport_read, s);
+    register_ioport_write(addr + 0x10, 2, 2, ne2000_asic_ioport_write, s);
+    register_ioport_read(addr + 0x10, 2, 2, ne2000_asic_ioport_read, s);
+    register_ioport_write(addr + 0x10, 4, 4, ne2000_asic_ioport_writel, s);
+    register_ioport_read(addr + 0x10, 4, 4, ne2000_asic_ioport_readl, s);
+
+    register_ioport_write(addr + 0x1f, 1, 1, ne2000_reset_ioport_write, s);
+    register_ioport_read(addr + 0x1f, 1, 1, ne2000_reset_ioport_read, s);
+}
+
+void pci_ne2000_init(PCIBus *bus, NetDriverState *nd)
+{
+    PCINE2000State *d;
+    NE2000State *s;
+    uint8_t *pci_conf;
+    
+    d = (PCINE2000State *)pci_register_device(bus,
+                                              "NE2000", sizeof(PCINE2000State),
+                                              -1, 
+                                              NULL, NULL);
+    pci_conf = d->dev.config;
+    pci_conf[0x00] = 0xec; // Realtek 8029
+    pci_conf[0x01] = 0x10;
+    pci_conf[0x02] = 0x29;
+    pci_conf[0x03] = 0x80;
+    pci_conf[0x0a] = 0x00; // ethernet network controller 
+    pci_conf[0x0b] = 0x02;
+    pci_conf[0x0e] = 0x00; // header_type
+    pci_conf[0x3d] = 1; // interrupt pin 0
+    
+    pci_register_io_region(&d->dev, 0, 0x100, 
+                           PCI_ADDRESS_SPACE_IO, ne2000_map);
+    s = &d->ne2000;
+    s->irq = 16; // PCI interrupt
+    s->pci_dev = (PCIDevice *)d;
+    s->nd = nd;
+    ne2000_reset(s);
+    qemu_add_read_packet(nd, ne2000_can_receive, ne2000_receive, s);
+
+    /* XXX: instance number ? */
+    register_savevm("ne2000", 0, 1, ne2000_save, ne2000_load, s);
+    register_savevm("ne2000_pci", 0, 1, generic_pci_save, generic_pci_load, 
+                    &d->dev);
+}
diff --git a/tools/ioemu/hw/openpic.c b/tools/ioemu/hw/openpic.c
new file mode 100644 (file)
index 0000000..d193cfe
--- /dev/null
@@ -0,0 +1,1023 @@
+/*
+ * OpenPIC emulation
+ * 
+ * Copyright (c) 2004 Jocelyn Mayer
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+/*
+ *
+ * Based on OpenPic implementations:
+ * - Intel GW80314 I/O compagnion chip developper's manual
+ * - Motorola MPC8245 & MPC8540 user manuals.
+ * - Motorola MCP750 (aka Raven) programmer manual.
+ * - Motorola Harrier programmer manuel
+ *
+ * Serial interrupts, as implemented in Raven chipset are not supported yet.
+ * 
+ */
+#include "vl.h"
+
+//#define DEBUG_OPENPIC
+
+#ifdef DEBUG_OPENPIC
+#define DPRINTF(fmt, args...) do { printf(fmt , ##args); } while (0)
+#else
+#define DPRINTF(fmt, args...) do { } while (0)
+#endif
+#define ERROR(fmr, args...) do { printf("ERROR: " fmr , ##args); } while (0)
+
+#define USE_MPCxxx /* Intel model is broken, for now */
+
+#if defined (USE_INTEL_GW80314)
+/* Intel GW80314 I/O Companion chip */
+
+#define MAX_CPU     4
+#define MAX_IRQ    32
+#define MAX_DBL     4
+#define MAX_MBX     4
+#define MAX_TMR     4
+#define VECTOR_BITS 8
+#define MAX_IPI     0
+
+#define VID (0x00000000)
+
+#define OPENPIC_LITTLE_ENDIAN 1
+#define OPENPIC_BIG_ENDIAN    0
+
+#elif defined(USE_MPCxxx)
+
+#define MAX_CPU     2
+#define MAX_IRQ    64
+#define EXT_IRQ    48
+#define MAX_DBL     0
+#define MAX_MBX     0
+#define MAX_TMR     4
+#define VECTOR_BITS 8
+#define MAX_IPI     4
+#define VID         0x03 /* MPIC version ID */
+#define VENI        0x00000000 /* Vendor ID */
+
+enum {
+    IRQ_IPVP = 0,
+    IRQ_IDE,
+};
+
+#define OPENPIC_LITTLE_ENDIAN 1
+#define OPENPIC_BIG_ENDIAN    0
+
+#else
+#error "Please select which OpenPic implementation is to be emulated"
+#endif
+
+#if (OPENPIC_BIG_ENDIAN && !TARGET_WORDS_BIGENDIAN) || \
+    (OPENPIC_LITTLE_ENDIAN && TARGET_WORDS_BIGENDIAN)
+#define OPENPIC_SWAP
+#endif
+
+/* Interrupt definitions */
+#define IRQ_FE     (EXT_IRQ)     /* Internal functional IRQ */
+#define IRQ_ERR    (EXT_IRQ + 1) /* Error IRQ */
+#define IRQ_TIM0   (EXT_IRQ + 2) /* First timer IRQ */
+#if MAX_IPI > 0
+#define IRQ_IPI0   (IRQ_TIM0 + MAX_TMR) /* First IPI IRQ */
+#define IRQ_DBL0   (IRQ_IPI0 + (MAX_CPU * MAX_IPI)) /* First doorbell IRQ */
+#else
+#define IRQ_DBL0   (IRQ_TIM0 + MAX_TMR) /* First doorbell IRQ */
+#define IRQ_MBX0   (IRQ_DBL0 + MAX_DBL) /* First mailbox IRQ */
+#endif
+
+#define BF_WIDTH(_bits_) \
+(((_bits_) + (sizeof(uint32_t) * 8) - 1) / (sizeof(uint32_t) * 8))
+
+static inline void set_bit (uint32_t *field, int bit)
+{
+    field[bit >> 5] |= 1 << (bit & 0x1F);
+}
+
+static inline void reset_bit (uint32_t *field, int bit)
+{
+    field[bit >> 5] &= ~(1 << (bit & 0x1F));
+}
+
+static inline int test_bit (uint32_t *field, int bit)
+{
+    return (field[bit >> 5] & 1 << (bit & 0x1F)) != 0;
+}
+
+enum {
+    IRQ_EXTERNAL = 0x01,
+    IRQ_INTERNAL = 0x02,
+    IRQ_TIMER    = 0x04,
+    IRQ_SPECIAL  = 0x08,
+} IRQ_src_type;
+
+typedef struct IRQ_queue_t {
+    uint32_t queue[BF_WIDTH(MAX_IRQ)];
+    int next;
+    int priority;
+} IRQ_queue_t;
+
+typedef struct IRQ_src_t {
+    uint32_t ipvp;  /* IRQ vector/priority register */
+    uint32_t ide;   /* IRQ destination register */
+    int type;
+    int last_cpu;
+    int pending;    /* TRUE if IRQ is pending */
+} IRQ_src_t;
+
+enum IPVP_bits {
+    IPVP_MASK     = 31,
+    IPVP_ACTIVITY = 30,
+    IPVP_MODE     = 29,
+    IPVP_POLARITY = 23,
+    IPVP_SENSE    = 22,
+};
+#define IPVP_PRIORITY_MASK     (0x1F << 16)
+#define IPVP_PRIORITY(_ipvpr_) ((int)(((_ipvpr_) & IPVP_PRIORITY_MASK) >> 16))
+#define IPVP_VECTOR_MASK       ((1 << VECTOR_BITS) - 1)
+#define IPVP_VECTOR(_ipvpr_)   ((_ipvpr_) & IPVP_VECTOR_MASK)
+
+typedef struct IRQ_dst_t {
+    uint32_t pctp; /* CPU current task priority */
+    uint32_t pcsr; /* CPU sensitivity register */
+    IRQ_queue_t raised;
+    IRQ_queue_t servicing;
+    CPUState *env; /* Needed if we did SMP */
+} IRQ_dst_t;
+
+struct openpic_t {
+    PCIDevice pci_dev;
+    int mem_index;
+    /* Global registers */
+    uint32_t frep; /* Feature reporting register */
+    uint32_t glbc; /* Global configuration register  */
+    uint32_t micr; /* MPIC interrupt configuration register */
+    uint32_t veni; /* Vendor identification register */
+    uint32_t spve; /* Spurious vector register */
+    uint32_t tifr; /* Timer frequency reporting register */
+    /* Source registers */
+    IRQ_src_t src[MAX_IRQ];
+    /* Local registers per output pin */
+    IRQ_dst_t dst[MAX_CPU];
+    int nb_cpus;
+    /* Timer registers */
+    struct {
+       uint32_t ticc;  /* Global timer current count register */
+       uint32_t tibc;  /* Global timer base count register */
+    } timers[MAX_TMR];
+#if MAX_DBL > 0
+    /* Doorbell registers */
+    uint32_t dar;        /* Doorbell activate register */
+    struct {
+       uint32_t dmr;    /* Doorbell messaging register */
+    } doorbells[MAX_DBL];
+#endif
+#if MAX_MBX > 0
+    /* Mailbox registers */
+    struct {
+       uint32_t mbr;    /* Mailbox register */
+    } mailboxes[MAX_MAILBOXES];
+#endif
+};
+
+static inline void IRQ_setbit (IRQ_queue_t *q, int n_IRQ)
+{
+    set_bit(q->queue, n_IRQ);
+}
+
+static inline void IRQ_resetbit (IRQ_queue_t *q, int n_IRQ)
+{
+    reset_bit(q->queue, n_IRQ);
+}
+
+static inline int IRQ_testbit (IRQ_queue_t *q, int n_IRQ)
+{
+    return test_bit(q->queue, n_IRQ);
+}
+
+static void IRQ_check (openpic_t *opp, IRQ_queue_t *q)
+{
+    int next, i;
+    int priority;
+
+    next = -1;
+    priority = -1;
+    for (i = 0; i < MAX_IRQ; i++) {
+       if (IRQ_testbit(q, i)) {
+            DPRINTF("IRQ_check: irq %d set ipvp_pr=%d pr=%d\n", 
+                    i, IPVP_PRIORITY(opp->src[i].ipvp), priority);
+           if (IPVP_PRIORITY(opp->src[i].ipvp) > priority) {
+               next = i;
+               priority = IPVP_PRIORITY(opp->src[i].ipvp);
+           }
+       }
+    }
+    q->next = next;
+    q->priority = priority;
+}
+
+static int IRQ_get_next (openpic_t *opp, IRQ_queue_t *q)
+{
+    if (q->next == -1) {
+        /* XXX: optimize */
+       IRQ_check(opp, q);
+    }
+
+    return q->next;
+}
+
+static void IRQ_local_pipe (openpic_t *opp, int n_CPU, int n_IRQ)
+{
+    IRQ_dst_t *dst;
+    IRQ_src_t *src;
+    int priority;
+
+    dst = &opp->dst[n_CPU];
+    src = &opp->src[n_IRQ];
+    priority = IPVP_PRIORITY(src->ipvp);
+    if (priority <= dst->pctp) {
+       /* Too low priority */
+       return;
+    }
+    if (IRQ_testbit(&dst->raised, n_IRQ)) {
+       /* Interrupt miss */
+       return;
+    }
+    set_bit(&src->ipvp, IPVP_ACTIVITY);
+    IRQ_setbit(&dst->raised, n_IRQ);
+    if (priority > dst->raised.priority) {
+        IRQ_get_next(opp, &dst->raised);
+        DPRINTF("Raise CPU IRQ\n");
+        cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HARD);
+    }
+}
+
+/* update pic state because registers for n_IRQ have changed value */
+static void openpic_update_irq(openpic_t *opp, int n_IRQ)
+{
+    IRQ_src_t *src;
+    int i;
+
+    src = &opp->src[n_IRQ];
+
+    if (!src->pending) {
+        /* no irq pending */
+        return;
+    }
+    if (test_bit(&src->ipvp, IPVP_MASK)) {
+       /* Interrupt source is disabled */
+       return;
+    }
+    if (IPVP_PRIORITY(src->ipvp) == 0) {
+       /* Priority set to zero */
+       return;
+    }
+    if (test_bit(&src->ipvp, IPVP_ACTIVITY)) {
+        /* IRQ already active */
+        return;
+    }
+    if (src->ide == 0x00000000) {
+       /* No target */
+       return;
+    }
+
+    if (!test_bit(&src->ipvp, IPVP_MODE) ||
+        src->ide == (1 << src->last_cpu)) {
+        /* Directed delivery mode */
+        for (i = 0; i < opp->nb_cpus; i++) {
+            if (test_bit(&src->ide, i))
+                IRQ_local_pipe(opp, i, n_IRQ);
+        }
+    } else {
+        /* Distributed delivery mode */
+        /* XXX: incorrect code */
+        for (i = src->last_cpu; i < src->last_cpu; i++) {
+            if (i == MAX_IRQ)
+                i = 0;
+            if (test_bit(&src->ide, i)) {
+                IRQ_local_pipe(opp, i, n_IRQ);
+                src->last_cpu = i;
+                break;
+            }
+        }
+    }
+}
+
+void openpic_set_irq(openpic_t *opp, int n_IRQ, int level)
+{
+    IRQ_src_t *src;
+
+    src = &opp->src[n_IRQ];
+    DPRINTF("openpic: set irq %d = %d ipvp=%08x\n", 
+            n_IRQ, level, src->ipvp);
+    if (test_bit(&src->ipvp, IPVP_SENSE)) {
+        /* level-sensitive irq */
+        src->pending = level;
+        if (!level)
+            reset_bit(&src->ipvp, IPVP_ACTIVITY);
+    } else {
+        /* edge-sensitive irq */
+        if (level)
+            src->pending = 1;
+    }
+    openpic_update_irq(opp, n_IRQ);
+}
+
+static void openpic_reset (openpic_t *opp)
+{
+    int i;
+
+    opp->glbc = 0x80000000;
+    /* Initialise controler registers */
+    opp->frep = ((EXT_IRQ - 1) << 16) | ((MAX_CPU - 1) << 8) | VID;
+    opp->veni = VENI;
+    opp->spve = 0x000000FF;
+    opp->tifr = 0x003F7A00;
+    /* ? */
+    opp->micr = 0x00000000;
+    /* Initialise IRQ sources */
+    for (i = 0; i < MAX_IRQ; i++) {
+       opp->src[i].ipvp = 0xA0000000;
+       opp->src[i].ide  = 0x00000000;
+    }
+    /* Initialise IRQ destinations */
+    for (i = 0; i < opp->nb_cpus; i++) {
+       opp->dst[i].pctp      = 0x0000000F;
+       opp->dst[i].pcsr      = 0x00000000;
+       memset(&opp->dst[i].raised, 0, sizeof(IRQ_queue_t));
+       memset(&opp->dst[i].servicing, 0, sizeof(IRQ_queue_t));
+    }
+    /* Initialise timers */
+    for (i = 0; i < MAX_TMR; i++) {
+       opp->timers[i].ticc = 0x00000000;
+       opp->timers[i].tibc = 0x80000000;
+    }
+    /* Initialise doorbells */
+#if MAX_DBL > 0
+    opp->dar = 0x00000000;
+    for (i = 0; i < MAX_DBL; i++) {
+       opp->doorbells[i].dmr  = 0x00000000;
+    }
+#endif
+    /* Initialise mailboxes */
+#if MAX_MBX > 0
+    for (i = 0; i < MAX_MBX; i++) { /* ? */
+       opp->mailboxes[i].mbr   = 0x00000000;
+    }
+#endif
+    /* Go out of RESET state */
+    opp->glbc = 0x00000000;
+}
+
+static inline uint32_t read_IRQreg (openpic_t *opp, int n_IRQ, uint32_t reg)
+{
+    uint32_t retval;
+
+    switch (reg) {
+    case IRQ_IPVP:
+       retval = opp->src[n_IRQ].ipvp;
+       break;
+    case IRQ_IDE:
+       retval = opp->src[n_IRQ].ide;
+       break;
+    }
+
+    return retval;
+}
+
+static inline void write_IRQreg (openpic_t *opp, int n_IRQ,
+                                 uint32_t reg, uint32_t val)
+{
+    uint32_t tmp;
+
+    switch (reg) {
+    case IRQ_IPVP:
+        /* NOTE: not fully accurate for special IRQs, but simple and
+           sufficient */
+        /* ACTIVITY bit is read-only */
+       opp->src[n_IRQ].ipvp = 
+            (opp->src[n_IRQ].ipvp & 0x40000000) |
+            (val & 0x800F00FF);
+        openpic_update_irq(opp, n_IRQ);
+        DPRINTF("Set IPVP %d to 0x%08x -> 0x%08x\n", 
+                n_IRQ, val, opp->src[n_IRQ].ipvp);
+       break;
+    case IRQ_IDE:
+       tmp = val & 0xC0000000;
+        tmp |= val & ((1 << MAX_CPU) - 1);
+       opp->src[n_IRQ].ide = tmp;
+        DPRINTF("Set IDE %d to 0x%08x\n", n_IRQ, opp->src[n_IRQ].ide);
+       break;
+    }
+}
+
+#if 0 // Code provision for Intel model
+#if MAX_DBL > 0
+static uint32_t read_doorbell_register (openpic_t *opp,
+                                       int n_dbl, uint32_t offset)
+{
+    uint32_t retval;
+
+    switch (offset) {
+    case DBL_IPVP_OFFSET:
+       retval = read_IRQreg(opp, IRQ_DBL0 + n_dbl, IRQ_IPVP);
+       break;
+    case DBL_IDE_OFFSET:
+       retval = read_IRQreg(opp, IRQ_DBL0 + n_dbl, IRQ_IDE);
+       break;
+    case DBL_DMR_OFFSET:
+       retval = opp->doorbells[n_dbl].dmr;
+       break;
+    }
+
+    return retval;
+}
+     
+static void write_doorbell_register (penpic_t *opp, int n_dbl,
+                                    uint32_t offset, uint32_t value)
+{
+    switch (offset) {
+    case DBL_IVPR_OFFSET:
+       write_IRQreg(opp, IRQ_DBL0 + n_dbl, IRQ_IPVP, value);
+       break;
+    case DBL_IDE_OFFSET:
+       write_IRQreg(opp, IRQ_DBL0 + n_dbl, IRQ_IDE, value);
+       break;
+    case DBL_DMR_OFFSET:
+       opp->doorbells[n_dbl].dmr = value;
+       break;
+    }
+}
+#endif
+
+#if MAX_MBX > 0
+static uint32_t read_mailbox_register (openpic_t *opp,
+                                      int n_mbx, uint32_t offset)
+{
+    uint32_t retval;
+
+    switch (offset) {
+    case MBX_MBR_OFFSET:
+       retval = opp->mailboxes[n_mbx].mbr;
+       break;
+    case MBX_IVPR_OFFSET:
+       retval = read_IRQreg(opp, IRQ_MBX0 + n_mbx, IRQ_IPVP);
+       break;
+    case MBX_DMR_OFFSET:
+       retval = read_IRQreg(opp, IRQ_MBX0 + n_mbx, IRQ_IDE);
+       break;
+    }
+
+    return retval;
+}
+
+static void write_mailbox_register (openpic_t *opp, int n_mbx,
+                                   uint32_t address, uint32_t value)
+{
+    switch (offset) {
+    case MBX_MBR_OFFSET:
+       opp->mailboxes[n_mbx].mbr = value;
+       break;
+    case MBX_IVPR_OFFSET:
+       write_IRQreg(opp, IRQ_MBX0 + n_mbx, IRQ_IPVP, value);
+       break;
+    case MBX_DMR_OFFSET:
+       write_IRQreg(opp, IRQ_MBX0 + n_mbx, IRQ_IDE, value);
+       break;
+    }
+}
+#endif
+#endif /* 0 : Code provision for Intel model */
+
+static void openpic_gbl_write (void *opaque, uint32_t addr, uint32_t val)
+{
+    openpic_t *opp = opaque;
+
+    DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
+    if (addr & 0xF)
+        return;
+#if defined OPENPIC_SWAP
+    val = bswap32(val);
+#endif
+    addr &= 0xFF;
+    switch (addr) {
+    case 0x00: /* FREP */
+        break;
+    case 0x20: /* GLBC */
+        if (val & 0x80000000)
+            openpic_reset(opp);
+        opp->glbc = val & ~0x80000000;
+       break;
+    case 0x80: /* VENI */
+       break;
+    case 0x90: /* PINT */
+        /* XXX: Should be able to reset any CPU */
+        if (val & 1) {
+            DPRINTF("Reset CPU IRQ\n");
+            //            cpu_interrupt(cpu_single_env, CPU_INTERRUPT_RESET);
+        }
+       break;
+#if MAX_IPI > 0
+    case 0xA0: /* IPI_IPVP */
+    case 0xB0:
+    case 0xC0:
+    case 0xD0:
+        {
+            int idx;
+            idx = (addr - 0xA0) >> 4;
+            write_IRQreg(opp, IRQ_IPI0 + idx, IRQ_IPVP, val);
+        }
+        break;
+#endif
+    case 0xE0: /* SPVE */
+        opp->spve = val & 0x000000FF;
+        break;
+    case 0xF0: /* TIFR */
+        opp->tifr = val;
+       break;
+    default:
+        break;
+    }
+}
+
+static uint32_t openpic_gbl_read (void *opaque, uint32_t addr)
+{
+    openpic_t *opp = opaque;
+    uint32_t retval;
+
+    DPRINTF("%s: addr %08x\n", __func__, addr);
+    retval = 0xFFFFFFFF;
+    if (addr & 0xF)
+        return retval;
+    addr &= 0xFF;
+    switch (addr) {
+    case 0x00: /* FREP */
+        retval = opp->frep;
+        break;
+    case 0x20: /* GLBC */
+        retval = opp->glbc;
+       break;
+    case 0x80: /* VENI */
+        retval = opp->veni;
+       break;
+    case 0x90: /* PINT */
+        retval = 0x00000000;
+       break;
+#if MAX_IPI > 0
+    case 0xA0: /* IPI_IPVP */
+    case 0xB0:
+    case 0xC0:
+    case 0xD0:
+        {
+            int idx;
+            idx = (addr - 0xA0) >> 4;
+            retval = read_IRQreg(opp, IRQ_IPI0 + idx, IRQ_IPVP);
+        }
+       break;
+#endif
+    case 0xE0: /* SPVE */
+        retval = opp->spve;
+        break;
+    case 0xF0: /* TIFR */
+        retval = opp->tifr;
+       break;
+    default:
+        break;
+    }
+    DPRINTF("%s: => %08x\n", __func__, retval);
+#if defined OPENPIC_SWAP
+    retval = bswap32(retval);
+#endif
+
+    return retval;
+}
+
+static void openpic_timer_write (void *opaque, uint32_t addr, uint32_t val)
+{
+    openpic_t *opp = opaque;
+    int idx;
+
+    DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
+    if (addr & 0xF)
+        return;
+#if defined OPENPIC_SWAP
+    val = bswap32(val);
+#endif
+    addr -= 0x1100;
+    addr &= 0xFFFF;
+    idx = (addr & 0xFFF0) >> 6;
+    addr = addr & 0x30;
+    switch (addr) {
+    case 0x00: /* TICC */
+        break;
+    case 0x10: /* TIBC */
+       if ((opp->timers[idx].ticc & 0x80000000) != 0 &&
+           (val & 0x800000000) == 0 &&
+            (opp->timers[idx].tibc & 0x80000000) != 0)
+           opp->timers[idx].ticc &= ~0x80000000;
+       opp->timers[idx].tibc = val;
+       break;
+    case 0x20: /* TIVP */
+       write_IRQreg(opp, IRQ_TIM0 + idx, IRQ_IPVP, val);
+       break;
+    case 0x30: /* TIDE */
+       write_IRQreg(opp, IRQ_TIM0 + idx, IRQ_IDE, val);
+       break;
+    }
+}
+
+static uint32_t openpic_timer_read (void *opaque, uint32_t addr)
+{
+    openpic_t *opp = opaque;
+    uint32_t retval;
+    int idx;
+
+    DPRINTF("%s: addr %08x\n", __func__, addr);
+    retval = 0xFFFFFFFF;
+    if (addr & 0xF)
+        return retval;
+    addr -= 0x1100;
+    addr &= 0xFFFF;
+    idx = (addr & 0xFFF0) >> 6;
+    addr = addr & 0x30;
+    switch (addr) {
+    case 0x00: /* TICC */
+       retval = opp->timers[idx].ticc;
+        break;
+    case 0x10: /* TIBC */
+       retval = opp->timers[idx].tibc;
+       break;
+    case 0x20: /* TIPV */
+       retval = read_IRQreg(opp, IRQ_TIM0 + idx, IRQ_IPVP);
+       break;
+    case 0x30: /* TIDE */
+       retval = read_IRQreg(opp, IRQ_TIM0 + idx, IRQ_IDE);
+       break;
+    }
+    DPRINTF("%s: => %08x\n", __func__, retval);
+#if defined OPENPIC_SWAP
+    retval = bswap32(retval);
+#endif
+
+    return retval;
+}
+
+static void openpic_src_write (void *opaque, uint32_t addr, uint32_t val)
+{
+    openpic_t *opp = opaque;
+    int idx;
+
+    DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
+    if (addr & 0xF)
+        return;
+#if defined OPENPIC_SWAP
+    val = tswap32(val);
+#endif
+    addr = addr & 0xFFF0;
+    idx = addr >> 5;
+    if (addr & 0x10) {
+        /* EXDE / IFEDE / IEEDE */
+        write_IRQreg(opp, idx, IRQ_IDE, val);
+    } else {
+        /* EXVP / IFEVP / IEEVP */
+        write_IRQreg(opp, idx, IRQ_IPVP, val);
+    }
+}
+
+static uint32_t openpic_src_read (void *opaque, uint32_t addr)
+{
+    openpic_t *opp = opaque;
+    uint32_t retval;
+    int idx;
+
+    DPRINTF("%s: addr %08x\n", __func__, addr);
+    retval = 0xFFFFFFFF;
+    if (addr & 0xF)
+        return retval;
+    addr = addr & 0xFFF0;
+    idx = addr >> 5;
+    if (addr & 0x10) {
+        /* EXDE / IFEDE / IEEDE */
+        retval = read_IRQreg(opp, idx, IRQ_IDE);
+    } else {
+        /* EXVP / IFEVP / IEEVP */
+        retval = read_IRQreg(opp, idx, IRQ_IPVP);
+    }
+    DPRINTF("%s: => %08x\n", __func__, retval);
+#if defined OPENPIC_SWAP
+    retval = tswap32(retval);
+#endif
+
+    return retval;
+}
+
+static void openpic_cpu_write (void *opaque, uint32_t addr, uint32_t val)
+{
+    openpic_t *opp = opaque;
+    IRQ_src_t *src;
+    IRQ_dst_t *dst;
+    int idx, n_IRQ;
+
+    DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val);
+    if (addr & 0xF)
+        return;
+#if defined OPENPIC_SWAP
+    val = bswap32(val);
+#endif
+    addr &= 0x1FFF0;
+    idx = addr / 0x1000;
+    dst = &opp->dst[idx];
+    addr &= 0xFF0;
+    switch (addr) {
+#if MAX_IPI > 0
+    case 0x40: /* PIPD */
+    case 0x50:
+    case 0x60:
+    case 0x70:
+        idx = (addr - 0x40) >> 4;
+        write_IRQreg(opp, IRQ_IPI0 + idx, IRQ_IDE, val);
+        openpic_set_irq(opp, IRQ_IPI0 + idx, 1);
+        openpic_set_irq(opp, IRQ_IPI0 + idx, 0);
+        break;
+#endif
+    case 0x80: /* PCTP */
+       dst->pctp = val & 0x0000000F;
+       break;
+    case 0x90: /* WHOAMI */
+       /* Read-only register */
+       break;
+    case 0xA0: /* PIAC */
+       /* Read-only register */
+       break;
+    case 0xB0: /* PEOI */
+        DPRINTF("PEOI\n");
+       n_IRQ = IRQ_get_next(opp, &dst->servicing);
+       IRQ_resetbit(&dst->servicing, n_IRQ);
+       dst->servicing.next = -1;
+       src = &opp->src[n_IRQ];
+       /* Set up next servicing IRQ */
+       IRQ_get_next(opp, &dst->servicing);
+       /* Check queued interrupts. */
+       n_IRQ = IRQ_get_next(opp, &dst->raised);
+       if (n_IRQ != -1) {
+           src = &opp->src[n_IRQ];
+           if (IPVP_PRIORITY(src->ipvp) > dst->servicing.priority) {
+                DPRINTF("Raise CPU IRQ\n");
+                cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HARD);
+            }
+       }
+       break;
+    default:
+        break;
+    }
+}
+
+static uint32_t openpic_cpu_read (void *opaque, uint32_t addr)
+{
+    openpic_t *opp = opaque;
+    IRQ_src_t *src;
+    IRQ_dst_t *dst;
+    uint32_t retval;
+    int idx, n_IRQ;
+    
+    DPRINTF("%s: addr %08x\n", __func__, addr);
+    retval = 0xFFFFFFFF;
+    if (addr & 0xF)
+        return retval;
+    addr &= 0x1FFF0;
+    idx = addr / 0x1000;
+    dst = &opp->dst[idx];
+    addr &= 0xFF0;
+    switch (addr) {
+    case 0x80: /* PCTP */
+       retval = dst->pctp;
+       break;
+    case 0x90: /* WHOAMI */
+       retval = idx;
+       break;
+    case 0xA0: /* PIAC */
+       n_IRQ = IRQ_get_next(opp, &dst->raised);
+        DPRINTF("PIAC: irq=%d\n", n_IRQ);
+       if (n_IRQ == -1) {
+           /* No more interrupt pending */
+            retval = opp->spve;
+       } else {
+           src = &opp->src[n_IRQ];
+           if (!test_bit(&src->ipvp, IPVP_ACTIVITY) ||
+               !(IPVP_PRIORITY(src->ipvp) > dst->pctp)) {
+               /* - Spurious level-sensitive IRQ
+                * - Priorities has been changed
+                *   and the pending IRQ isn't allowed anymore
+                */
+               reset_bit(&src->ipvp, IPVP_ACTIVITY);
+               retval = IPVP_VECTOR(opp->spve);
+           } else {
+               /* IRQ enter servicing state */
+               IRQ_setbit(&dst->servicing, n_IRQ);
+               retval = IPVP_VECTOR(src->ipvp);
+           }
+           IRQ_resetbit(&dst->raised, n_IRQ);
+           dst->raised.next = -1;
+           if (!test_bit(&src->ipvp, IPVP_SENSE)) {
+                /* edge-sensitive IRQ */
+               reset_bit(&src->ipvp, IPVP_ACTIVITY);
+                src->pending = 0;
+            }
+       }
+       break;
+    case 0xB0: /* PEOI */
+       retval = 0;
+       break;
+#if MAX_IPI > 0
+    case 0x40: /* IDE */
+    case 0x50:
+        idx = (addr - 0x40) >> 4;
+        retval = read_IRQreg(opp, IRQ_IPI0 + idx, IRQ_IDE);
+        break;
+#endif
+    default:
+        break;
+    }
+    DPRINTF("%s: => %08x\n", __func__, retval);
+#if defined OPENPIC_SWAP
+    retval= bswap32(retval);
+#endif
+
+    return retval;
+}
+
+static void openpic_buggy_write (void *opaque,
+                                 target_phys_addr_t addr, uint32_t val)
+{
+    printf("Invalid OPENPIC write access !\n");
+}
+
+static uint32_t openpic_buggy_read (void *opaque, target_phys_addr_t addr)
+{
+    printf("Invalid OPENPIC read access !\n");
+
+    return -1;
+}
+
+static void openpic_writel (void *opaque,
+                            target_phys_addr_t addr, uint32_t val)
+{
+    openpic_t *opp = opaque;
+
+    addr &= 0x3FFFF;
+    DPRINTF("%s: offset %08x val: %08x\n", __func__, (int)addr, val);
+    if (addr < 0x1100) {
+        /* Global registers */
+        openpic_gbl_write(opp, addr, val);
+    } else if (addr < 0x10000) {
+        /* Timers registers */
+        openpic_timer_write(opp, addr, val);
+    } else if (addr < 0x20000) {
+        /* Source registers */
+        openpic_src_write(opp, addr, val);
+    } else {
+        /* CPU registers */
+        openpic_cpu_write(opp, addr, val);
+    }
+}
+
+static uint32_t openpic_readl (void *opaque,target_phys_addr_t addr)
+{
+    openpic_t *opp = opaque;
+    uint32_t retval;
+
+    addr &= 0x3FFFF;
+    DPRINTF("%s: offset %08x\n", __func__, (int)addr);
+    if (addr < 0x1100) {
+        /* Global registers */
+        retval = openpic_gbl_read(opp, addr);
+    } else if (addr < 0x10000) {
+        /* Timers registers */
+        retval = openpic_timer_read(opp, addr);
+    } else if (addr < 0x20000) {
+        /* Source registers */
+        retval = openpic_src_read(opp, addr);
+    } else {
+        /* CPU registers */
+        retval = openpic_cpu_read(opp, addr);
+    }
+
+    return retval;
+}
+
+static CPUWriteMemoryFunc *openpic_write[] = {
+    &openpic_buggy_write,
+    &openpic_buggy_write,
+    &openpic_writel,
+};
+
+static CPUReadMemoryFunc *openpic_read[] = {
+    &openpic_buggy_read,
+    &openpic_buggy_read,
+    &openpic_readl,
+};
+
+static void openpic_map(PCIDevice *pci_dev, int region_num, 
+                        uint32_t addr, uint32_t size, int type)
+{
+    openpic_t *opp;
+
+    DPRINTF("Map OpenPIC\n");
+    opp = (openpic_t *)pci_dev;
+    /* Global registers */
+    DPRINTF("Register OPENPIC gbl   %08x => %08x\n",
+            addr + 0x1000, addr + 0x1000 + 0x100);
+    /* Timer registers */
+    DPRINTF("Register OPENPIC timer %08x => %08x\n",
+            addr + 0x1100, addr + 0x1100 + 0x40 * MAX_TMR);
+    /* Interrupt source registers */
+    DPRINTF("Register OPENPIC src   %08x => %08x\n",
+            addr + 0x10000, addr + 0x10000 + 0x20 * (EXT_IRQ + 2));
+    /* Per CPU registers */
+    DPRINTF("Register OPENPIC dst   %08x => %08x\n",
+            addr + 0x20000, addr + 0x20000 + 0x1000 * MAX_CPU);
+    cpu_register_physical_memory(addr, 0x40000, opp->mem_index);
+#if 0 // Don't implement ISU for now
+    opp_io_memory = cpu_register_io_memory(0, openpic_src_read,
+                                           openpic_src_write);
+    cpu_register_physical_memory(isu_base, 0x20 * (EXT_IRQ + 2),
+                                 opp_io_memory);
+#endif
+}
+
+openpic_t *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus)
+{
+    openpic_t *opp;
+    uint8_t *pci_conf;
+    int i, m;
+    
+    /* XXX: for now, only one CPU is supported */
+    if (nb_cpus != 1)
+        return NULL;
+    if (bus) {
+        opp = (openpic_t *)pci_register_device(bus, "OpenPIC", sizeof(openpic_t),
+                                               -1, NULL, NULL);
+        if (opp == NULL)
+            return NULL;
+        pci_conf = opp->pci_dev.config;
+        pci_conf[0x00] = 0x14; // IBM MPIC2
+        pci_conf[0x01] = 0x10;
+        pci_conf[0x02] = 0xFF;
+        pci_conf[0x03] = 0xFF;
+        pci_conf[0x0a] = 0x80; // PIC
+        pci_conf[0x0b] = 0x08;
+        pci_conf[0x0e] = 0x00; // header_type
+        pci_conf[0x3d] = 0x00; // no interrupt pin
+        
+        /* Register I/O spaces */
+        pci_register_io_region((PCIDevice *)opp, 0, 0x40000,
+                               PCI_ADDRESS_SPACE_MEM, &openpic_map);
+    } else {
+        opp = qemu_mallocz(sizeof(openpic_t));
+    }
+
+    opp->mem_index = cpu_register_io_memory(0, openpic_read,
+                                            openpic_write, opp);
+    
+    //    isu_base &= 0xFFFC0000;
+    opp->nb_cpus = nb_cpus;
+    /* Set IRQ types */
+    for (i = 0; i < EXT_IRQ; i++) {
+        opp->src[i].type = IRQ_EXTERNAL;
+    }
+    for (; i < IRQ_TIM0; i++) {
+        opp->src[i].type = IRQ_SPECIAL;
+    }
+#if MAX_IPI > 0
+    m = IRQ_IPI0;
+#else
+    m = IRQ_DBL0;
+#endif
+    for (; i < m; i++) {
+        opp->src[i].type = IRQ_TIMER;
+    }
+    for (; i < MAX_IRQ; i++) {
+        opp->src[i].type = IRQ_INTERNAL;
+    }
+    openpic_reset(opp);
+    if (pmem_index)
+        *pmem_index = opp->mem_index;
+    return opp;
+}
diff --git a/tools/ioemu/hw/pc.c b/tools/ioemu/hw/pc.c
new file mode 100644 (file)
index 0000000..7bd85e7
--- /dev/null
@@ -0,0 +1,575 @@
+/*
+ * QEMU PC System Emulator
+ * 
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+
+/* output Bochs bios info messages */
+//#define DEBUG_BIOS
+
+#define BIOS_FILENAME "bios.bin"
+#define VGABIOS_FILENAME "vgabios.bin"
+#define VGABIOS_CIRRUS_FILENAME "vgabios-cirrus.bin"
+#define LINUX_BOOT_FILENAME "linux_boot.bin"
+
+#define KERNEL_LOAD_ADDR     0x00100000
+#define INITRD_LOAD_ADDR     0x00400000
+#define KERNEL_PARAMS_ADDR   0x00090000
+#define KERNEL_CMDLINE_ADDR  0x00099000
+
+int speaker_data_on;
+int dummy_refresh_clock;
+static fdctrl_t *floppy_controller;
+static RTCState *rtc_state;
+static PITState *pit;
+
+static void ioport80_write(void *opaque, uint32_t addr, uint32_t data)
+{
+}
+
+/* MSDOS compatibility mode FPU exception support */
+/* XXX: add IGNNE support */
+void cpu_set_ferr(CPUX86State *s)
+{
+    pic_set_irq(13, 1);
+}
+
+static void ioportF0_write(void *opaque, uint32_t addr, uint32_t data)
+{
+    pic_set_irq(13, 0);
+}
+
+/* TSC handling */
+
+uint64_t cpu_get_tsc(CPUX86State *env)
+{
+    return qemu_get_clock(vm_clock);
+}
+
+/* PC cmos mappings */
+
+#define REG_EQUIPMENT_BYTE          0x14
+#define REG_IBM_CENTURY_BYTE        0x32
+#define REG_IBM_PS2_CENTURY_BYTE    0x37
+
+
+static inline int to_bcd(RTCState *s, int a)
+{
+    return ((a / 10) << 4) | (a % 10);
+}
+
+static int cmos_get_fd_drive_type(int fd0)
+{
+    int val;
+
+    switch (fd0) {
+    case 0:
+        /* 1.44 Mb 3"5 drive */
+        val = 4;
+        break;
+    case 1:
+        /* 2.88 Mb 3"5 drive */
+        val = 5;
+        break;
+    case 2:
+        /* 1.2 Mb 5"5 drive */
+        val = 2;
+        break;
+    default:
+        val = 0;
+        break;
+    }
+    return val;
+}
+
+static void cmos_init_hd(int type_ofs, int info_ofs, BlockDriverState *hd) 
+{
+    RTCState *s = rtc_state;
+    int cylinders, heads, sectors;
+    bdrv_get_geometry_hint(hd, &cylinders, &heads, &sectors);
+    rtc_set_memory(s, type_ofs, 47);
+    rtc_set_memory(s, info_ofs, cylinders);
+    rtc_set_memory(s, info_ofs + 1, cylinders >> 8);
+    rtc_set_memory(s, info_ofs + 2, heads);
+    rtc_set_memory(s, info_ofs + 3, 0xff);
+    rtc_set_memory(s, info_ofs + 4, 0xff);
+    rtc_set_memory(s, info_ofs + 5, 0xc0 | ((heads > 8) << 3));
+    rtc_set_memory(s, info_ofs + 6, cylinders);
+    rtc_set_memory(s, info_ofs + 7, cylinders >> 8);
+    rtc_set_memory(s, info_ofs + 8, sectors);
+}
+
+/* hd_table must contain 4 block drivers */
+static void cmos_init(int ram_size, int boot_device, BlockDriverState **hd_table)
+{
+    RTCState *s = rtc_state;
+    int val;
+    int fd0, fd1, nb;
+    time_t ti;
+    struct tm *tm;
+    int i;
+
+    /* set the CMOS date */
+    time(&ti);
+    if (rtc_utc)
+        tm = gmtime(&ti);
+    else
+        tm = localtime(&ti);
+    rtc_set_date(s, tm);
+
+    val = to_bcd(s, (tm->tm_year / 100) + 19);
+    rtc_set_memory(s, REG_IBM_CENTURY_BYTE, val);
+    rtc_set_memory(s, REG_IBM_PS2_CENTURY_BYTE, val);
+
+    /* various important CMOS locations needed by PC/Bochs bios */
+
+    /* memory size */
+    val = 640; /* base memory in K */
+    rtc_set_memory(s, 0x15, val);
+    rtc_set_memory(s, 0x16, val >> 8);
+
+    val = (ram_size / 1024) - 1024;
+    if (val > 65535)
+        val = 65535;
+    rtc_set_memory(s, 0x17, val);
+    rtc_set_memory(s, 0x18, val >> 8);
+    rtc_set_memory(s, 0x30, val);
+    rtc_set_memory(s, 0x31, val >> 8);
+
+    if (ram_size > (16 * 1024 * 1024))
+        val = (ram_size / 65536) - ((16 * 1024 * 1024) / 65536);
+    else
+        val = 0;
+    if (val > 65535)
+        val = 65535;
+    rtc_set_memory(s, 0x34, val);
+    rtc_set_memory(s, 0x35, val >> 8);
+    
+    switch(boot_device) {
+    case 'a':
+    case 'b':
+        rtc_set_memory(s, 0x3d, 0x01); /* floppy boot */
+        break;
+    default:
+    case 'c':
+        rtc_set_memory(s, 0x3d, 0x02); /* hard drive boot */
+        break;
+    case 'd':
+        rtc_set_memory(s, 0x3d, 0x03); /* CD-ROM boot */
+        break;
+    }
+
+    /* floppy type */
+
+    fd0 = fdctrl_get_drive_type(floppy_controller, 0);
+    fd1 = fdctrl_get_drive_type(floppy_controller, 1);
+
+    val = (cmos_get_fd_drive_type(fd0) << 4) | cmos_get_fd_drive_type(fd1);
+    rtc_set_memory(s, 0x10, val);
+    
+    val = 0;
+    nb = 0;
+    if (fd0 < 3)
+        nb++;
+    if (fd1 < 3)
+        nb++;
+    switch (nb) {
+    case 0:
+        break;
+    case 1:
+        val |= 0x01; /* 1 drive, ready for boot */
+        break;
+    case 2:
+        val |= 0x41; /* 2 drives, ready for boot */
+        break;
+    }
+    val |= 0x02; /* FPU is there */
+    val |= 0x04; /* PS/2 mouse installed */
+    rtc_set_memory(s, REG_EQUIPMENT_BYTE, val);
+
+    /* hard drives */
+
+    rtc_set_memory(s, 0x12, (hd_table[0] ? 0xf0 : 0) | (hd_table[1] ? 0x0f : 0));
+    if (hd_table[0])
+        cmos_init_hd(0x19, 0x1b, hd_table[0]);
+    if (hd_table[1]) 
+        cmos_init_hd(0x1a, 0x24, hd_table[1]);
+
+    val = 0;
+    for (i = 0; i < 4; i++) {
+        if (hd_table[i]) {
+            int cylinders, heads, sectors;
+            uint8_t translation;
+            /* NOTE: bdrv_get_geometry_hint() returns the geometry
+               that the hard disk returns. It is always such that: 1 <=
+               sects <= 63, 1 <= heads <= 16, 1 <= cylinders <=
+               16383. The BIOS geometry can be different. */
+            bdrv_get_geometry_hint(hd_table[i], &cylinders, &heads, &sectors);
+            if (cylinders <= 1024 && heads <= 16 && sectors <= 63) {
+                /* No translation. */
+                translation = 0;
+            } else {
+                /* LBA translation. */
+                translation = 1;
+            }
+            val |= translation << (i * 2);
+        }
+    }
+    rtc_set_memory(s, 0x39, val);
+
+    /* Disable check of 0x55AA signature on the last two bytes of
+       first sector of disk. XXX: make it the default ? */
+    //    rtc_set_memory(s, 0x38, 1);
+}
+
+static void speaker_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+{
+    speaker_data_on = (val >> 1) & 1;
+    pit_set_gate(pit, 2, val & 1);
+}
+
+static uint32_t speaker_ioport_read(void *opaque, uint32_t addr)
+{
+    int out;
+    out = pit_get_out(pit, 2, qemu_get_clock(vm_clock));
+    dummy_refresh_clock ^= 1;
+    return (speaker_data_on << 1) | pit_get_gate(pit, 2) | (out << 5) |
+      (dummy_refresh_clock << 4);
+}
+
+static void ioport92_write(void *opaque, uint32_t addr, uint32_t val)
+{
+    cpu_x86_set_a20(cpu_single_env, (val >> 1) & 1);
+    /* XXX: bit 0 is fast reset */
+}
+
+static uint32_t ioport92_read(void *opaque, uint32_t addr)
+{
+    return ((cpu_single_env->a20_mask >> 20) & 1) << 1;
+}
+
+/***********************************************************/
+/* Bochs BIOS debug ports */
+
+void bochs_bios_write(void *opaque, uint32_t addr, uint32_t val)
+{
+    static const char shutdown_str[8] = "Shutdown";
+    static int shutdown_index = 0;
+    
+    switch(addr) {
+        /* Bochs BIOS messages */
+    case 0x400:
+    case 0x401:
+        fprintf(stderr, "BIOS panic at rombios.c, line %d\n", val);
+        exit(1);
+    case 0x402:
+    case 0x403:
+#ifdef DEBUG_BIOS
+        fprintf(stderr, "%c", val);
+#endif
+        break;
+    case 0x8900:
+        /* same as Bochs power off */
+        if (val == shutdown_str[shutdown_index]) {
+            shutdown_index++;
+            if (shutdown_index == 8) {
+                shutdown_index = 0;
+                qemu_system_shutdown_request();
+            }
+        } else {
+            shutdown_index = 0;
+        }
+        break;
+
+        /* LGPL'ed VGA BIOS messages */
+    case 0x501:
+    case 0x502:
+        fprintf(stderr, "VGA BIOS panic, line %d\n", val);
+        exit(1);
+    case 0x500:
+    case 0x503:
+#ifdef DEBUG_BIOS
+        fprintf(stderr, "%c", val);
+#endif
+        break;
+    }
+}
+
+void bochs_bios_init(void)
+{
+    register_ioport_write(0x400, 1, 2, bochs_bios_write, NULL);
+    register_ioport_write(0x401, 1, 2, bochs_bios_write, NULL);
+    register_ioport_write(0x402, 1, 1, bochs_bios_write, NULL);
+    register_ioport_write(0x403, 1, 1, bochs_bios_write, NULL);
+    register_ioport_write(0x8900, 1, 1, bochs_bios_write, NULL);
+
+    register_ioport_write(0x501, 1, 2, bochs_bios_write, NULL);
+    register_ioport_write(0x502, 1, 2, bochs_bios_write, NULL);
+    register_ioport_write(0x500, 1, 1, bochs_bios_write, NULL);
+    register_ioport_write(0x503, 1, 1, bochs_bios_write, NULL);
+}
+
+
+int load_kernel(const char *filename, uint8_t *addr, 
+                uint8_t *real_addr)
+{
+    int fd, size;
+    int setup_sects;
+
+    fd = open(filename, O_RDONLY | O_BINARY);
+    if (fd < 0)
+        return -1;
+
+    /* load 16 bit code */
+    if (read(fd, real_addr, 512) != 512)
+        goto fail;
+    setup_sects = real_addr[0x1F1];
+    if (!setup_sects)
+        setup_sects = 4;
+    if (read(fd, real_addr + 512, setup_sects * 512) != 
+        setup_sects * 512)
+        goto fail;
+    
+    /* load 32 bit code */
+    size = read(fd, addr, 16 * 1024 * 1024);
+    if (size < 0)
+        goto fail;
+    close(fd);
+    return size;
+ fail:
+    close(fd);
+    return -1;
+}
+
+static const int ide_iobase[2] = { 0x1f0, 0x170 };
+static const int ide_iobase2[2] = { 0x3f6, 0x376 };
+static const int ide_irq[2] = { 14, 15 };
+
+#define NE2000_NB_MAX 6
+
+static int ne2000_io[NE2000_NB_MAX] = { 0x300, 0x320, 0x340, 0x360, 0x280, 0x380 };
+static int ne2000_irq[NE2000_NB_MAX] = { 9, 10, 11, 3, 4, 5 };
+
+static int serial_io[MAX_SERIAL_PORTS] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
+static int serial_irq[MAX_SERIAL_PORTS] = { 4, 3, 4, 3 };
+
+#define NOBIOS 1
+
+/* PC hardware initialisation */
+void pc_init(int ram_size, int vga_ram_size, int boot_device,
+             DisplayState *ds, const char **fd_filename, int snapshot,
+             const char *kernel_filename, const char *kernel_cmdline,
+             const char *initrd_filename)
+{
+    char buf[1024];
+    int ret, linux_boot, initrd_size, i, nb_nics1;
+    unsigned long bios_offset, vga_bios_offset;
+    int bios_size, isa_bios_size;
+    PCIBus *pci_bus;
+    
+    linux_boot = (kernel_filename != NULL);
+
+    /* allocate RAM */
+//    cpu_register_physical_memory(0, ram_size, 0);
+
+#ifndef NOBIOS
+    /* BIOS load */
+    bios_offset = ram_size + vga_ram_size;
+    vga_bios_offset = bios_offset + 256 * 1024;
+
+    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
+    bios_size = get_image_size(buf);
+    if (bios_size <= 0 || 
+        (bios_size % 65536) != 0 ||
+        bios_size > (256 * 1024)) {
+        goto bios_error;
+    }
+    ret = load_image(buf, phys_ram_base + bios_offset);
+    if (ret != bios_size) {
+    bios_error:
+        fprintf(stderr, "qemu: could not load PC bios '%s'\n", buf);
+        exit(1);
+    }
+
+    /* VGA BIOS load */
+    if (cirrus_vga_enabled) {
+        snprintf(buf, sizeof(buf), "%s/%s", bios_dir, VGABIOS_CIRRUS_FILENAME);
+    } else {
+        snprintf(buf, sizeof(buf), "%s/%s", bios_dir, VGABIOS_FILENAME);
+    }
+    ret = load_image(buf, phys_ram_base + vga_bios_offset);
+#endif 
+
+    /* setup basic memory access */
+    cpu_register_physical_memory(0xc0000, 0x10000, 
+                                 vga_bios_offset | IO_MEM_ROM);
+
+#ifndef NOBIOS
+    /* map the last 128KB of the BIOS in ISA space */
+    isa_bios_size = bios_size;
+    if (isa_bios_size > (128 * 1024))
+        isa_bios_size = 128 * 1024;
+    cpu_register_physical_memory(0xd0000, (192 * 1024) - isa_bios_size, 
+                                 IO_MEM_UNASSIGNED);
+    cpu_register_physical_memory(0x100000 - isa_bios_size, 
+                                 isa_bios_size, 
+                                 (bios_offset + bios_size - isa_bios_size) | IO_MEM_ROM);
+    /* map all the bios at the top of memory */
+    cpu_register_physical_memory((uint32_t)(-bios_size), 
+                                 bios_size, bios_offset | IO_MEM_ROM);
+    
+    bochs_bios_init();
+#endif
+
+    if (linux_boot) {
+        uint8_t bootsect[512];
+        uint8_t old_bootsect[512];
+
+        if (bs_table[0] == NULL) {
+            fprintf(stderr, "A disk image must be given for 'hda' when booting a Linux kernel\n");
+            exit(1);
+        }
+        snprintf(buf, sizeof(buf), "%s/%s", bios_dir, LINUX_BOOT_FILENAME);
+        ret = load_image(buf, bootsect);
+        if (ret != sizeof(bootsect)) {
+            fprintf(stderr, "qemu: could not load linux boot sector '%s'\n",
+                    buf);
+            exit(1);
+        }
+
+        if (bdrv_read(bs_table[0], 0, old_bootsect, 1) >= 0) {
+            /* copy the MSDOS partition table */
+            memcpy(bootsect + 0x1be, old_bootsect + 0x1be, 0x40);
+        }
+
+        bdrv_set_boot_sector(bs_table[0], bootsect, sizeof(bootsect));
+
+        /* now we can load the kernel */
+        ret = load_kernel(kernel_filename, 
+                          phys_ram_base + KERNEL_LOAD_ADDR,
+                          phys_ram_base + KERNEL_PARAMS_ADDR);
+        if (ret < 0) {
+            fprintf(stderr, "qemu: could not load kernel '%s'\n", 
+                    kernel_filename);
+            exit(1);
+        }
+        
+        /* load initrd */
+        initrd_size = 0;
+        if (initrd_filename) {
+            initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR);
+            if (initrd_size < 0) {
+                fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", 
+                        initrd_filename);
+                exit(1);
+            }
+        }
+        if (initrd_size > 0) {
+            stl_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x218, INITRD_LOAD_ADDR);
+            stl_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x21c, initrd_size);
+        }
+        pstrcpy(phys_ram_base + KERNEL_CMDLINE_ADDR, 4096,
+                kernel_cmdline);
+        stw_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x20, 0xA33F);
+        stw_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x22,
+                KERNEL_CMDLINE_ADDR - KERNEL_PARAMS_ADDR);
+        /* loader type */
+        stw_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x210, 0x01);
+    }
+
+    if (pci_enabled) {
+        pci_bus = i440fx_init();
+        piix3_init(pci_bus);
+    } else {
+        pci_bus = NULL;
+    }
+
+    /* init basic PC hardware */
+    register_ioport_write(0x80, 1, 1, ioport80_write, NULL);
+
+    register_ioport_write(0xf0, 1, 1, ioportF0_write, NULL);
+
+#ifdef NOBIOS
+    cirrus_vga_enabled = 0;
+#endif
+    if (cirrus_vga_enabled) {
+        if (pci_enabled) {
+            pci_cirrus_vga_init(pci_bus, 
+                                ds, phys_ram_base + ram_size, ram_size, 
+                                vga_ram_size);
+        } else {
+            isa_cirrus_vga_init(ds, phys_ram_base + ram_size, ram_size, 
+                                vga_ram_size);
+        }
+    } else {
+        vga_initialize(pci_bus, ds, phys_ram_base + ram_size, ram_size, 
+                       vga_ram_size);
+    }
+
+    rtc_state = rtc_init(0x70, 8);
+    register_ioport_read(0x61, 1, 1, speaker_ioport_read, NULL);
+    register_ioport_write(0x61, 1, 1, speaker_ioport_write, NULL);
+
+    register_ioport_read(0x92, 1, 1, ioport92_read, NULL);
+    register_ioport_write(0x92, 1, 1, ioport92_write, NULL);
+
+    pic_init();
+    pit = pit_init(0x40, 0);
+
+    for(i = 0; i < MAX_SERIAL_PORTS; i++) {
+        if (serial_hds[i]) {
+            serial_init(serial_io[i], serial_irq[i], serial_hds[i]);
+        }
+    }
+
+    if (pci_enabled) {
+        for(i = 0; i < nb_nics; i++) {
+            pci_ne2000_init(pci_bus, &nd_table[i]);
+        }
+        pci_piix3_ide_init(pci_bus, bs_table);
+    } else {
+        nb_nics1 = nb_nics;
+        if (nb_nics1 > NE2000_NB_MAX)
+            nb_nics1 = NE2000_NB_MAX;
+        for(i = 0; i < nb_nics1; i++) {
+            isa_ne2000_init(ne2000_io[i], ne2000_irq[i], &nd_table[i]);
+        }
+
+        for(i = 0; i < 2; i++) {
+            isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i],
+                         bs_table[2 * i], bs_table[2 * i + 1]);
+        }
+    }
+
+    kbd_init();
+    DMA_init(0);
+
+    floppy_controller = fdctrl_init(6, 2, 0, 0x3f0, fd_table);
+
+    cmos_init(ram_size, boot_device, bs_table);
+
+    /* must be done after all PCI devices are instanciated */
+    /* XXX: should be done in the Bochs BIOS */
+    if (pci_enabled) {
+        pci_bios_init();
+    }
+}
diff --git a/tools/ioemu/hw/pci.c b/tools/ioemu/hw/pci.c
new file mode 100644 (file)
index 0000000..2fed66f
--- /dev/null
@@ -0,0 +1,1524 @@
+/*
+ * QEMU PCI bus manager
+ *
+ * Copyright (c) 2004 Fabrice Bellard
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+
+//#define DEBUG_PCI
+
+#define PCI_VENDOR_ID          0x00    /* 16 bits */
+#define PCI_DEVICE_ID          0x02    /* 16 bits */
+#define PCI_COMMAND            0x04    /* 16 bits */
+#define  PCI_COMMAND_IO                0x1     /* Enable response in I/O space */
+#define  PCI_COMMAND_MEMORY    0x2     /* Enable response in Memory space */
+#define PCI_CLASS_DEVICE        0x0a    /* Device class */
+#define PCI_INTERRUPT_LINE     0x3c    /* 8 bits */
+#define PCI_INTERRUPT_PIN      0x3d    /* 8 bits */
+#define PCI_MIN_GNT            0x3e    /* 8 bits */
+#define PCI_MAX_LAT            0x3f    /* 8 bits */
+
+/* just used for simpler irq handling. */
+#define PCI_DEVICES_MAX 64
+#define PCI_IRQ_WORDS   ((PCI_DEVICES_MAX + 31) / 32)
+
+struct PCIBus {
+    int bus_num;
+    int devfn_min;
+    void (*set_irq)(PCIDevice *pci_dev, int irq_num, int level);
+    uint32_t config_reg; /* XXX: suppress */
+    openpic_t *openpic; /* XXX: suppress */
+    PCIDevice *devices[256];
+};
+
+target_phys_addr_t pci_mem_base;
+static int pci_irq_index;
+static uint32_t pci_irq_levels[4][PCI_IRQ_WORDS];
+static PCIBus *first_bus;
+
+static PCIBus *pci_register_bus(void)
+{
+    PCIBus *bus;
+    bus = qemu_mallocz(sizeof(PCIBus));
+    first_bus = bus;
+    return bus;
+}
+
+void generic_pci_save(QEMUFile* f, void *opaque)
+{
+    PCIDevice* s=(PCIDevice*)opaque;
+
+    qemu_put_buffer(f, s->config, 256);
+}
+
+int generic_pci_load(QEMUFile* f, void *opaque, int version_id)
+{
+    PCIDevice* s=(PCIDevice*)opaque;
+
+    if (version_id != 1)
+        return -EINVAL;
+
+    qemu_get_buffer(f, s->config, 256);
+    return 0;
+}
+
+/* -1 for devfn means auto assign */
+PCIDevice *pci_register_device(PCIBus *bus, const char *name, 
+                               int instance_size, int devfn,
+                               PCIConfigReadFunc *config_read, 
+                               PCIConfigWriteFunc *config_write)
+{
+    PCIDevice *pci_dev;
+
+    if (pci_irq_index >= PCI_DEVICES_MAX)
+        return NULL;
+    
+    if (devfn < 0) {
+        for(devfn = bus->devfn_min ; devfn < 256; devfn += 8) {
+            if (!bus->devices[devfn])
+                goto found;
+        }
+        return NULL;
+    found: ;
+    }
+    pci_dev = qemu_mallocz(instance_size);
+    if (!pci_dev)
+        return NULL;
+    pci_dev->bus = bus;
+    pci_dev->devfn = devfn;
+    pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
+
+    if (!config_read)
+        config_read = pci_default_read_config;
+    if (!config_write)
+        config_write = pci_default_write_config;
+    pci_dev->config_read = config_read;
+    pci_dev->config_write = config_write;
+    pci_dev->irq_index = pci_irq_index++;
+    bus->devices[devfn] = pci_dev;
+    return pci_dev;
+}
+
+void pci_register_io_region(PCIDevice *pci_dev, int region_num, 
+                            uint32_t size, int type, 
+                            PCIMapIORegionFunc *map_func)
+{
+    PCIIORegion *r;
+
+    if ((unsigned int)region_num >= PCI_NUM_REGIONS)
+        return;
+    r = &pci_dev->io_regions[region_num];
+    r->addr = -1;
+    r->size = size;
+    r->type = type;
+    r->map_func = map_func;
+}
+
+static void pci_addr_writel(void* opaque, uint32_t addr, uint32_t val)
+{
+    PCIBus *s = opaque;
+    s->config_reg = val;
+}
+
+static uint32_t pci_addr_readl(void* opaque, uint32_t addr)
+{
+    PCIBus *s = opaque;
+    return s->config_reg;
+}
+
+static void pci_update_mappings(PCIDevice *d)
+{
+    PCIIORegion *r;
+    int cmd, i;
+    uint32_t last_addr, new_addr, config_ofs;
+    
+    cmd = le16_to_cpu(*(uint16_t *)(d->config + PCI_COMMAND));
+    for(i = 0; i < PCI_NUM_REGIONS; i++) {
+        r = &d->io_regions[i];
+        if (i == PCI_ROM_SLOT) {
+            config_ofs = 0x30;
+        } else {
+            config_ofs = 0x10 + i * 4;
+        }
+        if (r->size != 0) {
+            if (r->type & PCI_ADDRESS_SPACE_IO) {
+                if (cmd & PCI_COMMAND_IO) {
+                    new_addr = le32_to_cpu(*(uint32_t *)(d->config + 
+                                                         config_ofs));
+                    new_addr = new_addr & ~(r->size - 1);
+                    last_addr = new_addr + r->size - 1;
+                    /* NOTE: we have only 64K ioports on PC */
+                    if (last_addr <= new_addr || new_addr == 0 ||
+                        last_addr >= 0x10000) {
+                        new_addr = -1;
+                    }
+                } else {
+                    new_addr = -1;
+                }
+            } else {
+                if (cmd & PCI_COMMAND_MEMORY) {
+                    new_addr = le32_to_cpu(*(uint32_t *)(d->config + 
+                                                         config_ofs));
+                    /* the ROM slot has a specific enable bit */
+                    if (i == PCI_ROM_SLOT && !(new_addr & 1))
+                        goto no_mem_map;
+                    new_addr = new_addr & ~(r->size - 1);
+                    last_addr = new_addr + r->size - 1;
+                    /* NOTE: we do not support wrapping */
+                    /* XXX: as we cannot support really dynamic
+                       mappings, we handle specific values as invalid
+                       mappings. */
+                    if (last_addr <= new_addr || new_addr == 0 ||
+                        last_addr == -1) {
+                        new_addr = -1;
+                    }
+                } else {
+                no_mem_map:
+                    new_addr = -1;
+                }
+            }
+            /* now do the real mapping */
+            if (new_addr != r->addr) {
+                if (r->addr != -1) {
+                    if (r->type & PCI_ADDRESS_SPACE_IO) {
+                        int class;
+                        /* NOTE: specific hack for IDE in PC case:
+                           only one byte must be mapped. */
+                        class = d->config[0x0a] | (d->config[0x0b] << 8);
+                        if (class == 0x0101 && r->size == 4) {
+                            isa_unassign_ioport(r->addr + 2, 1);
+                        } else {
+                            isa_unassign_ioport(r->addr, r->size);
+                        }
+                    } else {
+                        cpu_register_physical_memory(r->addr + pci_mem_base, 
+                                                     r->size, 
+                                                     IO_MEM_UNASSIGNED);
+                    }
+                }
+                r->addr = new_addr;
+                if (r->addr != -1) {
+                    r->map_func(d, i, r->addr, r->size, r->type);
+                }
+            }
+        }
+    }
+}
+
+uint32_t pci_default_read_config(PCIDevice *d, 
+                                 uint32_t address, int len)
+{
+    uint32_t val;
+    switch(len) {
+    case 1:
+        val = d->config[address];
+        break;
+    case 2:
+        val = le16_to_cpu(*(uint16_t *)(d->config + address));
+        break;
+    default:
+    case 4:
+        val = le32_to_cpu(*(uint32_t *)(d->config + address));
+        break;
+    }
+    return val;
+}
+
+void pci_default_write_config(PCIDevice *d, 
+                              uint32_t address, uint32_t val, int len)
+{
+    int can_write, i;
+    uint32_t end, addr;
+
+    if (len == 4 && ((address >= 0x10 && address < 0x10 + 4 * 6) || 
+                     (address >= 0x30 && address < 0x34))) {
+        PCIIORegion *r;
+        int reg;
+
+        if ( address >= 0x30 ) {
+            reg = PCI_ROM_SLOT;
+        }else{
+            reg = (address - 0x10) >> 2;
+        }
+        r = &d->io_regions[reg];
+        if (r->size == 0)
+            goto default_config;
+        /* compute the stored value */
+        if (reg == PCI_ROM_SLOT) {
+            /* keep ROM enable bit */
+            val &= (~(r->size - 1)) | 1;
+        } else {
+            val &= ~(r->size - 1);
+            val |= r->type;
+        }
+        *(uint32_t *)(d->config + address) = cpu_to_le32(val);
+        pci_update_mappings(d);
+        return;
+    }
+ default_config:
+    /* not efficient, but simple */
+    addr = address;
+    for(i = 0; i < len; i++) {
+        /* default read/write accesses */
+        switch(d->config[0x0e]) {
+        case 0x00:
+        case 0x80:
+            switch(addr) {
+            case 0x00:
+            case 0x01:
+            case 0x02:
+            case 0x03:
+            case 0x08:
+            case 0x09:
+            case 0x0a:
+            case 0x0b:
+            case 0x0e:
+            case 0x10 ... 0x27: /* base */
+            case 0x30 ... 0x33: /* rom */
+            case 0x3d:
+                can_write = 0;
+                break;
+            default:
+                can_write = 1;
+                break;
+            }
+            break;
+        default:
+        case 0x01:
+            switch(addr) {
+            case 0x00:
+            case 0x01:
+            case 0x02:
+            case 0x03:
+            case 0x08:
+            case 0x09:
+            case 0x0a:
+            case 0x0b:
+            case 0x0e:
+            case 0x38 ... 0x3b: /* rom */
+            case 0x3d:
+                can_write = 0;
+                break;
+            default:
+                can_write = 1;
+                break;
+            }
+            break;
+        }
+        if (can_write) {
+            d->config[addr] = val;
+        }
+        addr++;
+        val >>= 8;
+    }
+
+    end = address + len;
+    if (end > PCI_COMMAND && address < (PCI_COMMAND + 2)) {
+        /* if the command register is modified, we must modify the mappings */
+        pci_update_mappings(d);
+    }
+}
+
+static void pci_data_write(void *opaque, uint32_t addr, 
+                           uint32_t val, int len)
+{
+    PCIBus *s = opaque;
+    PCIDevice *pci_dev;
+    int config_addr, bus_num;
+    
+#if defined(DEBUG_PCI) && 0
+    printf("pci_data_write: addr=%08x val=%08x len=%d\n",
+           s->config_reg, val, len);
+#endif
+    if (!(s->config_reg & (1 << 31))) {
+        return;
+    }
+    if ((s->config_reg & 0x3) != 0) {
+        return;
+    }
+    bus_num = (s->config_reg >> 16) & 0xff;
+    if (bus_num != 0)
+        return;
+    pci_dev = s->devices[(s->config_reg >> 8) & 0xff];
+    if (!pci_dev)
+        return;
+    config_addr = (s->config_reg & 0xfc) | (addr & 3);
+#if defined(DEBUG_PCI)
+    printf("pci_config_write: %s: addr=%02x val=%08x len=%d\n",
+           pci_dev->name, config_addr, val, len);
+#endif
+    pci_dev->config_write(pci_dev, config_addr, val, len);
+}
+
+static uint32_t pci_data_read(void *opaque, uint32_t addr, 
+                              int len)
+{
+    PCIBus *s = opaque;
+    PCIDevice *pci_dev;
+    int config_addr, bus_num;
+    uint32_t val;
+
+    if (!(s->config_reg & (1 << 31)))
+        goto fail;
+    if ((s->config_reg & 0x3) != 0)
+        goto fail;
+    bus_num = (s->config_reg >> 16) & 0xff;
+    if (bus_num != 0)
+        goto fail;
+    pci_dev = s->devices[(s->config_reg >> 8) & 0xff];
+    if (!pci_dev) {
+    fail:
+        switch(len) {
+        case 1:
+            val = 0xff;
+            break;
+        case 2:
+            val = 0xffff;
+            break;
+        default:
+        case 4:
+            val = 0xffffffff;
+            break;
+        }
+        goto the_end;
+    }
+    config_addr = (s->config_reg & 0xfc) | (addr & 3);
+    val = pci_dev->config_read(pci_dev, config_addr, len);
+#if defined(DEBUG_PCI)
+    printf("pci_config_read: %s: addr=%02x val=%08x len=%d\n",
+           pci_dev->name, config_addr, val, len);
+#endif
+ the_end:
+#if defined(DEBUG_PCI) && 0
+    printf("pci_data_read: addr=%08x val=%08x len=%d\n",
+           s->config_reg, val, len);
+#endif
+    return val;
+}
+
+static void pci_data_writeb(void* opaque, uint32_t addr, uint32_t val)
+{
+    pci_data_write(opaque, addr, val, 1);
+}
+
+static void pci_data_writew(void* opaque, uint32_t addr, uint32_t val)
+{
+    pci_data_write(opaque, addr, val, 2);
+}
+
+static void pci_data_writel(void* opaque, uint32_t addr, uint32_t val)
+{
+    pci_data_write(opaque, addr, val, 4);
+}
+
+static uint32_t pci_data_readb(void* opaque, uint32_t addr)
+{
+    return pci_data_read(opaque, addr, 1);
+}
+
+static uint32_t pci_data_readw(void* opaque, uint32_t addr)
+{
+    return pci_data_read(opaque, addr, 2);
+}
+
+static uint32_t pci_data_readl(void* opaque, uint32_t addr)
+{
+    return pci_data_read(opaque, addr, 4);
+}
+
+/* i440FX PCI bridge */
+
+static void piix3_set_irq(PCIDevice *pci_dev, int irq_num, int level);
+
+PCIBus *i440fx_init(void)
+{
+    PCIBus *s;
+    PCIDevice *d;
+
+    s = pci_register_bus();
+    s->set_irq = piix3_set_irq;
+
+    register_ioport_write(0xcf8, 4, 4, pci_addr_writel, s);
+    register_ioport_read(0xcf8, 4, 4, pci_addr_readl, s);
+
+    register_ioport_write(0xcfc, 4, 1, pci_data_writeb, s);
+    register_ioport_write(0xcfc, 4, 2, pci_data_writew, s);
+    register_ioport_write(0xcfc, 4, 4, pci_data_writel, s);
+    register_ioport_read(0xcfc, 4, 1, pci_data_readb, s);
+    register_ioport_read(0xcfc, 4, 2, pci_data_readw, s);
+    register_ioport_read(0xcfc, 4, 4, pci_data_readl, s);
+
+    d = pci_register_device(s, "i440FX", sizeof(PCIDevice), 0, 
+                            NULL, NULL);
+
+    d->config[0x00] = 0x86; // vendor_id
+    d->config[0x01] = 0x80;
+    d->config[0x02] = 0x37; // device_id
+    d->config[0x03] = 0x12;
+    d->config[0x08] = 0x02; // revision
+    d->config[0x0a] = 0x00; // class_sub = host2pci
+    d->config[0x0b] = 0x06; // class_base = PCI_bridge
+    d->config[0x0e] = 0x00; // header_type
+    return s;
+}
+
+/* PIIX3 PCI to ISA bridge */
+
+typedef struct PIIX3State {
+    PCIDevice dev;
+} PIIX3State;
+
+PIIX3State *piix3_state;
+
+/* return the global irq number corresponding to a given device irq
+   pin. We could also use the bus number to have a more precise
+   mapping. */
+static inline int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
+{
+    int slot_addend;
+    slot_addend = (pci_dev->devfn >> 3);
+    return (irq_num + slot_addend) & 3;
+}
+
+static void piix3_set_irq(PCIDevice *pci_dev, int irq_num, int level)
+{
+    int irq_index, shift, pic_irq, pic_level;
+    uint32_t *p;
+
+    irq_num = pci_slot_get_pirq(pci_dev, irq_num);
+    irq_index = pci_dev->irq_index;
+    p = &pci_irq_levels[irq_num][irq_index >> 5];
+    shift = (irq_index & 0x1f);
+    *p = (*p & ~(1 << shift)) | (level << shift);
+
+    /* now we change the pic irq level according to the piix irq mappings */
+    pic_irq = piix3_state->dev.config[0x60 + irq_num];
+    if (pic_irq < 16) {
+        /* the pic level is the logical OR of all the PCI irqs mapped
+           to it */
+        pic_level = 0;
+#if (PCI_IRQ_WORDS == 2)
+        pic_level = ((pci_irq_levels[irq_num][0] | 
+                      pci_irq_levels[irq_num][1]) != 0);
+#else
+        {
+            int i;
+            pic_level = 0;
+            for(i = 0; i < PCI_IRQ_WORDS; i++) {
+                if (pci_irq_levels[irq_num][i]) {
+                    pic_level = 1;
+                    break;
+                }
+            }
+        }
+#endif
+        pic_set_irq(pic_irq, pic_level);
+    }
+}
+
+static void piix3_reset(PIIX3State *d)
+{
+    uint8_t *pci_conf = d->dev.config;
+
+    pci_conf[0x04] = 0x07; // master, memory and I/O
+    pci_conf[0x05] = 0x00;
+    pci_conf[0x06] = 0x00;
+    pci_conf[0x07] = 0x02; // PCI_status_devsel_medium
+    pci_conf[0x4c] = 0x4d;
+    pci_conf[0x4e] = 0x03;
+    pci_conf[0x4f] = 0x00;
+    pci_conf[0x60] = 0x80;
+    pci_conf[0x69] = 0x02;
+    pci_conf[0x70] = 0x80;
+    pci_conf[0x76] = 0x0c;
+    pci_conf[0x77] = 0x0c;
+    pci_conf[0x78] = 0x02;
+    pci_conf[0x79] = 0x00;
+    pci_conf[0x80] = 0x00;
+    pci_conf[0x82] = 0x00;
+    pci_conf[0xa0] = 0x08;
+    pci_conf[0xa0] = 0x08;
+    pci_conf[0xa2] = 0x00;
+    pci_conf[0xa3] = 0x00;
+    pci_conf[0xa4] = 0x00;
+    pci_conf[0xa5] = 0x00;
+    pci_conf[0xa6] = 0x00;
+    pci_conf[0xa7] = 0x00;
+    pci_conf[0xa8] = 0x0f;
+    pci_conf[0xaa] = 0x00;
+    pci_conf[0xab] = 0x00;
+    pci_conf[0xac] = 0x00;
+    pci_conf[0xae] = 0x00;
+}
+
+void piix3_init(PCIBus *bus)
+{
+    PIIX3State *d;
+    uint8_t *pci_conf;
+
+    d = (PIIX3State *)pci_register_device(bus, "PIIX3", sizeof(PIIX3State),
+                                          -1, NULL, NULL);
+    register_savevm("PIIX3", 0, 1, generic_pci_save, generic_pci_load, d);
+
+    piix3_state = d;
+    pci_conf = d->dev.config;
+
+    pci_conf[0x00] = 0x86; // Intel
+    pci_conf[0x01] = 0x80;
+    pci_conf[0x02] = 0x00; // 82371SB PIIX3 PCI-to-ISA bridge (Step A1)
+    pci_conf[0x03] = 0x70;
+    pci_conf[0x0a] = 0x01; // class_sub = PCI_ISA
+    pci_conf[0x0b] = 0x06; // class_base = PCI_bridge
+    pci_conf[0x0e] = 0x80; // header_type = PCI_multifunction, generic
+
+    piix3_reset(d);
+}
+
+/* PREP pci init */
+
+static inline void set_config(PCIBus *s, target_phys_addr_t addr)
+{
+    int devfn, i;
+
+    for(i = 0; i < 11; i++) {
+        if ((addr & (1 << (11 + i))) != 0)
+            break;
+    }
+    devfn = ((addr >> 8) & 7) | (i << 3);
+    s->config_reg = 0x80000000 | (addr & 0xfc) | (devfn << 8);
+}
+
+static void PPC_PCIIO_writeb (void *opaque, target_phys_addr_t addr, uint32_t val)
+{
+    PCIBus *s = opaque;
+    set_config(s, addr);
+    pci_data_write(s, addr, val, 1);
+}
+
+static void PPC_PCIIO_writew (void *opaque, target_phys_addr_t addr, uint32_t val)
+{
+    PCIBus *s = opaque;
+    set_config(s, addr);
+#ifdef TARGET_WORDS_BIGENDIAN
+    val = bswap16(val);
+#endif
+    pci_data_write(s, addr, val, 2);
+}
+
+static void PPC_PCIIO_writel (void *opaque, target_phys_addr_t addr, uint32_t val)
+{
+    PCIBus *s = opaque;
+    set_config(s, addr);
+#ifdef TARGET_WORDS_BIGENDIAN
+    val = bswap32(val);
+#endif
+    pci_data_write(s, addr, val, 4);
+}
+
+static uint32_t PPC_PCIIO_readb (void *opaque, target_phys_addr_t addr)
+{
+    PCIBus *s = opaque;
+    uint32_t val;
+    set_config(s, addr);
+    val = pci_data_read(s, addr, 1);
+    return val;
+}
+
+static uint32_t PPC_PCIIO_readw (void *opaque, target_phys_addr_t addr)
+{
+    PCIBus *s = opaque;
+    uint32_t val;
+    set_config(s, addr);
+    val = pci_data_read(s, addr, 2);
+#ifdef TARGET_WORDS_BIGENDIAN
+    val = bswap16(val);
+#endif
+    return val;
+}
+
+static uint32_t PPC_PCIIO_readl (void *opaque, target_phys_addr_t addr)
+{
+    PCIBus *s = opaque;
+    uint32_t val;
+    set_config(s, addr);
+    val = pci_data_read(s, addr, 4);
+#ifdef TARGET_WORDS_BIGENDIAN
+    val = bswap32(val);
+#endif
+    return val;
+}
+
+static CPUWriteMemoryFunc *PPC_PCIIO_write[] = {
+    &PPC_PCIIO_writeb,
+    &PPC_PCIIO_writew,
+    &PPC_PCIIO_writel,
+};
+
+static CPUReadMemoryFunc *PPC_PCIIO_read[] = {
+    &PPC_PCIIO_readb,
+    &PPC_PCIIO_readw,
+    &PPC_PCIIO_readl,
+};
+
+static void prep_set_irq(PCIDevice *d, int irq_num, int level)
+{
+    /* XXX: we do not simulate the hardware - we rely on the BIOS to
+       set correctly for irq line field */
+    pic_set_irq(d->config[PCI_INTERRUPT_LINE], level);
+}
+
+PCIBus *pci_prep_init(void)
+{
+    PCIBus *s;
+    PCIDevice *d;
+    int PPC_io_memory;
+
+    s = pci_register_bus();
+    s->set_irq = prep_set_irq;
+
+    PPC_io_memory = cpu_register_io_memory(0, PPC_PCIIO_read, 
+                                           PPC_PCIIO_write, s);
+    cpu_register_physical_memory(0x80800000, 0x00400000, PPC_io_memory);
+
+    d = pci_register_device(s, "PREP PCI Bridge", sizeof(PCIDevice), 0,
+                            NULL, NULL);
+
+    /* XXX: put correct IDs */
+    d->config[0x00] = 0x11; // vendor_id
+    d->config[0x01] = 0x10;
+    d->config[0x02] = 0x26; // device_id
+    d->config[0x03] = 0x00;
+    d->config[0x08] = 0x02; // revision
+    d->config[0x0a] = 0x04; // class_sub = pci2pci
+    d->config[0x0b] = 0x06; // class_base = PCI_bridge
+    d->config[0x0e] = 0x01; // header_type
+    return s;
+}
+
+
+/* pmac pci init */
+
+#if 0
+/* Grackle PCI host */
+static void pci_grackle_config_writel (void *opaque, target_phys_addr_t addr,
+                                       uint32_t val)
+{
+    PCIBus *s = opaque;
+#ifdef TARGET_WORDS_BIGENDIAN
+    val = bswap32(val);
+#endif
+    s->config_reg = val;
+}
+
+static uint32_t pci_grackle_config_readl (void *opaque, target_phys_addr_t addr)
+{
+    PCIBus *s = opaque;
+    uint32_t val;
+
+    val = s->config_reg;
+#ifdef TARGET_WORDS_BIGENDIAN
+    val = bswap32(val);
+#endif
+    return val;
+}
+
+static CPUWriteMemoryFunc *pci_grackle_config_write[] = {
+    &pci_grackle_config_writel,
+    &pci_grackle_config_writel,
+    &pci_grackle_config_writel,
+};
+
+static CPUReadMemoryFunc *pci_grackle_config_read[] = {
+    &pci_grackle_config_readl,
+    &pci_grackle_config_readl,
+    &pci_grackle_config_readl,
+};
+
+static void pci_grackle_writeb (void *opaque, target_phys_addr_t addr,
+                                uint32_t val)
+{
+    PCIBus *s = opaque;
+    pci_data_write(s, addr, val, 1);
+}
+
+static void pci_grackle_writew (void *opaque, target_phys_addr_t addr,
+                                uint32_t val)
+{
+    PCIBus *s = opaque;
+#ifdef TARGET_WORDS_BIGENDIAN
+    val = bswap16(val);
+#endif
+    pci_data_write(s, addr, val, 2);
+}
+
+static void pci_grackle_writel (void *opaque, target_phys_addr_t addr,
+                                uint32_t val)
+{
+    PCIBus *s = opaque;
+#ifdef TARGET_WORDS_BIGENDIAN
+    val = bswap32(val);
+#endif
+    pci_data_write(s, addr, val, 4);
+}
+
+static uint32_t pci_grackle_readb (void *opaque, target_phys_addr_t addr)
+{
+    PCIBus *s = opaque;
+    uint32_t val;
+    val = pci_data_read(s, addr, 1);
+    return val;
+}
+
+static uint32_t pci_grackle_readw (void *opaque, target_phys_addr_t addr)
+{
+    PCIBus *s = opaque;
+    uint32_t val;
+    val = pci_data_read(s, addr, 2);
+#ifdef TARGET_WORDS_BIGENDIAN
+    val = bswap16(val);
+#endif
+    return val;
+}
+
+static uint32_t pci_grackle_readl (void *opaque, target_phys_addr_t addr)
+{
+    PCIBus *s = opaque;
+    uint32_t val;
+
+    val = pci_data_read(s, addr, 4);
+#ifdef TARGET_WORDS_BIGENDIAN
+    val = bswap32(val);
+#endif
+    return val;
+}
+
+static CPUWriteMemoryFunc *pci_grackle_write[] = {
+    &pci_grackle_writeb,
+    &pci_grackle_writew,
+    &pci_grackle_writel,
+};
+
+static CPUReadMemoryFunc *pci_grackle_read[] = {
+    &pci_grackle_readb,
+    &pci_grackle_readw,
+    &pci_grackle_readl,
+};
+#endif
+
+/* Uninorth PCI host (for all Mac99 and newer machines */
+static void pci_unin_main_config_writel (void *opaque, target_phys_addr_t addr,
+                                         uint32_t val)
+{
+    PCIBus *s = opaque;
+    int i;
+
+#ifdef TARGET_WORDS_BIGENDIAN
+    val = bswap32(val);
+#endif
+
+    for (i = 11; i < 32; i++) {
+        if ((val & (1 << i)) != 0)
+            break;
+    }
+#if 0
+    s->config_reg = 0x80000000 | (1 << 16) | (val & 0x7FC) | (i << 11);
+#else
+    s->config_reg = 0x80000000 | (0 << 16) | (val & 0x7FC) | (i << 11);
+#endif
+}
+
+static uint32_t pci_unin_main_config_readl (void *opaque,
+                                            target_phys_addr_t addr)
+{
+    PCIBus *s = opaque;
+    uint32_t val;
+    int devfn;
+
+    devfn = (s->config_reg >> 8) & 0xFF;
+    val = (1 << (devfn >> 3)) | ((devfn & 0x07) << 8) | (s->config_reg & 0xFC);
+#ifdef TARGET_WORDS_BIGENDIAN
+    val = bswap32(val);
+#endif
+
+    return val;
+}
+
+static CPUWriteMemoryFunc *pci_unin_main_config_write[] = {
+    &pci_unin_main_config_writel,
+    &pci_unin_main_config_writel,
+    &pci_unin_main_config_writel,
+};
+
+static CPUReadMemoryFunc *pci_unin_main_config_read[] = {
+    &pci_unin_main_config_readl,
+    &pci_unin_main_config_readl,
+    &pci_unin_main_config_readl,
+};
+
+static void pci_unin_main_writeb (void *opaque, target_phys_addr_t addr,
+                                  uint32_t val)
+{
+    PCIBus *s = opaque;
+    pci_data_write(s, addr & 7, val, 1);
+}
+
+static void pci_unin_main_writew (void *opaque, target_phys_addr_t addr,
+                                  uint32_t val)
+{
+    PCIBus *s = opaque;
+#ifdef TARGET_WORDS_BIGENDIAN
+    val = bswap16(val);
+#endif
+    pci_data_write(s, addr & 7, val, 2);
+}
+
+static void pci_unin_main_writel (void *opaque, target_phys_addr_t addr,
+                                uint32_t val)
+{
+    PCIBus *s = opaque;
+#ifdef TARGET_WORDS_BIGENDIAN
+    val = bswap32(val);
+#endif
+    pci_data_write(s, addr & 7, val, 4);
+}
+
+static uint32_t pci_unin_main_readb (void *opaque, target_phys_addr_t addr)
+{
+    PCIBus *s = opaque;
+    uint32_t val;
+
+    val = pci_data_read(s, addr & 7, 1);
+
+    return val;
+}
+
+static uint32_t pci_unin_main_readw (void *opaque, target_phys_addr_t addr)
+{
+    PCIBus *s = opaque;
+    uint32_t val;
+
+    val = pci_data_read(s, addr & 7, 2);
+#ifdef TARGET_WORDS_BIGENDIAN
+    val = bswap16(val);
+#endif
+
+    return val;
+}
+
+static uint32_t pci_unin_main_readl (void *opaque, target_phys_addr_t addr)
+{
+    PCIBus *s = opaque;
+    uint32_t val;
+
+    val = pci_data_read(s, addr, 4);
+#ifdef TARGET_WORDS_BIGENDIAN
+    val = bswap32(val);
+#endif
+
+    return val;
+}
+
+static CPUWriteMemoryFunc *pci_unin_main_write[] = {
+    &pci_unin_main_writeb,
+    &pci_unin_main_writew,
+    &pci_unin_main_writel,
+};
+
+static CPUReadMemoryFunc *pci_unin_main_read[] = {
+    &pci_unin_main_readb,
+    &pci_unin_main_readw,
+    &pci_unin_main_readl,
+};
+
+#if 0
+
+static void pci_unin_config_writel (void *opaque, target_phys_addr_t addr,
+                                    uint32_t val)
+{
+    PCIBus *s = opaque;
+
+#ifdef TARGET_WORDS_BIGENDIAN
+    val = bswap32(val);
+#endif
+    s->config_reg = 0x80000000 | (val & ~0x00000001);
+}
+
+static uint32_t pci_unin_config_readl (void *opaque,
+                                       target_phys_addr_t addr)
+{
+    PCIBus *s = opaque;
+    uint32_t val;
+
+    val = (s->config_reg | 0x00000001) & ~0x80000000;
+#ifdef TARGET_WORDS_BIGENDIAN
+    val = bswap32(val);
+#endif
+
+    return val;
+}
+
+static CPUWriteMemoryFunc *pci_unin_config_write[] = {
+    &pci_unin_config_writel,
+    &pci_unin_config_writel,
+    &pci_unin_config_writel,
+};
+
+static CPUReadMemoryFunc *pci_unin_config_read[] = {
+    &pci_unin_config_readl,
+    &pci_unin_config_readl,
+    &pci_unin_config_readl,
+};
+
+static void pci_unin_writeb (void *opaque, target_phys_addr_t addr,
+                             uint32_t val)
+{
+    PCIBus *s = opaque;
+    pci_data_write(s, addr & 3, val, 1);
+}
+
+static void pci_unin_writew (void *opaque, target_phys_addr_t addr,
+                             uint32_t val)
+{
+    PCIBus *s = opaque;
+#ifdef TARGET_WORDS_BIGENDIAN
+    val = bswap16(val);
+#endif
+    pci_data_write(s, addr & 3, val, 2);
+}
+
+static void pci_unin_writel (void *opaque, target_phys_addr_t addr,
+                             uint32_t val)
+{
+    PCIBus *s = opaque;
+#ifdef TARGET_WORDS_BIGENDIAN
+    val = bswap32(val);
+#endif
+    pci_data_write(s, addr & 3, val, 4);
+}
+
+static uint32_t pci_unin_readb (void *opaque, target_phys_addr_t addr)
+{
+    PCIBus *s = opaque;
+    uint32_t val;
+
+    val = pci_data_read(s, addr & 3, 1);
+
+    return val;
+}
+
+static uint32_t pci_unin_readw (void *opaque, target_phys_addr_t addr)
+{
+    PCIBus *s = opaque;
+    uint32_t val;
+
+    val = pci_data_read(s, addr & 3, 2);
+#ifdef TARGET_WORDS_BIGENDIAN
+    val = bswap16(val);
+#endif
+
+    return val;
+}
+
+static uint32_t pci_unin_readl (void *opaque, target_phys_addr_t addr)
+{
+    PCIBus *s = opaque;
+    uint32_t val;
+
+    val = pci_data_read(s, addr & 3, 4);
+#ifdef TARGET_WORDS_BIGENDIAN
+    val = bswap32(val);
+#endif
+
+    return val;
+}
+
+static CPUWriteMemoryFunc *pci_unin_write[] = {
+    &pci_unin_writeb,
+    &pci_unin_writew,
+    &pci_unin_writel,
+};
+
+static CPUReadMemoryFunc *pci_unin_read[] = {
+    &pci_unin_readb,
+    &pci_unin_readw,
+    &pci_unin_readl,
+};
+#endif
+
+static void pmac_set_irq(PCIDevice *d, int irq_num, int level)
+{
+    openpic_t *openpic;
+    /* XXX: we do not simulate the hardware - we rely on the BIOS to
+       set correctly for irq line field */
+    openpic = d->bus->openpic;
+#ifdef TARGET_PPC
+    if (openpic)
+        openpic_set_irq(openpic, d->config[PCI_INTERRUPT_LINE], level);
+#endif
+}
+
+void pci_pmac_set_openpic(PCIBus *bus, openpic_t *openpic)
+{
+    bus->openpic = openpic;
+}
+
+PCIBus *pci_pmac_init(void)
+{
+    PCIBus *s;
+    PCIDevice *d;
+    int pci_mem_config, pci_mem_data;
+
+    /* Use values found on a real PowerMac */
+    /* Uninorth main bus */
+    s = pci_register_bus();
+    s->set_irq = pmac_set_irq;
+
+    pci_mem_config = cpu_register_io_memory(0, pci_unin_main_config_read, 
+                                            pci_unin_main_config_write, s);
+    pci_mem_data = cpu_register_io_memory(0, pci_unin_main_read,
+                                          pci_unin_main_write, s);
+    cpu_register_physical_memory(0xf2800000, 0x1000, pci_mem_config);
+    cpu_register_physical_memory(0xf2c00000, 0x1000, pci_mem_data);
+    s->devfn_min = 11 << 3;
+    d = pci_register_device(s, "Uni-north main", sizeof(PCIDevice), 
+                            11 << 3, NULL, NULL);
+    d->config[0x00] = 0x6b; // vendor_id : Apple
+    d->config[0x01] = 0x10;
+    d->config[0x02] = 0x1F; // device_id
+    d->config[0x03] = 0x00;
+    d->config[0x08] = 0x00; // revision
+    d->config[0x0A] = 0x00; // class_sub = pci host
+    d->config[0x0B] = 0x06; // class_base = PCI_bridge
+    d->config[0x0C] = 0x08; // cache_line_size
+    d->config[0x0D] = 0x10; // latency_timer
+    d->config[0x0E] = 0x00; // header_type
+    d->config[0x34] = 0x00; // capabilities_pointer
+
+#if 0 // XXX: not activated as PPC BIOS doesn't handle mutiple buses properly
+    /* pci-to-pci bridge */
+    d = pci_register_device("Uni-north bridge", sizeof(PCIDevice), 0, 13 << 3,
+                            NULL, NULL);
+    d->config[0x00] = 0x11; // vendor_id : TI
+    d->config[0x01] = 0x10;
+    d->config[0x02] = 0x26; // device_id
+    d->config[0x03] = 0x00;
+    d->config[0x08] = 0x05; // revision
+    d->config[0x0A] = 0x04; // class_sub = pci2pci
+    d->config[0x0B] = 0x06; // class_base = PCI_bridge
+    d->config[0x0C] = 0x08; // cache_line_size
+    d->config[0x0D] = 0x20; // latency_timer
+    d->config[0x0E] = 0x01; // header_type
+
+    d->config[0x18] = 0x01; // primary_bus
+    d->config[0x19] = 0x02; // secondary_bus
+    d->config[0x1A] = 0x02; // subordinate_bus
+    d->config[0x1B] = 0x20; // secondary_latency_timer
+    d->config[0x1C] = 0x11; // io_base
+    d->config[0x1D] = 0x01; // io_limit
+    d->config[0x20] = 0x00; // memory_base
+    d->config[0x21] = 0x80;
+    d->config[0x22] = 0x00; // memory_limit
+    d->config[0x23] = 0x80;
+    d->config[0x24] = 0x01; // prefetchable_memory_base
+    d->config[0x25] = 0x80;
+    d->config[0x26] = 0xF1; // prefectchable_memory_limit
+    d->config[0x27] = 0x7F;
+    // d->config[0x34] = 0xdc // capabilities_pointer
+#endif
+#if 0 // XXX: not needed for now
+    /* Uninorth AGP bus */
+    s = &pci_bridge[1];
+    pci_mem_config = cpu_register_io_memory(0, pci_unin_config_read, 
+                                            pci_unin_config_write, s);
+    pci_mem_data = cpu_register_io_memory(0, pci_unin_read,
+                                          pci_unin_write, s);
+    cpu_register_physical_memory(0xf0800000, 0x1000, pci_mem_config);
+    cpu_register_physical_memory(0xf0c00000, 0x1000, pci_mem_data);
+
+    d = pci_register_device("Uni-north AGP", sizeof(PCIDevice), 0, 11 << 3,
+                            NULL, NULL);
+    d->config[0x00] = 0x6b; // vendor_id : Apple
+    d->config[0x01] = 0x10;
+    d->config[0x02] = 0x20; // device_id
+    d->config[0x03] = 0x00;
+    d->config[0x08] = 0x00; // revision
+    d->config[0x0A] = 0x00; // class_sub = pci host
+    d->config[0x0B] = 0x06; // class_base = PCI_bridge
+    d->config[0x0C] = 0x08; // cache_line_size
+    d->config[0x0D] = 0x10; // latency_timer
+    d->config[0x0E] = 0x00; // header_type
+    //    d->config[0x34] = 0x80; // capabilities_pointer
+#endif
+
+#if 0 // XXX: not needed for now
+    /* Uninorth internal bus */
+    s = &pci_bridge[2];
+    pci_mem_config = cpu_register_io_memory(0, pci_unin_config_read, 
+                                            pci_unin_config_write, s);
+    pci_mem_data = cpu_register_io_memory(0, pci_unin_read,
+                                          pci_unin_write, s);
+    cpu_register_physical_memory(0xf4800000, 0x1000, pci_mem_config);
+    cpu_register_physical_memory(0xf4c00000, 0x1000, pci_mem_data);
+
+    d = pci_register_device("Uni-north internal", sizeof(PCIDevice),
+                            3, 11 << 3, NULL, NULL);
+    d->config[0x00] = 0x6b; // vendor_id : Apple
+    d->config[0x01] = 0x10;
+    d->config[0x02] = 0x1E; // device_id
+    d->config[0x03] = 0x00;
+    d->config[0x08] = 0x00; // revision
+    d->config[0x0A] = 0x00; // class_sub = pci host
+    d->config[0x0B] = 0x06; // class_base = PCI_bridge
+    d->config[0x0C] = 0x08; // cache_line_size
+    d->config[0x0D] = 0x10; // latency_timer
+    d->config[0x0E] = 0x00; // header_type
+    d->config[0x34] = 0x00; // capabilities_pointer
+#endif
+
+#if 0 // Grackle ?
+    /* same values as PearPC - check this */
+    d->config[0x00] = 0x11; // vendor_id
+    d->config[0x01] = 0x10;
+    d->config[0x02] = 0x26; // device_id
+    d->config[0x03] = 0x00;
+    d->config[0x08] = 0x02; // revision
+    d->config[0x0a] = 0x04; // class_sub = pci2pci
+    d->config[0x0b] = 0x06; // class_base = PCI_bridge
+    d->config[0x0e] = 0x01; // header_type
+
+    d->config[0x18] = 0x0;  // primary_bus
+    d->config[0x19] = 0x1;  // secondary_bus
+    d->config[0x1a] = 0x1;  // subordinate_bus
+    d->config[0x1c] = 0x10; // io_base
+    d->config[0x1d] = 0x20; // io_limit
+    
+    d->config[0x20] = 0x80; // memory_base
+    d->config[0x21] = 0x80;
+    d->config[0x22] = 0x90; // memory_limit
+    d->config[0x23] = 0x80;
+    
+    d->config[0x24] = 0x00; // prefetchable_memory_base
+    d->config[0x25] = 0x84;
+    d->config[0x26] = 0x00; // prefetchable_memory_limit
+    d->config[0x27] = 0x85;
+#endif
+    return s;
+}
+
+/***********************************************************/
+/* generic PCI irq support */
+
+/* 0 <= irq_num <= 3. level must be 0 or 1 */
+void pci_set_irq(PCIDevice *pci_dev, int irq_num, int level)
+{
+    PCIBus *bus = pci_dev->bus;
+    bus->set_irq(pci_dev, irq_num, level);
+}
+
+/***********************************************************/
+/* monitor info on PCI */
+
+static void pci_info_device(PCIDevice *d)
+{
+    int i, class;
+    PCIIORegion *r;
+
+    term_printf("  Bus %2d, device %3d, function %d:\n",
+           d->bus->bus_num, d->devfn >> 3, d->devfn & 7);
+    class = le16_to_cpu(*((uint16_t *)(d->config + PCI_CLASS_DEVICE)));
+    term_printf("    ");
+    switch(class) {
+    case 0x0101:
+        term_printf("IDE controller");
+        break;
+    case 0x0200:
+        term_printf("Ethernet controller");
+        break;
+    case 0x0300:
+        term_printf("VGA controller");
+        break;
+    default:
+        term_printf("Class %04x", class);
+        break;
+    }
+    term_printf(": PCI device %04x:%04x\n",
+           le16_to_cpu(*((uint16_t *)(d->config + PCI_VENDOR_ID))),
+           le16_to_cpu(*((uint16_t *)(d->config + PCI_DEVICE_ID))));
+
+    if (d->config[PCI_INTERRUPT_PIN] != 0) {
+        term_printf("      IRQ %d.\n", d->config[PCI_INTERRUPT_LINE]);
+    }
+    for(i = 0;i < PCI_NUM_REGIONS; i++) {
+        r = &d->io_regions[i];
+        if (r->size != 0) {
+            term_printf("      BAR%d: ", i);
+            if (r->type & PCI_ADDRESS_SPACE_IO) {
+                term_printf("I/O at 0x%04x [0x%04x].\n", 
+                       r->addr, r->addr + r->size - 1);
+            } else {
+                term_printf("32 bit memory at 0x%08x [0x%08x].\n", 
+                       r->addr, r->addr + r->size - 1);
+            }
+        }
+    }
+}
+
+void pci_info(void)
+{
+    PCIBus *bus = first_bus;
+    PCIDevice *d;
+    int devfn;
+    
+    if (bus) {
+        for(devfn = 0; devfn < 256; devfn++) {
+            d = bus->devices[devfn];
+            if (d)
+                pci_info_device(d);
+        }
+    }
+}
+
+/***********************************************************/
+/* XXX: the following should be moved to the PC BIOS */
+
+static __attribute__((unused)) uint32_t isa_inb(uint32_t addr)
+{
+    return cpu_inb(cpu_single_env, addr);
+}
+
+static void isa_outb(uint32_t val, uint32_t addr)
+{
+    cpu_outb(cpu_single_env, addr, val);
+}
+
+static __attribute__((unused)) uint32_t isa_inw(uint32_t addr)
+{
+    return cpu_inw(cpu_single_env, addr);
+}
+
+static __attribute__((unused)) void isa_outw(uint32_t val, uint32_t addr)
+{
+    cpu_outw(cpu_single_env, addr, val);
+}
+
+static __attribute__((unused)) uint32_t isa_inl(uint32_t addr)
+{
+    return cpu_inl(cpu_single_env, addr);
+}
+
+static __attribute__((unused)) void isa_outl(uint32_t val, uint32_t addr)
+{
+    cpu_outl(cpu_single_env, addr, val);
+}
+
+static void pci_config_writel(PCIDevice *d, uint32_t addr, uint32_t val)
+{
+    PCIBus *s = d->bus;
+    s->config_reg = 0x80000000 | (s->bus_num << 16) | 
+        (d->devfn << 8) | addr;
+    pci_data_write(s, 0, val, 4);
+}
+
+static void pci_config_writew(PCIDevice *d, uint32_t addr, uint32_t val)
+{
+    PCIBus *s = d->bus;
+    s->config_reg = 0x80000000 | (s->bus_num << 16) | 
+        (d->devfn << 8) | (addr & ~3);
+    pci_data_write(s, addr & 3, val, 2);
+}
+
+static void pci_config_writeb(PCIDevice *d, uint32_t addr, uint32_t val)
+{
+    PCIBus *s = d->bus;
+    s->config_reg = 0x80000000 | (s->bus_num << 16) | 
+        (d->devfn << 8) | (addr & ~3);
+    pci_data_write(s, addr & 3, val, 1);
+}
+
+static __attribute__((unused)) uint32_t pci_config_readl(PCIDevice *d, uint32_t addr)
+{
+    PCIBus *s = d->bus;
+    s->config_reg = 0x80000000 | (s->bus_num << 16) | 
+        (d->devfn << 8) | addr;
+    return pci_data_read(s, 0, 4);
+}
+
+static uint32_t pci_config_readw(PCIDevice *d, uint32_t addr)
+{
+    PCIBus *s = d->bus;
+    s->config_reg = 0x80000000 | (s->bus_num << 16) | 
+        (d->devfn << 8) | (addr & ~3);
+    return pci_data_read(s, addr & 3, 2);
+}
+
+static uint32_t pci_config_readb(PCIDevice *d, uint32_t addr)
+{
+    PCIBus *s = d->bus;
+    s->config_reg = 0x80000000 | (s->bus_num << 16) | 
+        (d->devfn << 8) | (addr & ~3);
+    return pci_data_read(s, addr & 3, 1);
+}
+
+static uint32_t pci_bios_io_addr;
+static uint32_t pci_bios_mem_addr;
+/* host irqs corresponding to PCI irqs A-D */
+static uint8_t pci_irqs[4] = { 11, 9, 11, 9 };
+
+static void pci_set_io_region_addr(PCIDevice *d, int region_num, uint32_t addr)
+{
+    PCIIORegion *r;
+    uint16_t cmd;
+    uint32_t ofs;
+
+    if ( region_num == PCI_ROM_SLOT ) {
+        ofs = 0x30;
+    }else{
+        ofs = 0x10 + region_num * 4;
+    }
+
+    pci_config_writel(d, ofs, addr);
+    r = &d->io_regions[region_num];
+
+    /* enable memory mappings */
+    cmd = pci_config_readw(d, PCI_COMMAND);
+    if ( region_num == PCI_ROM_SLOT )
+        cmd |= 2;
+    else if (r->type & PCI_ADDRESS_SPACE_IO)
+        cmd |= 1;
+    else
+        cmd |= 2;
+    pci_config_writew(d, PCI_COMMAND, cmd);
+}
+
+static void pci_bios_init_device(PCIDevice *d)
+{
+    int class;
+    PCIIORegion *r;
+    uint32_t *paddr;
+    int i, pin, pic_irq, vendor_id, device_id;
+
+    class = pci_config_readw(d, PCI_CLASS_DEVICE);
+    vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
+    device_id = pci_config_readw(d, PCI_DEVICE_ID);
+    switch(class) {
+    case 0x0101:
+        if (vendor_id == 0x8086 && device_id == 0x7010) {
+            /* PIIX3 IDE */
+            pci_config_writew(d, 0x40, 0x8000); // enable IDE0
+            pci_config_writew(d, 0x42, 0x8000); // enable IDE1
+            goto default_map;
+        } else {
+            /* IDE: we map it as in ISA mode */
+            pci_set_io_region_addr(d, 0, 0x1f0);
+            pci_set_io_region_addr(d, 1, 0x3f4);
+            pci_set_io_region_addr(d, 2, 0x170);
+            pci_set_io_region_addr(d, 3, 0x374);
+        }
+        break;
+    case 0x0300:
+        if (vendor_id != 0x1234)
+            goto default_map;
+        /* VGA: map frame buffer to default Bochs VBE address */
+        pci_set_io_region_addr(d, 0, 0xE0000000);
+        break;
+    case 0x0800:
+        /* PIC */
+        vendor_id = pci_config_readw(d, PCI_VENDOR_ID);
+        device_id = pci_config_readw(d, PCI_DEVICE_ID);
+        if (vendor_id == 0x1014) {
+            /* IBM */
+            if (device_id == 0x0046 || device_id == 0xFFFF) {
+                /* MPIC & MPIC2 */
+                pci_set_io_region_addr(d, 0, 0x80800000 + 0x00040000);
+            }
+        }
+        break;
+    case 0xff00:
+        if (vendor_id == 0x0106b &&
+            (device_id == 0x0017 || device_id == 0x0022)) {
+            /* macio bridge */
+            pci_set_io_region_addr(d, 0, 0x80800000);
+        }
+        break;
+    default:
+    default_map:
+        /* default memory mappings */
+        for(i = 0; i < PCI_NUM_REGIONS; i++) {
+            r = &d->io_regions[i];
+            if (r->size) {
+                if (r->type & PCI_ADDRESS_SPACE_IO)
+                    paddr = &pci_bios_io_addr;
+                else
+                    paddr = &pci_bios_mem_addr;
+                *paddr = (*paddr + r->size - 1) & ~(r->size - 1);
+                pci_set_io_region_addr(d, i, *paddr);
+                *paddr += r->size;
+            }
+        }
+        break;
+    }
+
+    /* map the interrupt */
+    pin = pci_config_readb(d, PCI_INTERRUPT_PIN);
+    if (pin != 0) {
+        pin = pci_slot_get_pirq(d, pin - 1);
+        pic_irq = pci_irqs[pin];
+        pci_config_writeb(d, PCI_INTERRUPT_LINE, pic_irq);
+    }
+}
+
+/*
+ * This function initializes the PCI devices as a normal PCI BIOS
+ * would do. It is provided just in case the BIOS has no support for
+ * PCI.
+ */
+void pci_bios_init(void)
+{
+    PCIBus *bus;
+    PCIDevice *d;
+    int devfn, i, irq;
+    uint8_t elcr[2];
+
+    pci_bios_io_addr = 0xc000;
+    pci_bios_mem_addr = 0xf0000000;
+
+    /* activate IRQ mappings */
+    elcr[0] = 0x00;
+    elcr[1] = 0x00;
+    for(i = 0; i < 4; i++) {
+        irq = pci_irqs[i];
+        /* set to trigger level */
+        elcr[irq >> 3] |= (1 << (irq & 7));
+        /* activate irq remapping in PIIX */
+        pci_config_writeb((PCIDevice *)piix3_state, 0x60 + i, irq);
+    }
+    isa_outb(elcr[0], 0x4d0);
+    isa_outb(elcr[1], 0x4d1);
+
+    bus = first_bus;
+    if (bus) {
+        for(devfn = 0; devfn < 256; devfn++) {
+            d = bus->devices[devfn];
+            if (d)
+                pci_bios_init_device(d);
+        }
+    }
+}
diff --git a/tools/ioemu/hw/pckbd.c b/tools/ioemu/hw/pckbd.c
new file mode 100644 (file)
index 0000000..85863b4
--- /dev/null
@@ -0,0 +1,919 @@
+/*
+ * QEMU PC keyboard emulation
+ * 
+ * Copyright (c) 2003 Fabrice Bellard
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+
+/* debug PC keyboard */
+//#define DEBUG_KBD
+
+/* debug PC keyboard : only mouse */
+//#define DEBUG_MOUSE
+
+/*     Keyboard Controller Commands */
+#define KBD_CCMD_READ_MODE     0x20    /* Read mode bits */
+#define KBD_CCMD_WRITE_MODE    0x60    /* Write mode bits */
+#define KBD_CCMD_GET_VERSION   0xA1    /* Get controller version */
+#define KBD_CCMD_MOUSE_DISABLE 0xA7    /* Disable mouse interface */
+#define KBD_CCMD_MOUSE_ENABLE  0xA8    /* Enable mouse interface */
+#define KBD_CCMD_TEST_MOUSE    0xA9    /* Mouse interface test */
+#define KBD_CCMD_SELF_TEST     0xAA    /* Controller self test */
+#define KBD_CCMD_KBD_TEST      0xAB    /* Keyboard interface test */
+#define KBD_CCMD_KBD_DISABLE   0xAD    /* Keyboard interface disable */
+#define KBD_CCMD_KBD_ENABLE    0xAE    /* Keyboard interface enable */
+#define KBD_CCMD_READ_INPORT    0xC0    /* read input port */
+#define KBD_CCMD_READ_OUTPORT  0xD0    /* read output port */
+#define KBD_CCMD_WRITE_OUTPORT 0xD1    /* write output port */
+#define KBD_CCMD_WRITE_OBUF    0xD2
+#define KBD_CCMD_WRITE_AUX_OBUF        0xD3    /* Write to output buffer as if
+                                          initiated by the auxiliary device */
+#define KBD_CCMD_WRITE_MOUSE   0xD4    /* Write the following byte to the mouse */
+#define KBD_CCMD_DISABLE_A20    0xDD    /* HP vectra only ? */
+#define KBD_CCMD_ENABLE_A20     0xDF    /* HP vectra only ? */
+#define KBD_CCMD_RESET         0xFE
+
+/* Keyboard Commands */
+#define KBD_CMD_SET_LEDS       0xED    /* Set keyboard leds */
+#define KBD_CMD_ECHO           0xEE
+#define KBD_CMD_GET_ID                 0xF2    /* get keyboard ID */
+#define KBD_CMD_SET_RATE       0xF3    /* Set typematic rate */
+#define KBD_CMD_ENABLE         0xF4    /* Enable scanning */
+#define KBD_CMD_RESET_DISABLE  0xF5    /* reset and disable scanning */
+#define KBD_CMD_RESET_ENABLE           0xF6    /* reset and enable scanning */
+#define KBD_CMD_RESET          0xFF    /* Reset */
+
+/* Keyboard Replies */
+#define KBD_REPLY_POR          0xAA    /* Power on reset */
+#define KBD_REPLY_ACK          0xFA    /* Command ACK */
+#define KBD_REPLY_RESEND       0xFE    /* Command NACK, send the cmd again */
+
+/* Status Register Bits */
+#define KBD_STAT_OBF           0x01    /* Keyboard output buffer full */
+#define KBD_STAT_IBF           0x02    /* Keyboard input buffer full */
+#define KBD_STAT_SELFTEST      0x04    /* Self test successful */
+#define KBD_STAT_CMD           0x08    /* Last write was a command write (0=data) */
+#define KBD_STAT_UNLOCKED      0x10    /* Zero if keyboard locked */
+#define KBD_STAT_MOUSE_OBF     0x20    /* Mouse output buffer full */
+#define KBD_STAT_GTO           0x40    /* General receive/xmit timeout */
+#define KBD_STAT_PERR          0x80    /* Parity error */
+
+/* Controller Mode Register Bits */
+#define KBD_MODE_KBD_INT       0x01    /* Keyboard data generate IRQ1 */
+#define KBD_MODE_MOUSE_INT     0x02    /* Mouse data generate IRQ12 */
+#define KBD_MODE_SYS           0x04    /* The system flag (?) */
+#define KBD_MODE_NO_KEYLOCK    0x08    /* The keylock doesn't affect the keyboard if set */
+#define KBD_MODE_DISABLE_KBD   0x10    /* Disable keyboard interface */
+#define KBD_MODE_DISABLE_MOUSE 0x20    /* Disable mouse interface */
+#define KBD_MODE_KCC           0x40    /* Scan code conversion to PC format */
+#define KBD_MODE_RFU           0x80
+
+/* Mouse Commands */
+#define AUX_SET_SCALE11                0xE6    /* Set 1:1 scaling */
+#define AUX_SET_SCALE21                0xE7    /* Set 2:1 scaling */
+#define AUX_SET_RES            0xE8    /* Set resolution */
+#define AUX_GET_SCALE          0xE9    /* Get scaling factor */
+/* according to Synaptic docs this $E9 is really 3-byte status */
+#define AUX_SET_STREAM         0xEA    /* Set stream mode */
+#define AUX_POLL               0xEB    /* Poll */
+#define AUX_RESET_WRAP         0xEC    /* Reset wrap mode */
+#define AUX_SET_WRAP           0xEE    /* Set wrap mode */
+#define AUX_SET_REMOTE         0xF0    /* Set remote mode */
+#define AUX_GET_TYPE           0xF2    /* Get type */
+#define AUX_SET_SAMPLE         0xF3    /* Set sample rate */
+#define AUX_ENABLE_DEV         0xF4    /* Enable aux device */
+#define AUX_DISABLE_DEV                0xF5    /* Disable aux device */
+#define AUX_SET_DEFAULT                0xF6
+#define AUX_RESET              0xFF    /* Reset aux device */
+#define AUX_ACK                        0xFA    /* Command byte ACK. */
+
+#define MOUSE_STATUS_REMOTE     0x40
+#define MOUSE_STATUS_ENABLED    0x20
+#define MOUSE_STATUS_SCALE21    0x10
+
+#define KBD_QUEUE_SIZE 256
+
+typedef struct {
+    uint8_t aux[KBD_QUEUE_SIZE];
+    uint8_t data[KBD_QUEUE_SIZE];
+    int rptr, wptr, count;
+} KBDQueue;
+
+typedef struct {
+    int absolute;
+    int high;
+} TouchPad;
+
+typedef struct KBDState {
+    KBDQueue queue;
+    uint8_t write_cmd; /* if non zero, write data to port 60 is expected */
+    uint8_t status;
+    uint8_t mode;
+    /* keyboard state */
+    int kbd_write_cmd;
+    int scan_enabled;
+    /* mouse state */
+    int mouse_write_cmd;
+    uint8_t mouse_status;
+    uint8_t mouse_resolution;
+    uint8_t mouse_sample_rate;
+    uint8_t mouse_wrap;
+    uint8_t mouse_type; /* 0 = PS2, 3 = IMPS/2, 4 = IMEX */
+    uint8_t mouse_detect_state;
+    int mouse_dx; /* current values, needed for 'poll' mode */
+    int mouse_dy;
+    int mouse_dz;
+    uint8_t mouse_buttons;
+    TouchPad touchpad;
+} KBDState;
+
+KBDState kbd_state;
+
+/* update irq and KBD_STAT_[MOUSE_]OBF */
+/* XXX: not generating the irqs if KBD_MODE_DISABLE_KBD is set may be
+   incorrect, but it avoids having to simulate exact delays */
+static void kbd_update_irq(KBDState *s)
+{
+    KBDQueue *q = &s->queue;
+    int irq12_level, irq1_level;
+
+    irq1_level = 0;    
+    irq12_level = 0;    
+    s->status &= ~(KBD_STAT_OBF | KBD_STAT_MOUSE_OBF);
+    if (q->count != 0) {
+        s->status |= KBD_STAT_OBF;
+        if (q->aux[q->rptr]) {
+            s->status |= KBD_STAT_MOUSE_OBF;
+            if (s->mode & KBD_MODE_MOUSE_INT)
+                irq12_level = 1;
+        } else {
+            if ((s->mode & KBD_MODE_KBD_INT) && 
+                !(s->mode & KBD_MODE_DISABLE_KBD))
+                irq1_level = 1;
+        }
+    }
+    pic_set_irq(1, irq1_level);
+    pic_set_irq(12, irq12_level);
+}
+
+static void kbd_queue(KBDState *s, int b, int aux)
+{
+    KBDQueue *q = &s->queue;
+
+#if defined(DEBUG_MOUSE) || defined(DEBUG_KBD)
+    if (aux)
+        printf("mouse event: 0x%02x\n", b);
+#ifdef DEBUG_KBD
+    else
+        printf("kbd event: 0x%02x\n", b);
+#endif
+#endif
+    if (q->count >= KBD_QUEUE_SIZE)
+        return;
+    q->aux[q->wptr] = aux;
+    q->data[q->wptr] = b;
+    if (++q->wptr == KBD_QUEUE_SIZE)
+        q->wptr = 0;
+    q->count++;
+    kbd_update_irq(s);
+}
+
+static void pc_kbd_put_keycode(void *opaque, int keycode)
+{
+    KBDState *s = opaque;
+    kbd_queue(s, keycode, 0);
+}
+
+static uint32_t kbd_read_status(void *opaque, uint32_t addr)
+{
+    KBDState *s = opaque;
+    int val;
+    val = s->status;
+#if defined(DEBUG_KBD)
+    printf("kbd: read status=0x%02x\n", val);
+#endif
+    return val;
+}
+
+static void kbd_write_command(void *opaque, uint32_t addr, uint32_t val)
+{
+    KBDState *s = opaque;
+
+#ifdef DEBUG_KBD
+    printf("kbd: write cmd=0x%02x\n", val);
+#endif
+    switch(val) {
+    case KBD_CCMD_READ_MODE:
+        kbd_queue(s, s->mode, 0);
+        break;
+    case KBD_CCMD_WRITE_MODE:
+    case KBD_CCMD_WRITE_OBUF:
+    case KBD_CCMD_WRITE_AUX_OBUF:
+    case KBD_CCMD_WRITE_MOUSE:
+    case KBD_CCMD_WRITE_OUTPORT:
+        s->write_cmd = val;
+        break;
+    case KBD_CCMD_MOUSE_DISABLE:
+        s->mode |= KBD_MODE_DISABLE_MOUSE;
+        break;
+    case KBD_CCMD_MOUSE_ENABLE:
+        s->mode &= ~KBD_MODE_DISABLE_MOUSE;
+        break;
+    case KBD_CCMD_TEST_MOUSE:
+        kbd_queue(s, 0x00, 0);
+        break;
+    case KBD_CCMD_SELF_TEST:
+        s->status |= KBD_STAT_SELFTEST;
+        kbd_queue(s, 0x55, 0);
+        break;
+    case KBD_CCMD_KBD_TEST:
+        kbd_queue(s, 0x00, 0);
+        break;
+    case KBD_CCMD_KBD_DISABLE:
+        s->mode |= KBD_MODE_DISABLE_KBD;
+        kbd_update_irq(s);
+        break;
+    case KBD_CCMD_KBD_ENABLE:
+        s->mode &= ~KBD_MODE_DISABLE_KBD;
+        kbd_update_irq(s);
+        break;
+    case KBD_CCMD_READ_INPORT:
+        kbd_queue(s, 0x00, 0);
+        break;
+    case KBD_CCMD_READ_OUTPORT:
+        /* XXX: check that */
+#ifdef TARGET_I386
+        val = 0x01 | (((cpu_single_env->a20_mask >> 20) & 1) << 1);
+#else
+        val = 0x01;
+#endif
+        if (s->status & KBD_STAT_OBF)
+            val |= 0x10;
+        if (s->status & KBD_STAT_MOUSE_OBF)
+            val |= 0x20;
+        kbd_queue(s, val, 0);
+        break;
+#ifdef TARGET_I386
+    case KBD_CCMD_ENABLE_A20:
+        cpu_x86_set_a20(cpu_single_env, 1);
+        break;
+    case KBD_CCMD_DISABLE_A20:
+        cpu_x86_set_a20(cpu_single_env, 0);
+        break;
+#endif
+    case KBD_CCMD_RESET:
+        qemu_system_reset_request();
+        break;
+    case 0xff:
+        /* ignore that - I don't know what is its use */
+        break;
+    default:
+        fprintf(stderr, "qemu: unsupported keyboard cmd=0x%02x\n", val);
+        break;
+    }
+}
+
+static uint32_t kbd_read_data(void *opaque, uint32_t addr)
+{
+    KBDState *s = opaque;
+    KBDQueue *q;
+    int val, index, aux;
+    
+    q = &s->queue;
+    if (q->count == 0) {
+        /* NOTE: if no data left, we return the last keyboard one
+           (needed for EMM386) */
+        /* XXX: need a timer to do things correctly */
+        index = q->rptr - 1;
+        if (index < 0)
+            index = KBD_QUEUE_SIZE - 1;
+        val = q->data[index];
+    } else {
+        aux = q->aux[q->rptr];
+        val = q->data[q->rptr];
+        if (++q->rptr == KBD_QUEUE_SIZE)
+            q->rptr = 0;
+        q->count--;
+        /* reading deasserts IRQ */
+        if (aux)
+            pic_set_irq(12, 0);
+        else
+            pic_set_irq(1, 0);
+    }
+    /* reassert IRQs if data left */
+    kbd_update_irq(s);
+#ifdef DEBUG_KBD
+    printf("kbd: read data=0x%02x\n", val);
+#endif
+    return val;
+}
+
+static void kbd_reset_keyboard(KBDState *s)
+{
+    s->scan_enabled = 1;
+}
+
+static void kbd_write_keyboard(KBDState *s, int val)
+{
+    switch(s->kbd_write_cmd) {
+    default:
+    case -1:
+        switch(val) {
+        case 0x00:
+            kbd_queue(s, KBD_REPLY_ACK, 0);
+            break;
+        case 0x05:
+            kbd_queue(s, KBD_REPLY_RESEND, 0);
+            break;
+        case KBD_CMD_GET_ID:
+            kbd_queue(s, KBD_REPLY_ACK, 0);
+            kbd_queue(s, 0xab, 0);
+            kbd_queue(s, 0x83, 0);
+            break;
+        case KBD_CMD_ECHO:
+            kbd_queue(s, KBD_CMD_ECHO, 0);
+            break;
+        case KBD_CMD_ENABLE:
+            s->scan_enabled = 1;
+            kbd_queue(s, KBD_REPLY_ACK, 0);
+            break;
+        case KBD_CMD_SET_LEDS:
+        case KBD_CMD_SET_RATE:
+            s->kbd_write_cmd = val;
+            kbd_queue(s, KBD_REPLY_ACK, 0);
+            break;
+        case KBD_CMD_RESET_DISABLE:
+            kbd_reset_keyboard(s);
+            s->scan_enabled = 0;
+            kbd_queue(s, KBD_REPLY_ACK, 0);
+            break;
+        case KBD_CMD_RESET_ENABLE:
+            kbd_reset_keyboard(s);
+            s->scan_enabled = 1;
+            kbd_queue(s, KBD_REPLY_ACK, 0);
+            break;
+        case KBD_CMD_RESET:
+            kbd_reset_keyboard(s);
+            kbd_queue(s, KBD_REPLY_ACK, 0);
+            kbd_queue(s, KBD_REPLY_POR, 0);
+            break;
+        default:
+            kbd_queue(s, KBD_REPLY_ACK, 0);
+            break;
+        }
+        break;
+    case KBD_CMD_SET_LEDS:
+        kbd_queue(s, KBD_REPLY_ACK, 0);
+        s->kbd_write_cmd = -1;
+        break;
+    case KBD_CMD_SET_RATE:
+        kbd_queue(s, KBD_REPLY_ACK, 0);
+        s->kbd_write_cmd = -1;
+        break;
+    }
+}
+
+static void kbd_mouse_send_packet(KBDState *s)
+{
+    unsigned int b;
+    int dx1, dy1, dz1;
+
+    dx1 = s->mouse_dx;
+    dy1 = s->mouse_dy;
+    dz1 = s->mouse_dz;
+    if (s->touchpad.absolute)
+    {
+       int dz2, dleftnright, dg, df;
+       if (dx1 > 6143)
+           dx1 = 6143;
+       else if (dx1 < 0)
+           dx1 = 0;
+       if (dy1 > 6143)
+           dy1 = 6143;
+       else if (dy1 < 0)
+           dy1 = 0;
+       dz2 = 80; /* normal finger pressure */
+       dg = 0; /* guesture not supported */
+       df = 0; /* finger not supported */
+       dleftnright = (s->mouse_buttons & 0x07);
+       /*
+       X: 13 bits --return absolute x ord
+       Y: 13 bits --return absolute y ord
+       Z: 8 bits --return constant 80 since we don't know how hard the user
+               is pressing on the mouse button ;) 80 is the default for pen
+               pressure, as touchpads cant sense what pressure a pen makes.
+       W: 4 bits --return 0, we don't support finger width (should we?)
+       left: 1 bit --is left button pressed
+       right: 1 bit --is right button pressed
+       guesture: 1 bit --we dont support, return 0
+       finger: 1 bit --ditto
+       total: 42 bits in 6 bytes
+       note that Synaptics drivers ignore the finger and guesture bits and
+       consider them redundant
+       */
+       /*
+       note: the packet setup is different when Wmode = 1, but
+           this doesn't apply since we don't support Wmode capability
+       format of packet is as follows:
+       */
+       // 1 0 finger reserved 0 gesture right left
+       kbd_queue(s, (0x80 | (df ? 0x20 : 0) | (dg ? 0x04 : 0) | dleftnright), 1);
+       kbd_queue(s, ((dy1 & 0xF) * 256) + (dx1 & 0xF), 1);
+       kbd_queue(s, 80, 1); //byte 3
+       // 1 1 y-12 x-12 0 gesture right left
+       kbd_queue(s, (0xC0 | ((dy1 & 1000) ? 0x20 : 0) | ((dx1 & 1000) ? 0x10 : 0) | (dg ? 0x04 : 0) | dleftnright), 1);
+       kbd_queue(s, dx1 & 0xFF, 1);
+       kbd_queue(s, dy1 & 0xFF, 1);
+       return;
+    }
+    /* XXX: increase range to 8 bits ? */
+    if (dx1 > 127)
+        dx1 = 127;
+    else if (dx1 < -127)
+        dx1 = -127;
+    if (dy1 > 127)
+        dy1 = 127;
+    else if (dy1 < -127)
+        dy1 = -127;
+    b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07);
+    kbd_queue(s, b, 1);
+    kbd_queue(s, dx1 & 0xff, 1);
+    kbd_queue(s, dy1 & 0xff, 1);
+    /* extra byte for IMPS/2 or IMEX */
+    switch(s->mouse_type) {
+    default:
+        break;
+    case 3:
+        if (dz1 > 127)
+            dz1 = 127;
+        else if (dz1 < -127)
+                dz1 = -127;
+        kbd_queue(s, dz1 & 0xff, 1);
+        break;
+    case 4:
+        if (dz1 > 7)
+            dz1 = 7;
+        else if (dz1 < -7)
+            dz1 = -7;
+        b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
+        kbd_queue(s, b, 1);
+        break;
+    }
+
+    /* update deltas */
+    s->mouse_dx -= dx1;
+    s->mouse_dy -= dy1;
+    s->mouse_dz -= dz1;
+}
+
+static void pc_kbd_mouse_event(void *opaque, 
+                               int dx, int dy, int dz, int buttons_state)
+{
+    KBDState *s = opaque;
+
+    /* check if deltas are recorded when disabled */
+    if (!(s->mouse_status & MOUSE_STATUS_ENABLED))
+        return;
+
+    s->mouse_dx += dx;
+    s->mouse_dy -= dy;
+    s->mouse_dz += dz;
+    /* XXX: SDL sometimes generates nul events: we delete them */
+    if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0 &&
+        s->mouse_buttons == buttons_state)
+       return;
+    s->mouse_buttons = buttons_state;
+    
+    if (!(s->mouse_status & MOUSE_STATUS_REMOTE) &&
+        (s->queue.count < (KBD_QUEUE_SIZE - 16))) {
+        for(;;) {
+            /* if not remote, send event. Multiple events are sent if
+               too big deltas */
+            kbd_mouse_send_packet(s);
+            if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0)
+                break;
+        }
+    }
+}
+
+static void kbd_write_mouse(KBDState *s, int val)
+{
+/* variables needed to store synaptics command info */
+static int rr = 0, ss = 0, tt = 0, uu = 0, res_count = 0, last_com = 0;
+int spare;
+#ifdef DEBUG_MOUSE
+    printf("kbd: write mouse 0x%02x\n", val);
+#endif
+    switch(s->mouse_write_cmd) {
+    default:
+    case -1:
+        /* mouse command */
+        if (s->mouse_wrap) {
+            if (val == AUX_RESET_WRAP) {
+                s->mouse_wrap = 0;
+                kbd_queue(s, AUX_ACK, 1);
+                return;
+            } else if (val != AUX_RESET) {
+                kbd_queue(s, val, 1);
+                return;
+            }
+        }
+       last_com = val;
+        switch(val) {
+        case AUX_SET_SCALE11:
+            s->mouse_status &= ~MOUSE_STATUS_SCALE21;
+            kbd_queue(s, AUX_ACK, 1);
+            break;
+        case AUX_SET_SCALE21:
+            s->mouse_status |= MOUSE_STATUS_SCALE21;
+            kbd_queue(s, AUX_ACK, 1);
+            break;
+        case AUX_SET_STREAM:
+            s->mouse_status &= ~MOUSE_STATUS_REMOTE;
+            kbd_queue(s, AUX_ACK, 1);
+            break;
+        case AUX_SET_WRAP:
+            s->mouse_wrap = 1;
+            kbd_queue(s, AUX_ACK, 1);
+            break;
+        case AUX_SET_REMOTE:
+            s->mouse_status |= MOUSE_STATUS_REMOTE;
+            kbd_queue(s, AUX_ACK, 1);
+            break;
+        case AUX_GET_TYPE:
+            kbd_queue(s, AUX_ACK, 1);
+            kbd_queue(s, s->mouse_type, 1);
+            break;
+        case AUX_SET_RES:
+        case AUX_SET_SAMPLE:
+            s->mouse_write_cmd = val;
+            kbd_queue(s, AUX_ACK, 1);
+            break;
+        case AUX_GET_SCALE:
+           if (res_count == 4)
+           {
+                   /* time for the special stuff */
+                   kbd_queue(s, AUX_ACK, 1);
+                   /* below is how we get the real synaptic command */
+                   val = (rr*64) + (ss*16) + (tt*4) + uu;
+                   switch(val)
+                   {
+                           /* id touchpad */
+                           case 0x00:
+                                   /* info Minor */
+                                   kbd_queue(s, 0x00, 1);
+                                   /* special verification byte */
+                                   kbd_queue(s, 0x47, 1);
+                                   /* info Major * 0x10 + Info ModelCode*/
+                                   kbd_queue(s, 4 * 0x10 + 0, 1);
+                                   break;
+                                   /* read touchpad modes */
+                           case 0x01:
+                                   /* special verification byte */
+                                   kbd_queue(s, 0x3B, 1);
+                                   /* mode */
+                                   /*
+                                       bit 7 - absolute or relative position
+                                       bit 6 - 0 for 40 packets/sec, 1 for 80 pack/sec
+                                       bit 3 - 1 for sleep mode, 0 for normal
+                                       bit 2 - 1 to detect tap/drag, 0 to disable
+                                       bit 1 - packet size, only valid for serial protocol
+                                       bit 0 - 0 for normal packets, 1 for enhanced packets
+                                       (absolute mode packets which have finger width)
+                                       */
+                                   if (s->touchpad.absolute && s->touchpad.high)
+                                   {
+                                           spare = 0xC0;
+                                   }
+                                   else if (s->touchpad.absolute)
+                                   {
+                                           spare = 0x80;
+                                   }
+                                   else if (s->touchpad.high)
+                                   {
+                                           spare = 0x40;
+                                   }
+                                   else
+                                   {
+                                           spare = 0x00;
+                                   }
+                                   kbd_queue(s, spare, 1);
+                                   /* special verification byte */
+                                   kbd_queue(s, 0x47, 1);
+                                   break;
+                                   /* read touchpad capabilites */
+                           case 0x02:
+                                   /* extended capability first 8 bits */
+                                   kbd_queue(s, 0x00, 1);
+                                   /* special verification byte */
+                                   kbd_queue(s, 0x47, 1);
+                                   /* extended capability last 8 bits */
+                                   kbd_queue(s, 0x00, 1);
+                                   /* basicly, we don't have any capabilites ;0 */
+                                   break;
+                                   /* read model id */
+                           case 0x03:
+                                   /*
+                                       bit 23 = 0 (1 for upsidedownpad)
+                                       bit 22 = 0 (1 for 90 degree rotated pad)
+                                       bits 21-16 = 1 (standard model)
+                                       bits 15-9 = ??? (reserved for synaptics use)
+                                       bit 7 = 1
+                                       bit 6 = 0 (1 for sensing pens)
+                                       bit 5 = 1
+                                       bits 3-0 = 1 (rectangular geometery)
+                                   */
+                                   kbd_queue(s, 0xFC, 1);
+                                   kbd_queue(s, 0x00, 1);
+                                   kbd_queue(s, 0xF5, 1); //F7 for sensing pens
+                                   break;
+                                   /* read serial number prefix */
+                           case 0x06:
+                                   /* strange how they have this query even though
+                                       no touchpad actually has serial numbers */
+                                   /* return serial prefix of 0 if we dont have one */
+                                   kbd_queue(s, 0x00, 1);
+                                   kbd_queue(s, 0x00, 1);
+                                   kbd_queue(s, 0x00, 1);
+                                   break;
+                                   /* read serial number suffix */
+                           case 0x07:
+                                   /* undefined if we dont have a valid serial prefix */
+                                   kbd_queue(s, 0x00, 1);
+                                   kbd_queue(s, 0x00, 1);
+                                   kbd_queue(s, 0x00, 1);
+                                   break;
+                                   /* read resolutions */
+                           case 0x08:
+                                   /* going to go with infoSensor = 1 (Standard model) here */
+                                   /* absolute X in abolute units per mm */
+                                   kbd_queue(s, 85, 1);
+                                   /* undefined but first bit 7 will be set to 1...
+                                       hell I'm going to set them all to 1 */
+                                   kbd_queue(s, 0xFF, 1);
+                                   /* absolute Y in abolute units per mm */
+                                   kbd_queue(s, 94, 1);
+                                   break;
+                           default:
+                                   /* invalid commands return undefined data */
+                                   kbd_queue(s, 0x00, 1);
+                                   kbd_queue(s, 0x00, 1);
+                                   kbd_queue(s, 0x00, 1);
+                                   break;
+                   }
+           }
+           else
+           {
+                   /* not a special command, just do the regular stuff */
+            kbd_queue(s, AUX_ACK, 1);
+            kbd_queue(s, s->mouse_status, 1);
+            kbd_queue(s, s->mouse_resolution, 1);
+            kbd_queue(s, s->mouse_sample_rate, 1);
+           }
+            break;
+        case AUX_POLL:
+            kbd_queue(s, AUX_ACK, 1);
+            kbd_mouse_send_packet(s);
+            break;
+        case AUX_ENABLE_DEV:
+            s->mouse_status |= MOUSE_STATUS_ENABLED;
+            kbd_queue(s, AUX_ACK, 1);
+            break;
+        case AUX_DISABLE_DEV:
+            s->mouse_status &= ~MOUSE_STATUS_ENABLED;
+            kbd_queue(s, AUX_ACK, 1);
+            break;
+        case AUX_SET_DEFAULT:
+            s->mouse_sample_rate = 100;
+            s->mouse_resolution = 2;
+            s->mouse_status = 0;
+                   s->touchpad.absolute = 0;
+            kbd_queue(s, AUX_ACK, 1);
+            break;
+        case AUX_RESET:
+            s->mouse_sample_rate = 100;
+            s->mouse_resolution = 2;
+            s->mouse_status = 0;
+           s->touchpad.absolute = 0;
+            kbd_queue(s, AUX_ACK, 1);
+            kbd_queue(s, 0xaa, 1);
+            kbd_queue(s, s->mouse_type, 1);
+            break;
+        default:
+            break;
+        }
+        break;
+    case AUX_SET_SAMPLE:
+       if (res_count == 4 && val == 0x14)
+       {
+               /* time for the special stuff */
+               /* below is how we get the real synaptic command */
+               val = (rr*64) + (ss*16) + (tt*4) + uu;
+               /* TODO: set the mode byte */
+       } else
+        s->mouse_sample_rate = val;
+#if 0
+        /* detect IMPS/2 or IMEX */
+        switch(s->mouse_detect_state) {
+        default:
+        case 0:
+            if (val == 200)
+                s->mouse_detect_state = 1;
+            break;
+        case 1:
+            if (val == 100)
+                s->mouse_detect_state = 2;
+            else if (val == 200)
+                s->mouse_detect_state = 3;
+            else
+                s->mouse_detect_state = 0;
+            break;
+        case 2:
+            if (val == 80) 
+                s->mouse_type = 3; /* IMPS/2 */
+            s->mouse_detect_state = 0;
+            break;
+        case 3:
+            if (val == 80) 
+                s->mouse_type = 4; /* IMEX */
+            s->mouse_detect_state = 0;
+            break;
+        }
+#endif
+        kbd_queue(s, AUX_ACK, 1);
+        s->mouse_write_cmd = -1;
+        break;
+    case AUX_SET_RES:
+       if (last_com != AUX_SET_RES)
+       {
+               /* if its not 4 in a row, its not a command */
+               /* FIXME: if we are set 8 of these in a row, or 12, or 16,
+                  or etc ... or 4^n commands, then the nth'd mode byte sent might
+                  still work. not sure if this is how things are suppose to be
+                  or not. */
+               res_count = 0;
+       }
+       res_count++;
+       if (res_count > 4) res_count = 4;
+       switch(res_count)
+               /* we need to save the val in the right spots to get the
+                  real command later */
+       {
+               case 1:
+                       break;
+                       rr = val;
+               case 2:
+                       ss = val;
+                       break;
+               case 3:
+                       tt = val;
+                       break;
+               case 4:
+                       uu = val;
+                       break;
+       }
+        s->mouse_resolution = val;
+        kbd_queue(s, AUX_ACK, 1);
+        s->mouse_write_cmd = -1;
+        break;
+    }
+}
+
+void kbd_write_data(void *opaque, uint32_t addr, uint32_t val)
+{
+    KBDState *s = opaque;
+
+#ifdef DEBUG_KBD
+    printf("kbd: write data=0x%02x\n", val);
+#endif
+
+    switch(s->write_cmd) {
+    case 0:
+        kbd_write_keyboard(s, val);
+        break;
+    case KBD_CCMD_WRITE_MODE:
+        s->mode = val;
+        kbd_update_irq(s);
+        break;
+    case KBD_CCMD_WRITE_OBUF:
+        kbd_queue(s, val, 0);
+        break;
+    case KBD_CCMD_WRITE_AUX_OBUF:
+        kbd_queue(s, val, 1);
+        break;
+    case KBD_CCMD_WRITE_OUTPORT:
+#ifdef TARGET_I386
+        cpu_x86_set_a20(cpu_single_env, (val >> 1) & 1);
+#endif
+        if (!(val & 1)) {
+            qemu_system_reset_request();
+        }
+        break;
+    case KBD_CCMD_WRITE_MOUSE:
+        kbd_write_mouse(s, val);
+        break;
+    default:
+        break;
+    }
+    s->write_cmd = 0;
+}
+
+static void kbd_reset(void *opaque)
+{
+    KBDState *s = opaque;
+    KBDQueue *q;
+
+    s->kbd_write_cmd = -1;
+    s->mouse_write_cmd = -1;
+    s->mode = KBD_MODE_KBD_INT | KBD_MODE_MOUSE_INT | KBD_MODE_KCC;
+    s->status = KBD_STAT_CMD | KBD_STAT_UNLOCKED;
+    q = &s->queue;
+    q->rptr = 0;
+    q->wptr = 0;
+    q->count = 0;
+}
+
+static void kbd_save(QEMUFile* f, void* opaque)
+{
+    KBDState *s = (KBDState*)opaque;
+    
+    qemu_put_8s(f, &s->write_cmd);
+    qemu_put_8s(f, &s->status);
+    qemu_put_8s(f, &s->mode);
+    qemu_put_be32s(f, &s->kbd_write_cmd);
+    qemu_put_be32s(f, &s->scan_enabled);
+    qemu_put_be32s(f, &s->mouse_write_cmd);
+    qemu_put_8s(f, &s->mouse_status);
+    qemu_put_8s(f, &s->mouse_resolution);
+    qemu_put_8s(f, &s->mouse_sample_rate);
+    qemu_put_8s(f, &s->mouse_wrap);
+    qemu_put_8s(f, &s->mouse_type);
+    qemu_put_8s(f, &s->mouse_detect_state);
+    qemu_put_be32s(f, &s->mouse_dx);
+    qemu_put_be32s(f, &s->mouse_dy);
+    qemu_put_be32s(f, &s->mouse_dz);
+    qemu_put_8s(f, &s->mouse_buttons);
+    qemu_put_be32s(f, &s->touchpad.absolute);
+    qemu_put_be32s(f, &s->touchpad.high);
+}
+
+static int kbd_load(QEMUFile* f, void* opaque, int version_id)
+{
+    KBDState *s = (KBDState*)opaque;
+    
+    if (version_id != 2)
+        return -EINVAL;
+    qemu_get_8s(f, &s->write_cmd);
+    qemu_get_8s(f, &s->status);
+    qemu_get_8s(f, &s->mode);
+    qemu_get_be32s(f, &s->kbd_write_cmd);
+    qemu_get_be32s(f, &s->scan_enabled);
+    qemu_get_be32s(f, &s->mouse_write_cmd);
+    qemu_get_8s(f, &s->mouse_status);
+    qemu_get_8s(f, &s->mouse_resolution);
+    qemu_get_8s(f, &s->mouse_sample_rate);
+    qemu_get_8s(f, &s->mouse_wrap);
+    qemu_get_8s(f, &s->mouse_type);
+    qemu_get_8s(f, &s->mouse_detect_state);
+    qemu_get_be32s(f, &s->mouse_dx);
+    qemu_get_be32s(f, &s->mouse_dy);
+    qemu_get_be32s(f, &s->mouse_dz);
+    qemu_get_8s(f, &s->mouse_buttons);
+    qemu_get_be32s(f, &s->touchpad.absolute);
+    qemu_get_be32s(f, &s->touchpad.high);
+    return 0;
+}
+
+void kbd_init(void)
+{
+    KBDState *s = &kbd_state;
+    
+    kbd_reset(s);
+    register_savevm("pckbd", 0, 2, kbd_save, kbd_load, s);
+    register_ioport_read(0x60, 1, 1, kbd_read_data, s);
+    register_ioport_write(0x60, 1, 1, kbd_write_data, s);
+    register_ioport_read(0x64, 1, 1, kbd_read_status, s);
+    register_ioport_write(0x64, 1, 1, kbd_write_command, s);
+
+    qemu_add_kbd_event_handler(pc_kbd_put_keycode, s);
+    qemu_add_mouse_event_handler(pc_kbd_mouse_event, s);
+    qemu_register_reset(kbd_reset, s);
+}
diff --git a/tools/ioemu/hw/ppc.c b/tools/ioemu/hw/ppc.c
new file mode 100644 (file)
index 0000000..5f99229
--- /dev/null
@@ -0,0 +1,462 @@
+/*
+ * QEMU generic PPC hardware System Emulator
+ * 
+ * Copyright (c) 2003-2004 Jocelyn Mayer
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+#include "m48t59.h"
+
+/*****************************************************************************/
+/* PPC time base and decrementer emulation */
+//#define DEBUG_TB
+
+struct ppc_tb_t {
+    /* Time base management */
+    int64_t  tb_offset;    /* Compensation               */
+    uint32_t tb_freq;      /* TB frequency               */
+    /* Decrementer management */
+    uint64_t decr_next;    /* Tick for next decr interrupt  */
+    struct QEMUTimer *decr_timer;
+};
+
+static inline uint64_t cpu_ppc_get_tb (ppc_tb_t *tb_env)
+{
+    /* TB time in tb periods */
+    return muldiv64(qemu_get_clock(vm_clock) + tb_env->tb_offset,
+                   tb_env->tb_freq, ticks_per_sec);
+}
+
+uint32_t cpu_ppc_load_tbl (CPUState *env)
+{
+    ppc_tb_t *tb_env = env->tb_env;
+    uint64_t tb;
+
+    tb = cpu_ppc_get_tb(tb_env);
+#ifdef DEBUG_TB
+    {
+         static int last_time;
+        int now;
+        now = time(NULL);
+        if (last_time != now) {
+            last_time = now;
+            printf("%s: tb=0x%016lx %d %08lx\n",
+                    __func__, tb, now, tb_env->tb_offset);
+        }
+    }
+#endif
+
+    return tb & 0xFFFFFFFF;
+}
+
+uint32_t cpu_ppc_load_tbu (CPUState *env)
+{
+    ppc_tb_t *tb_env = env->tb_env;
+    uint64_t tb;
+
+    tb = cpu_ppc_get_tb(tb_env);
+#ifdef DEBUG_TB
+    printf("%s: tb=0x%016lx\n", __func__, tb);
+#endif
+    return tb >> 32;
+}
+
+static void cpu_ppc_store_tb (ppc_tb_t *tb_env, uint64_t value)
+{
+    tb_env->tb_offset = muldiv64(value, ticks_per_sec, tb_env->tb_freq)
+        - qemu_get_clock(vm_clock);
+#ifdef DEBUG_TB
+    printf("%s: tb=0x%016lx offset=%08x\n", __func__, value);
+#endif
+}
+
+void cpu_ppc_store_tbu (CPUState *env, uint32_t value)
+{
+    ppc_tb_t *tb_env = env->tb_env;
+
+    cpu_ppc_store_tb(tb_env,
+                     ((uint64_t)value << 32) | cpu_ppc_load_tbl(env));
+}
+
+void cpu_ppc_store_tbl (CPUState *env, uint32_t value)
+{
+    ppc_tb_t *tb_env = env->tb_env;
+
+    cpu_ppc_store_tb(tb_env,
+                     ((uint64_t)cpu_ppc_load_tbu(env) << 32) | value);
+}
+
+uint32_t cpu_ppc_load_decr (CPUState *env)
+{
+    ppc_tb_t *tb_env = env->tb_env;
+    uint32_t decr;
+
+    decr = muldiv64(tb_env->decr_next - qemu_get_clock(vm_clock),
+                    tb_env->tb_freq, ticks_per_sec);
+#if defined(DEBUG_TB)
+    printf("%s: 0x%08x\n", __func__, decr);
+#endif
+
+    return decr;
+}
+
+/* When decrementer expires,
+ * all we need to do is generate or queue a CPU exception
+ */
+static inline void cpu_ppc_decr_excp (CPUState *env)
+{
+    /* Raise it */
+#ifdef DEBUG_TB
+    printf("raise decrementer exception\n");
+#endif
+    cpu_interrupt(env, CPU_INTERRUPT_TIMER);
+}
+
+static void _cpu_ppc_store_decr (CPUState *env, uint32_t decr,
+                                 uint32_t value, int is_excp)
+{
+    ppc_tb_t *tb_env = env->tb_env;
+    uint64_t now, next;
+
+#ifdef DEBUG_TB
+    printf("%s: 0x%08x => 0x%08x\n", __func__, decr, value);
+#endif
+    now = qemu_get_clock(vm_clock);
+    next = now + muldiv64(value, ticks_per_sec, tb_env->tb_freq);
+    if (is_excp)
+        next += tb_env->decr_next - now;
+    if (next == now)
+       next++;
+    tb_env->decr_next = next;
+    /* Adjust timer */
+    qemu_mod_timer(tb_env->decr_timer, next);
+    /* If we set a negative value and the decrementer was positive,
+     * raise an exception.
+     */
+    if ((value & 0x80000000) && !(decr & 0x80000000))
+       cpu_ppc_decr_excp(env);
+}
+
+void cpu_ppc_store_decr (CPUState *env, uint32_t value)
+{
+    _cpu_ppc_store_decr(env, cpu_ppc_load_decr(env), value, 0);
+}
+
+static void cpu_ppc_decr_cb (void *opaque)
+{
+    _cpu_ppc_store_decr(opaque, 0x00000000, 0xFFFFFFFF, 1);
+}
+
+/* Set up (once) timebase frequency (in Hz) */
+ppc_tb_t *cpu_ppc_tb_init (CPUState *env, uint32_t freq)
+{
+    ppc_tb_t *tb_env;
+
+    tb_env = qemu_mallocz(sizeof(ppc_tb_t));
+    if (tb_env == NULL)
+        return NULL;
+    env->tb_env = tb_env;
+    if (tb_env->tb_freq == 0 || 1) {
+       tb_env->tb_freq = freq;
+       /* Create new timer */
+       tb_env->decr_timer =
+            qemu_new_timer(vm_clock, &cpu_ppc_decr_cb, env);
+       /* There is a bug in  2.4 kernels:
+        * if a decrementer exception is pending when it enables msr_ee,
+        * it's not ready to handle it...
+        */
+       _cpu_ppc_store_decr(env, 0xFFFFFFFF, 0xFFFFFFFF, 0);
+    }
+
+    return tb_env;
+}
+
+#if 0
+/*****************************************************************************/
+/* Handle system reset (for now, just stop emulation) */
+void cpu_ppc_reset (CPUState *env)
+{
+    printf("Reset asked... Stop emulation\n");
+    abort();
+}
+#endif
+
+static void PPC_io_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
+{
+    cpu_outb(NULL, addr & 0xffff, value);
+}
+
+static uint32_t PPC_io_readb (void *opaque, target_phys_addr_t addr)
+{
+    uint32_t ret = cpu_inb(NULL, addr & 0xffff);
+    return ret;
+}
+
+static void PPC_io_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
+{
+#ifdef TARGET_WORDS_BIGENDIAN
+    value = bswap16(value);
+#endif
+    cpu_outw(NULL, addr & 0xffff, value);
+}
+
+static uint32_t PPC_io_readw (void *opaque, target_phys_addr_t addr)
+{
+    uint32_t ret = cpu_inw(NULL, addr & 0xffff);
+#ifdef TARGET_WORDS_BIGENDIAN
+    ret = bswap16(ret);
+#endif
+    return ret;
+}
+
+static void PPC_io_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
+{
+#ifdef TARGET_WORDS_BIGENDIAN
+    value = bswap32(value);
+#endif
+    cpu_outl(NULL, addr & 0xffff, value);
+}
+
+static uint32_t PPC_io_readl (void *opaque, target_phys_addr_t addr)
+{
+    uint32_t ret = cpu_inl(NULL, addr & 0xffff);
+
+#ifdef TARGET_WORDS_BIGENDIAN
+    ret = bswap32(ret);
+#endif
+    return ret;
+}
+
+CPUWriteMemoryFunc *PPC_io_write[] = {
+    &PPC_io_writeb,
+    &PPC_io_writew,
+    &PPC_io_writel,
+};
+
+CPUReadMemoryFunc *PPC_io_read[] = {
+    &PPC_io_readb,
+    &PPC_io_readw,
+    &PPC_io_readl,
+};
+
+/*****************************************************************************/
+/* Debug port */
+void PPC_debug_write (void *opaque, uint32_t addr, uint32_t val)
+{
+    addr &= 0xF;
+    switch (addr) {
+    case 0:
+        printf("%c", val);
+        break;
+    case 1:
+        printf("\n");
+        fflush(stdout);
+        break;
+    case 2:
+        printf("Set loglevel to %04x\n", val);
+        cpu_set_log(val | 0x100);
+        break;
+    }
+}
+
+/*****************************************************************************/
+/* NVRAM helpers */
+void NVRAM_set_byte (m48t59_t *nvram, uint32_t addr, uint8_t value)
+{
+    m48t59_set_addr(nvram, addr);
+    m48t59_write(nvram, value);
+}
+
+uint8_t NVRAM_get_byte (m48t59_t *nvram, uint32_t addr)
+{
+    m48t59_set_addr(nvram, addr);
+    return m48t59_read(nvram);
+}
+
+void NVRAM_set_word (m48t59_t *nvram, uint32_t addr, uint16_t value)
+{
+    m48t59_set_addr(nvram, addr);
+    m48t59_write(nvram, value >> 8);
+    m48t59_set_addr(nvram, addr + 1);
+    m48t59_write(nvram, value & 0xFF);
+}
+
+uint16_t NVRAM_get_word (m48t59_t *nvram, uint32_t addr)
+{
+    uint16_t tmp;
+
+    m48t59_set_addr(nvram, addr);
+    tmp = m48t59_read(nvram) << 8;
+    m48t59_set_addr(nvram, addr + 1);
+    tmp |= m48t59_read(nvram);
+
+    return tmp;
+}
+
+void NVRAM_set_lword (m48t59_t *nvram, uint32_t addr, uint32_t value)
+{
+    m48t59_set_addr(nvram, addr);
+    m48t59_write(nvram, value >> 24);
+    m48t59_set_addr(nvram, addr + 1);
+    m48t59_write(nvram, (value >> 16) & 0xFF);
+    m48t59_set_addr(nvram, addr + 2);
+    m48t59_write(nvram, (value >> 8) & 0xFF);
+    m48t59_set_addr(nvram, addr + 3);
+    m48t59_write(nvram, value & 0xFF);
+}
+
+uint32_t NVRAM_get_lword (m48t59_t *nvram, uint32_t addr)
+{
+    uint32_t tmp;
+
+    m48t59_set_addr(nvram, addr);
+    tmp = m48t59_read(nvram) << 24;
+    m48t59_set_addr(nvram, addr + 1);
+    tmp |= m48t59_read(nvram) << 16;
+    m48t59_set_addr(nvram, addr + 2);
+    tmp |= m48t59_read(nvram) << 8;
+    m48t59_set_addr(nvram, addr + 3);
+    tmp |= m48t59_read(nvram);
+
+    return tmp;
+}
+
+void NVRAM_set_string (m48t59_t *nvram, uint32_t addr,
+                       const unsigned char *str, uint32_t max)
+{
+    int i;
+
+    for (i = 0; i < max && str[i] != '\0'; i++) {
+        m48t59_set_addr(nvram, addr + i);
+        m48t59_write(nvram, str[i]);
+    }
+    m48t59_set_addr(nvram, addr + max - 1);
+    m48t59_write(nvram, '\0');
+}
+
+int NVRAM_get_string (m48t59_t *nvram, uint8_t *dst, uint16_t addr, int max)
+{
+    int i;
+
+    memset(dst, 0, max);
+    for (i = 0; i < max; i++) {
+        dst[i] = NVRAM_get_byte(nvram, addr + i);
+        if (dst[i] == '\0')
+            break;
+    }
+
+    return i;
+}
+
+static uint16_t NVRAM_crc_update (uint16_t prev, uint16_t value)
+{
+    uint16_t tmp;
+    uint16_t pd, pd1, pd2;
+
+    tmp = prev >> 8;
+    pd = prev ^ value;
+    pd1 = pd & 0x000F;
+    pd2 = ((pd >> 4) & 0x000F) ^ pd1;
+    tmp ^= (pd1 << 3) | (pd1 << 8);
+    tmp ^= pd2 | (pd2 << 7) | (pd2 << 12);
+
+    return tmp;
+}
+
+uint16_t NVRAM_compute_crc (m48t59_t *nvram, uint32_t start, uint32_t count)
+{
+    uint32_t i;
+    uint16_t crc = 0xFFFF;
+    int odd;
+
+    odd = count & 1;
+    count &= ~1;
+    for (i = 0; i != count; i++) {
+       crc = NVRAM_crc_update(crc, NVRAM_get_word(nvram, start + i));
+    }
+    if (odd) {
+       crc = NVRAM_crc_update(crc, NVRAM_get_byte(nvram, start + i) << 8);
+    }
+
+    return crc;
+}
+
+#define CMDLINE_ADDR 0x017ff000
+
+int PPC_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size,
+                          const unsigned char *arch,
+                          uint32_t RAM_size, int boot_device,
+                          uint32_t kernel_image, uint32_t kernel_size,
+                          const char *cmdline,
+                          uint32_t initrd_image, uint32_t initrd_size,
+                          uint32_t NVRAM_image,
+                          int width, int height, int depth)
+{
+    uint16_t crc;
+
+    /* Set parameters for Open Hack'Ware BIOS */
+    NVRAM_set_string(nvram, 0x00, "QEMU_BIOS", 16);
+    NVRAM_set_lword(nvram,  0x10, 0x00000002); /* structure v2 */
+    NVRAM_set_word(nvram,   0x14, NVRAM_size);
+    NVRAM_set_string(nvram, 0x20, arch, 16);
+    NVRAM_set_lword(nvram,  0x30, RAM_size);
+    NVRAM_set_byte(nvram,   0x34, boot_device);
+    NVRAM_set_lword(nvram,  0x38, kernel_image);
+    NVRAM_set_lword(nvram,  0x3C, kernel_size);
+    if (cmdline) {
+        /* XXX: put the cmdline in NVRAM too ? */
+        strcpy(phys_ram_base + CMDLINE_ADDR, cmdline);
+        NVRAM_set_lword(nvram,  0x40, CMDLINE_ADDR);
+        NVRAM_set_lword(nvram,  0x44, strlen(cmdline));
+    } else {
+        NVRAM_set_lword(nvram,  0x40, 0);
+        NVRAM_set_lword(nvram,  0x44, 0);
+    }
+    NVRAM_set_lword(nvram,  0x48, initrd_image);
+    NVRAM_set_lword(nvram,  0x4C, initrd_size);
+    NVRAM_set_lword(nvram,  0x50, NVRAM_image);
+
+    NVRAM_set_word(nvram,   0x54, width);
+    NVRAM_set_word(nvram,   0x56, height);
+    NVRAM_set_word(nvram,   0x58, depth);
+    crc = NVRAM_compute_crc(nvram, 0x00, 0xF8);
+    NVRAM_set_word(nvram,  0xFC, crc);
+
+    return 0;
+ }
+
+/*****************************************************************************/
+void ppc_init (int ram_size, int vga_ram_size, int boot_device,
+              DisplayState *ds, const char **fd_filename, int snapshot,
+              const char *kernel_filename, const char *kernel_cmdline,
+              const char *initrd_filename)
+{
+    if (prep_enabled) {
+        ppc_prep_init(ram_size, vga_ram_size, boot_device, ds, fd_filename,
+                      snapshot, kernel_filename, kernel_cmdline,
+                      initrd_filename);
+    } else {
+        ppc_chrp_init(ram_size, vga_ram_size, boot_device, ds, fd_filename,
+                      snapshot, kernel_filename, kernel_cmdline,
+                      initrd_filename);
+    }
+    /* Special port to get debug messages from Open-Firmware */
+    register_ioport_write(0x0F00, 4, 1, &PPC_debug_write, NULL);
+}
diff --git a/tools/ioemu/hw/ppc_chrp.c b/tools/ioemu/hw/ppc_chrp.c
new file mode 100644 (file)
index 0000000..cf3a5f3
--- /dev/null
@@ -0,0 +1,233 @@
+/*
+ * QEMU PPC CHRP/PMAC hardware System Emulator
+ * 
+ * Copyright (c) 2004 Fabrice Bellard
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+
+#define BIOS_FILENAME "ppc_rom.bin"
+#define NVRAM_SIZE        0x2000
+
+#define KERNEL_LOAD_ADDR 0x01000000
+#define INITRD_LOAD_ADDR 0x01800000
+
+/* MacIO devices (mapped inside the MacIO address space): CUDA, DBDMA,
+   NVRAM (not implemented).  */
+
+static int dbdma_mem_index;
+static int cuda_mem_index;
+static int ide0_mem_index;
+static int ide1_mem_index;
+static int openpic_mem_index;
+
+/* DBDMA: currently no op - should suffice right now */
+
+static void dbdma_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
+{
+    printf("%s: 0x%08x <= 0x%08x\n", __func__, addr, value);
+}
+
+static void dbdma_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
+{
+}
+
+static void dbdma_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
+{
+}
+
+static uint32_t dbdma_readb (void *opaque, target_phys_addr_t addr)
+{
+    printf("%s: 0x%08x => 0x00000000\n", __func__, addr);
+    return 0;
+}
+
+static uint32_t dbdma_readw (void *opaque, target_phys_addr_t addr)
+{
+    return 0;
+}
+
+static uint32_t dbdma_readl (void *opaque, target_phys_addr_t addr)
+{
+    return 0;
+}
+
+static CPUWriteMemoryFunc *dbdma_write[] = {
+    &dbdma_writeb,
+    &dbdma_writew,
+    &dbdma_writel,
+};
+
+static CPUReadMemoryFunc *dbdma_read[] = {
+    &dbdma_readb,
+    &dbdma_readw,
+    &dbdma_readl,
+};
+
+static void macio_map(PCIDevice *pci_dev, int region_num, 
+                      uint32_t addr, uint32_t size, int type)
+{
+    cpu_register_physical_memory(addr + 0x08000, 0x1000, dbdma_mem_index);
+    cpu_register_physical_memory(addr + 0x16000, 0x2000, cuda_mem_index);
+    cpu_register_physical_memory(addr + 0x1f000, 0x1000, ide0_mem_index);
+    cpu_register_physical_memory(addr + 0x20000, 0x1000, ide1_mem_index);
+    cpu_register_physical_memory(addr + 0x40000, 0x40000, openpic_mem_index);
+}
+
+static void macio_init(PCIBus *bus)
+{
+    PCIDevice *d;
+
+    d = pci_register_device(bus, "macio", sizeof(PCIDevice),
+                            -1, NULL, NULL);
+    /* Note: this code is strongly inspirated from the corresponding code
+       in PearPC */
+    d->config[0x00] = 0x6b; // vendor_id
+    d->config[0x01] = 0x10;
+    d->config[0x02] = 0x22;
+    d->config[0x03] = 0x00;
+
+    d->config[0x0a] = 0x00; // class_sub = pci2pci
+    d->config[0x0b] = 0xff; // class_base = bridge
+    d->config[0x0e] = 0x00; // header_type
+
+    d->config[0x3d] = 0x01; // interrupt on pin 1
+    
+    dbdma_mem_index = cpu_register_io_memory(0, dbdma_read, dbdma_write, NULL);
+
+    pci_register_io_region(d, 0, 0x80000, 
+                           PCI_ADDRESS_SPACE_MEM, macio_map);
+}
+
+/* PowerPC PREP hardware initialisation */
+void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device,
+                  DisplayState *ds, const char **fd_filename, int snapshot,
+                  const char *kernel_filename, const char *kernel_cmdline,
+                  const char *initrd_filename)
+{
+    char buf[1024];
+    openpic_t *openpic;
+    m48t59_t *nvram;
+    int PPC_io_memory;
+    int ret, linux_boot, i;
+    unsigned long bios_offset;
+    uint32_t kernel_base, kernel_size, initrd_base, initrd_size;
+    PCIBus *pci_bus;
+
+    linux_boot = (kernel_filename != NULL);
+
+    /* allocate RAM */
+    cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
+
+    /* allocate and load BIOS */
+    bios_offset = ram_size + vga_ram_size;
+    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
+    ret = load_image(buf, phys_ram_base + bios_offset);
+    if (ret != BIOS_SIZE) {
+        fprintf(stderr, "qemu: could not load PPC PREP bios '%s'\n", buf);
+        exit(1);
+    }
+    cpu_register_physical_memory((uint32_t)(-BIOS_SIZE), 
+                                 BIOS_SIZE, bios_offset | IO_MEM_ROM);
+    cpu_single_env->nip = 0xfffffffc;
+
+    if (linux_boot) {
+        kernel_base = KERNEL_LOAD_ADDR;
+        /* now we can load the kernel */
+        kernel_size = load_image(kernel_filename, phys_ram_base + kernel_base);
+        if (kernel_size < 0) {
+            fprintf(stderr, "qemu: could not load kernel '%s'\n", 
+                    kernel_filename);
+            exit(1);
+        }
+        /* load initrd */
+        if (initrd_filename) {
+            initrd_base = INITRD_LOAD_ADDR;
+            initrd_size = load_image(initrd_filename,
+                                     phys_ram_base + initrd_base);
+            if (initrd_size < 0) {
+                fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", 
+                        initrd_filename);
+                exit(1);
+            }
+        } else {
+            initrd_base = 0;
+            initrd_size = 0;
+        }
+        boot_device = 'm';
+    } else {
+        kernel_base = 0;
+        kernel_size = 0;
+        initrd_base = 0;
+        initrd_size = 0;
+    }
+    /* Register CPU as a 74x/75x */
+    cpu_ppc_register(cpu_single_env, 0x00080000);
+    /* Set time-base frequency to 100 Mhz */
+    cpu_ppc_tb_init(cpu_single_env, 100UL * 1000UL * 1000UL);
+
+    isa_mem_base = 0x80000000;
+    pci_bus = pci_pmac_init();
+
+    /* Register 8 MB of ISA IO space */
+    PPC_io_memory = cpu_register_io_memory(0, PPC_io_read, PPC_io_write, NULL);
+    cpu_register_physical_memory(0xF2000000, 0x00800000, PPC_io_memory);
+
+    /* init basic PC hardware */
+    vga_initialize(pci_bus, ds, phys_ram_base + ram_size, ram_size, 
+                   vga_ram_size);
+    openpic = openpic_init(NULL, &openpic_mem_index, 1);
+    pci_pmac_set_openpic(pci_bus, openpic);
+    
+    /* XXX: suppress that */
+    pic_init();
+
+    /* XXX: use Mac Serial port */
+    serial_init(0x3f8, 4, serial_hds[0]);
+
+    for(i = 0; i < nb_nics; i++) {
+        pci_ne2000_init(pci_bus, &nd_table[i]);
+    }
+
+    ide0_mem_index = pmac_ide_init(&bs_table[0], openpic, 0x13);
+    ide1_mem_index = pmac_ide_init(&bs_table[2], openpic, 0x13);
+
+    /* cuda also initialize ADB */
+    cuda_mem_index = cuda_init(openpic, 0x19);
+
+    adb_kbd_init(&adb_bus);
+    adb_mouse_init(&adb_bus);
+    
+    macio_init(pci_bus);
+
+    nvram = m48t59_init(8, 0xFFF04000, 0x0074, NVRAM_SIZE);
+    
+    if (graphic_depth != 15 && graphic_depth != 32 && graphic_depth != 8)
+        graphic_depth = 15;
+
+    PPC_NVRAM_set_params(nvram, NVRAM_SIZE, "CHRP", ram_size, boot_device,
+                         kernel_base, kernel_size,
+                         kernel_cmdline,
+                         initrd_base, initrd_size,
+                         /* XXX: need an option to load a NVRAM image */
+                         0,
+                         graphic_width, graphic_height, graphic_depth);
+    /* No PCI init: the BIOS will do it */
+}
diff --git a/tools/ioemu/hw/ppc_prep.c b/tools/ioemu/hw/ppc_prep.c
new file mode 100644 (file)
index 0000000..c93b72f
--- /dev/null
@@ -0,0 +1,548 @@
+/*
+ * QEMU PPC PREP hardware System Emulator
+ * 
+ * Copyright (c) 2003-2004 Jocelyn Mayer
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+
+//#define HARD_DEBUG_PPC_IO
+//#define DEBUG_PPC_IO
+
+#define BIOS_FILENAME "ppc_rom.bin"
+#define KERNEL_LOAD_ADDR 0x01000000
+#define INITRD_LOAD_ADDR 0x01800000
+
+extern int loglevel;
+extern FILE *logfile;
+
+#if defined (HARD_DEBUG_PPC_IO) && !defined (DEBUG_PPC_IO)
+#define DEBUG_PPC_IO
+#endif
+
+#if defined (HARD_DEBUG_PPC_IO)
+#define PPC_IO_DPRINTF(fmt, args...)                     \
+do {                                                     \
+    if (loglevel & CPU_LOG_IOPORT) {                     \
+        fprintf(logfile, "%s: " fmt, __func__ , ##args); \
+    } else {                                             \
+        printf("%s : " fmt, __func__ , ##args);          \
+    }                                                    \
+} while (0)
+#elif defined (DEBUG_PPC_IO)
+#define PPC_IO_DPRINTF(fmt, args...)                     \
+do {                                                     \
+    if (loglevel & CPU_LOG_IOPORT) {                     \
+        fprintf(logfile, "%s: " fmt, __func__ , ##args); \
+    }                                                    \
+} while (0)
+#else
+#define PPC_IO_DPRINTF(fmt, args...) do { } while (0)
+#endif
+
+/* Constants for devices init */
+static const int ide_iobase[2] = { 0x1f0, 0x170 };
+static const int ide_iobase2[2] = { 0x3f6, 0x376 };
+static const int ide_irq[2] = { 13, 13 };
+
+#define NE2000_NB_MAX 6
+
+static uint32_t ne2000_io[NE2000_NB_MAX] = { 0x300, 0x320, 0x340, 0x360, 0x280, 0x380 };
+static int ne2000_irq[NE2000_NB_MAX] = { 9, 10, 11, 3, 4, 5 };
+
+//static PITState *pit;
+
+/* ISA IO ports bridge */
+#define PPC_IO_BASE 0x80000000
+
+/* Speaker port 0x61 */
+int speaker_data_on;
+int dummy_refresh_clock;
+
+static void speaker_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+{
+#if 0
+    speaker_data_on = (val >> 1) & 1;
+    pit_set_gate(pit, 2, val & 1);
+#endif
+}
+
+static uint32_t speaker_ioport_read(void *opaque, uint32_t addr)
+{
+#if 0
+    int out;
+    out = pit_get_out(pit, 2, qemu_get_clock(vm_clock));
+    dummy_refresh_clock ^= 1;
+    return (speaker_data_on << 1) | pit_get_gate(pit, 2) | (out << 5) |
+      (dummy_refresh_clock << 4);
+#endif
+    return 0;
+}
+
+/* PCI intack register */
+/* Read-only register (?) */
+static void _PPC_intack_write (void *opaque, target_phys_addr_t addr, uint32_t value)
+{
+    //    printf("%s: 0x%08x => 0x%08x\n", __func__, addr, value);
+}
+
+static inline uint32_t _PPC_intack_read (target_phys_addr_t addr)
+{
+    uint32_t retval = 0;
+
+    if (addr == 0xBFFFFFF0)
+        retval = pic_intack_read(NULL);
+       //   printf("%s: 0x%08x <= %d\n", __func__, addr, retval);
+
+    return retval;
+}
+
+static uint32_t PPC_intack_readb (void *opaque, target_phys_addr_t addr)
+{
+    return _PPC_intack_read(addr);
+}
+
+static uint32_t PPC_intack_readw (void *opaque, target_phys_addr_t addr)
+{
+#ifdef TARGET_WORDS_BIGENDIAN
+    return bswap16(_PPC_intack_read(addr));
+#else
+    return _PPC_intack_read(addr);
+#endif
+}
+
+static uint32_t PPC_intack_readl (void *opaque, target_phys_addr_t addr)
+{
+#ifdef TARGET_WORDS_BIGENDIAN
+    return bswap32(_PPC_intack_read(addr));
+#else
+    return _PPC_intack_read(addr);
+#endif
+}
+
+static CPUWriteMemoryFunc *PPC_intack_write[] = {
+    &_PPC_intack_write,
+    &_PPC_intack_write,
+    &_PPC_intack_write,
+};
+
+static CPUReadMemoryFunc *PPC_intack_read[] = {
+    &PPC_intack_readb,
+    &PPC_intack_readw,
+    &PPC_intack_readl,
+};
+
+/* PowerPC control and status registers */
+#if 0 // Not used
+static struct {
+    /* IDs */
+    uint32_t veni_devi;
+    uint32_t revi;
+    /* Control and status */
+    uint32_t gcsr;
+    uint32_t xcfr;
+    uint32_t ct32;
+    uint32_t mcsr;
+    /* General purpose registers */
+    uint32_t gprg[6];
+    /* Exceptions */
+    uint32_t feen;
+    uint32_t fest;
+    uint32_t fema;
+    uint32_t fecl;
+    uint32_t eeen;
+    uint32_t eest;
+    uint32_t eecl;
+    uint32_t eeint;
+    uint32_t eemck0;
+    uint32_t eemck1;
+    /* Error diagnostic */
+} XCSR;
+
+static void PPC_XCSR_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
+{
+    printf("%s: 0x%08lx => 0x%08x\n", __func__, (long)addr, value);
+}
+
+static void PPC_XCSR_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
+{
+#ifdef TARGET_WORDS_BIGENDIAN
+    value = bswap16(value);
+#endif
+    printf("%s: 0x%08lx => 0x%08x\n", __func__, (long)addr, value);
+}
+
+static void PPC_XCSR_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
+{
+#ifdef TARGET_WORDS_BIGENDIAN
+    value = bswap32(value);
+#endif
+    printf("%s: 0x%08lx => 0x%08x\n", __func__, (long)addr, value);
+}
+
+static uint32_t PPC_XCSR_readb (void *opaque, target_phys_addr_t addr)
+{
+    uint32_t retval = 0;
+
+    printf("%s: 0x%08lx <= %d\n", __func__, (long)addr, retval);
+
+    return retval;
+}
+
+static uint32_t PPC_XCSR_readw (void *opaque, target_phys_addr_t addr)
+{
+    uint32_t retval = 0;
+
+    printf("%s: 0x%08lx <= %d\n", __func__, (long)addr, retval);
+#ifdef TARGET_WORDS_BIGENDIAN
+    retval = bswap16(retval);
+#endif
+
+    return retval;
+}
+
+static uint32_t PPC_XCSR_readl (void *opaque, target_phys_addr_t addr)
+{
+    uint32_t retval = 0;
+
+    printf("%s: 0x%08lx <= %d\n", __func__, (long)addr, retval);
+#ifdef TARGET_WORDS_BIGENDIAN
+    retval = bswap32(retval);
+#endif
+
+    return retval;
+}
+
+static CPUWriteMemoryFunc *PPC_XCSR_write[] = {
+    &PPC_XCSR_writeb,
+    &PPC_XCSR_writew,
+    &PPC_XCSR_writel,
+};
+
+static CPUReadMemoryFunc *PPC_XCSR_read[] = {
+    &PPC_XCSR_readb,
+    &PPC_XCSR_readw,
+    &PPC_XCSR_readl,
+};
+#endif
+
+/* Fake super-io ports for PREP platform (Intel 82378ZB) */
+typedef struct sysctrl_t {
+    m48t59_t *nvram;
+    uint8_t state;
+    uint8_t syscontrol;
+    uint8_t fake_io[2];
+} sysctrl_t;
+
+enum {
+    STATE_HARDFILE = 0x01,
+};
+
+static sysctrl_t *sysctrl;
+
+static void PREP_io_write (void *opaque, uint32_t addr, uint32_t val)
+{
+    sysctrl_t *sysctrl = opaque;
+
+    PPC_IO_DPRINTF("0x%08lx => 0x%08x\n", (long)addr - PPC_IO_BASE, val);
+    sysctrl->fake_io[addr - 0x0398] = val;
+}
+
+static uint32_t PREP_io_read (void *opaque, uint32_t addr)
+{
+    sysctrl_t *sysctrl = opaque;
+
+    PPC_IO_DPRINTF("0x%08lx <= 0x%08x\n", (long)addr - PPC_IO_BASE,
+                   sysctrl->fake_io[addr - 0x0398]);
+    return sysctrl->fake_io[addr - 0x0398];
+}
+
+static void PREP_io_800_writeb (void *opaque, uint32_t addr, uint32_t val)
+{
+    sysctrl_t *sysctrl = opaque;
+
+    PPC_IO_DPRINTF("0x%08lx => 0x%08x\n", (long)addr - PPC_IO_BASE, val);
+    switch (addr) {
+    case 0x0092:
+        /* Special port 92 */
+        /* Check soft reset asked */
+        if (val & 0x01) {
+            //            cpu_interrupt(cpu_single_env, CPU_INTERRUPT_RESET);
+        }
+        /* Check LE mode */
+        if (val & 0x02) {
+            printf("Little Endian mode isn't supported (yet ?)\n");
+            abort();
+        }
+        break;
+    case 0x0800:
+        /* Motorola CPU configuration register : read-only */
+        break;
+    case 0x0802:
+        /* Motorola base module feature register : read-only */
+        break;
+    case 0x0803:
+        /* Motorola base module status register : read-only */
+        break;
+    case 0x0808:
+        /* Hardfile light register */
+        if (val & 1)
+            sysctrl->state |= STATE_HARDFILE;
+        else
+            sysctrl->state &= ~STATE_HARDFILE;
+        break;
+    case 0x0810:
+        /* Password protect 1 register */
+        if (sysctrl->nvram != NULL)
+            m48t59_toggle_lock(sysctrl->nvram, 1);
+        break;
+    case 0x0812:
+        /* Password protect 2 register */
+        if (sysctrl->nvram != NULL)
+            m48t59_toggle_lock(sysctrl->nvram, 2);
+        break;
+    case 0x0814:
+        /* L2 invalidate register */
+        //        tlb_flush(cpu_single_env, 1);
+        break;
+    case 0x081C:
+        /* system control register */
+        sysctrl->syscontrol = val & 0x0F;
+        break;
+    case 0x0850:
+        /* I/O map type register */
+        if (!(val & 0x01)) {
+            printf("No support for non-continuous I/O map mode\n");
+            abort();
+        }
+        break;
+    default:
+        printf("ERROR: unaffected IO port write: %04lx => %02x\n",
+               (long)addr, val);
+        break;
+    }
+}
+
+static uint32_t PREP_io_800_readb (void *opaque, uint32_t addr)
+{
+    sysctrl_t *sysctrl = opaque;
+    uint32_t retval = 0xFF;
+
+    switch (addr) {
+    case 0x0092:
+        /* Special port 92 */
+        retval = 0x00;
+        break;
+    case 0x0800:
+        /* Motorola CPU configuration register */
+        retval = 0xEF; /* MPC750 */
+        break;
+    case 0x0802:
+        /* Motorola Base module feature register */
+        retval = 0xAD; /* No ESCC, PMC slot neither ethernet */
+        break;
+    case 0x0803:
+        /* Motorola base module status register */
+        retval = 0xE0; /* Standard MPC750 */
+        break;
+    case 0x080C:
+        /* Equipment present register:
+         *  no L2 cache
+         *  no upgrade processor
+         *  no cards in PCI slots
+         *  SCSI fuse is bad
+         */
+        retval = 0x3C;
+        break;
+    case 0x0810:
+        /* Motorola base module extended feature register */
+        retval = 0x39; /* No USB, CF and PCI bridge. NVRAM present */
+        break;
+    case 0x0818:
+        /* Keylock */
+        retval = 0x00;
+        break;
+    case 0x081C:
+        /* system control register
+         * 7 - 6 / 1 - 0: L2 cache enable
+         */
+        retval = sysctrl->syscontrol;
+        break;
+    case 0x0823:
+        /* */
+        retval = 0x03; /* no L2 cache */
+        break;
+    case 0x0850:
+        /* I/O map type register */
+        retval = 0x01;
+        break;
+    default:
+        printf("ERROR: unaffected IO port: %04lx read\n", (long)addr);
+        break;
+    }
+    PPC_IO_DPRINTF("0x%08lx <= 0x%08x\n", (long)addr - PPC_IO_BASE, retval);
+
+    return retval;
+}
+
+extern CPUPPCState *global_env;
+
+#define NVRAM_SIZE        0x2000
+
+/* PowerPC PREP hardware initialisation */
+void ppc_prep_init(int ram_size, int vga_ram_size, int boot_device,
+                  DisplayState *ds, const char **fd_filename, int snapshot,
+                  const char *kernel_filename, const char *kernel_cmdline,
+                  const char *initrd_filename)
+{
+    char buf[1024];
+    m48t59_t *nvram;
+    int PPC_io_memory;
+    int ret, linux_boot, i, nb_nics1;
+    unsigned long bios_offset;
+    uint32_t kernel_base, kernel_size, initrd_base, initrd_size;
+    PCIBus *pci_bus;
+
+    sysctrl = qemu_mallocz(sizeof(sysctrl_t));
+    if (sysctrl == NULL)
+       return;
+
+    linux_boot = (kernel_filename != NULL);
+
+    /* allocate RAM */
+    cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
+
+    /* allocate and load BIOS */
+    bios_offset = ram_size + vga_ram_size;
+    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
+    ret = load_image(buf, phys_ram_base + bios_offset);
+    if (ret != BIOS_SIZE) {
+        fprintf(stderr, "qemu: could not load PPC PREP bios '%s'\n", buf);
+        exit(1);
+    }
+    cpu_register_physical_memory((uint32_t)(-BIOS_SIZE), 
+                                 BIOS_SIZE, bios_offset | IO_MEM_ROM);
+    cpu_single_env->nip = 0xfffffffc;
+
+    if (linux_boot) {
+        kernel_base = KERNEL_LOAD_ADDR;
+        /* now we can load the kernel */
+        kernel_size = load_image(kernel_filename, phys_ram_base + kernel_base);
+        if (kernel_size < 0) {
+            fprintf(stderr, "qemu: could not load kernel '%s'\n", 
+                    kernel_filename);
+            exit(1);
+        }
+        /* load initrd */
+        if (initrd_filename) {
+            initrd_base = INITRD_LOAD_ADDR;
+            initrd_size = load_image(initrd_filename,
+                                     phys_ram_base + initrd_base);
+            if (initrd_size < 0) {
+                fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", 
+                        initrd_filename);
+                exit(1);
+            }
+        } else {
+            initrd_base = 0;
+            initrd_size = 0;
+        }
+        boot_device = 'm';
+    } else {
+        kernel_base = 0;
+        kernel_size = 0;
+        initrd_base = 0;
+        initrd_size = 0;
+    }
+
+    /* Register CPU as a 74x/75x */
+    cpu_ppc_register(cpu_single_env, 0x00080000);
+    /* Set time-base frequency to 100 Mhz */
+    cpu_ppc_tb_init(cpu_single_env, 100UL * 1000UL * 1000UL);
+
+    isa_mem_base = 0xc0000000;
+    pci_bus = pci_prep_init();
+    /* Register 64 KB of ISA IO space */
+    PPC_io_memory = cpu_register_io_memory(0, PPC_io_read, PPC_io_write, NULL);
+    cpu_register_physical_memory(0x80000000, 0x00010000, PPC_io_memory);
+
+    /* init basic PC hardware */
+    vga_initialize(pci_bus, ds, phys_ram_base + ram_size, ram_size, 
+                   vga_ram_size);
+    rtc_init(0x70, 8);
+    //    openpic = openpic_init(0x00000000, 0xF0000000, 1);
+    //    pic_init(openpic);
+    pic_init();
+    //    pit = pit_init(0x40, 0);
+
+    serial_init(0x3f8, 4, serial_hds[0]);
+    nb_nics1 = nb_nics;
+    if (nb_nics1 > NE2000_NB_MAX)
+        nb_nics1 = NE2000_NB_MAX;
+    for(i = 0; i < nb_nics1; i++) {
+        isa_ne2000_init(ne2000_io[i], ne2000_irq[i], &nd_table[i]);
+    }
+
+    for(i = 0; i < 2; i++) {
+        isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i],
+                     bs_table[2 * i], bs_table[2 * i + 1]);
+    }
+    kbd_init();
+    DMA_init(1);
+    //    AUD_init();
+    //    SB16_init();
+
+    fdctrl_init(6, 2, 0, 0x3f0, fd_table);
+
+    /* Register speaker port */
+    register_ioport_read(0x61, 1, 1, speaker_ioport_read, NULL);
+    register_ioport_write(0x61, 1, 1, speaker_ioport_write, NULL);
+    /* Register fake IO ports for PREP */
+    register_ioport_read(0x398, 2, 1, &PREP_io_read, sysctrl);
+    register_ioport_write(0x398, 2, 1, &PREP_io_write, sysctrl);
+    /* System control ports */
+    register_ioport_read(0x0092, 0x01, 1, &PREP_io_800_readb, sysctrl);
+    register_ioport_write(0x0092, 0x01, 1, &PREP_io_800_writeb, sysctrl);
+    register_ioport_read(0x0800, 0x52, 1, &PREP_io_800_readb, sysctrl);
+    register_ioport_write(0x0800, 0x52, 1, &PREP_io_800_writeb, sysctrl);
+    /* PCI intack location */
+    PPC_io_memory = cpu_register_io_memory(0, PPC_intack_read,
+                                           PPC_intack_write, NULL);
+    cpu_register_physical_memory(0xBFFFFFF0, 0x4, PPC_io_memory);
+    /* PowerPC control and status register group */
+#if 0
+    PPC_io_memory = cpu_register_io_memory(0, PPC_XCSR_read, PPC_XCSR_write, NULL);
+    cpu_register_physical_memory(0xFEFF0000, 0x1000, PPC_io_memory);
+#endif
+
+    nvram = m48t59_init(8, 0, 0x0074, NVRAM_SIZE);
+    if (nvram == NULL)
+        return;
+    sysctrl->nvram = nvram;
+
+    /* Initialise NVRAM */
+    PPC_NVRAM_set_params(nvram, NVRAM_SIZE, "PREP", ram_size, boot_device,
+                         kernel_base, kernel_size,
+                         kernel_cmdline,
+                         initrd_base, initrd_size,
+                         /* XXX: need an option to load a NVRAM image */
+                         0,
+                         graphic_width, graphic_height, graphic_depth);
+}
diff --git a/tools/ioemu/hw/sb16.c b/tools/ioemu/hw/sb16.c
new file mode 100644 (file)
index 0000000..33026fe
--- /dev/null
@@ -0,0 +1,1268 @@
+/*
+ * QEMU Soundblaster 16 emulation
+ * 
+ * Copyright (c) 2003-2004 Vassili Karpov (malc)
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+
+#define LENOFA(a) ((int) (sizeof(a)/sizeof(a[0])))
+
+#define dolog(...) AUD_log ("sb16", __VA_ARGS__)
+
+/* #define DEBUG */
+/* #define DEBUG_SB16_MOST */
+
+#ifdef DEBUG
+#define ldebug(...) dolog (__VA_ARGS__)
+#else
+#define ldebug(...)
+#endif
+
+#define IO_READ_PROTO(name)                             \
+    uint32_t name (void *opaque, uint32_t nport)
+#define IO_WRITE_PROTO(name)                                    \
+    void name (void *opaque, uint32_t nport, uint32_t val)
+
+static const char e3[] = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992.";
+
+static struct {
+    int ver_lo;
+    int ver_hi;
+    int irq;
+    int dma;
+    int hdma;
+    int port;
+} conf = {5, 4, 5, 1, 5, 0x220};
+
+typedef struct SB16State {
+    int irq;
+    int dma;
+    int hdma;
+    int port;
+    int ver;
+
+    int in_index;
+    int out_data_len;
+    int fmt_stereo;
+    int fmt_signed;
+    int fmt_bits;
+    audfmt_e fmt;
+    int dma_auto;
+    int block_size;
+    int fifo;
+    int freq;
+    int time_const;
+    int speaker;
+    int needed_bytes;
+    int cmd;
+    int use_hdma;
+    int highspeed;
+    int can_write;
+
+    int v2x6;
+
+    uint8_t csp_param;
+    uint8_t csp_value;
+    uint8_t csp_mode;
+    uint8_t csp_regs[256];
+    uint8_t csp_index;
+    uint8_t csp_reg83[4];
+    int csp_reg83r;
+    int csp_reg83w;
+
+    uint8_t in2_data[10];
+    uint8_t out_data[50];
+    uint8_t test_reg;
+    uint8_t last_read_byte;
+    int nzero;
+
+    int left_till_irq;
+
+    int dma_running;
+    int bytes_per_second;
+    int align;
+    SWVoice *voice;
+
+    QEMUTimer *ts, *aux_ts;
+    /* mixer state */
+    int mixer_nreg;
+    uint8_t mixer_regs[256];
+} SB16State;
+
+/* XXX: suppress that and use a context */
+static struct SB16State dsp;
+
+static int magic_of_irq (int irq)
+{
+    switch (irq) {
+    case 5:
+        return 2;
+    case 7:
+        return 4;
+    case 9:
+        return 1;
+    case 10:
+        return 8;
+    default:
+        dolog ("bad irq %d\n", irq);
+        return 2;
+    }
+}
+
+static int irq_of_magic (int magic)
+{
+    switch (magic) {
+    case 1:
+        return 9;
+    case 2:
+        return 5;
+    case 4:
+        return 7;
+    case 8:
+        return 10;
+    default:
+        dolog ("bad irq magic %d\n", magic);
+        return -1;
+    }
+}
+
+#if 0
+static void log_dsp (SB16State *dsp)
+{
+    ldebug ("%s:%s:%d:%s:dmasize=%d:freq=%d:const=%d:speaker=%d\n",
+            dsp->fmt_stereo ? "Stereo" : "Mono",
+            dsp->fmt_signed ? "Signed" : "Unsigned",
+            dsp->fmt_bits,
+            dsp->dma_auto ? "Auto" : "Single",
+            dsp->block_size,
+            dsp->freq,
+            dsp->time_const,
+            dsp->speaker);
+}
+#endif
+
+static void speaker (SB16State *s, int on)
+{
+    s->speaker = on;
+    /* AUD_enable (s->voice, on); */
+}
+
+static void control (SB16State *s, int hold)
+{
+    int dma = s->use_hdma ? s->hdma : s->dma;
+    s->dma_running = hold;
+
+    ldebug ("hold %d high %d dma %d\n", hold, s->use_hdma, dma);
+
+    if (hold) {
+        DMA_hold_DREQ (dma);
+        AUD_enable (s->voice, 1);
+    }
+    else {
+        DMA_release_DREQ (dma);
+        AUD_enable (s->voice, 0);
+    }
+}
+
+static void aux_timer (void *opaque)
+{
+    SB16State *s = opaque;
+    s->can_write = 1;
+    pic_set_irq (s->irq, 1);
+}
+
+#define DMA8_AUTO 1
+#define DMA8_HIGH 2
+
+static void dma_cmd8 (SB16State *s, int mask, int dma_len)
+{
+    s->fmt = AUD_FMT_U8;
+    s->use_hdma = 0;
+    s->fmt_bits = 8;
+    s->fmt_signed = 0;
+    s->fmt_stereo = (s->mixer_regs[0x0e] & 2) != 0;
+    if (-1 == s->time_const) {
+        s->freq = 11025;
+    }
+    else {
+        int tmp = (256 - s->time_const);
+        s->freq = (1000000 + (tmp / 2)) / tmp;
+    }
+
+    if (dma_len != -1)
+        s->block_size = dma_len << s->fmt_stereo;
+    else {
+        /* This is apparently the only way to make both Act1/PL
+           and SecondReality/FC work
+
+           Act1 sets block size via command 0x48 and it's an odd number
+           SR does the same with even number
+           Both use stereo, and Creatives own documentation states that
+           0x48 sets block size in bytes less one.. go figure */
+        s->block_size &= ~s->fmt_stereo;
+    }
+
+    s->freq >>= s->fmt_stereo;
+    s->left_till_irq = s->block_size;
+    s->bytes_per_second = (s->freq << s->fmt_stereo);
+    /* s->highspeed = (mask & DMA8_HIGH) != 0; */
+    s->dma_auto = (mask & DMA8_AUTO) != 0;
+    s->align = (1 << s->fmt_stereo) - 1;
+
+    if (s->block_size & s->align)
+        dolog ("warning: unaligned buffer\n");
+
+    ldebug ("freq %d, stereo %d, sign %d, bits %d, "
+            "dma %d, auto %d, fifo %d, high %d\n",
+            s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
+            s->block_size, s->dma_auto, s->fifo, s->highspeed);
+
+    if (s->freq)
+        s->voice = AUD_open (s->voice, "sb16", s->freq,
+                             1 << s->fmt_stereo, s->fmt);
+
+    control (s, 1);
+    speaker (s, 1);
+}
+
+static void dma_cmd (SB16State *s, uint8_t cmd, uint8_t d0, int dma_len)
+{
+    s->use_hdma = cmd < 0xc0;
+    s->fifo = (cmd >> 1) & 1;
+    s->dma_auto = (cmd >> 2) & 1;
+    s->fmt_signed = (d0 >> 4) & 1;
+    s->fmt_stereo = (d0 >> 5) & 1;
+
+    switch (cmd >> 4) {
+    case 11:
+        s->fmt_bits = 16;
+        break;
+
+    case 12:
+        s->fmt_bits = 8;
+        break;
+    }
+
+    if (-1 != s->time_const) {
+#if 1
+        int tmp = 256 - s->time_const;
+        s->freq = (1000000 + (tmp / 2)) / tmp;
+#else
+        /* s->freq = 1000000 / ((255 - s->time_const) << s->fmt_stereo); */
+        s->freq = 1000000 / ((255 - s->time_const));
+#endif
+        s->time_const = -1;
+    }
+
+    s->block_size = dma_len + 1;
+    s->block_size <<= (s->fmt_bits == 16);
+    if (!s->dma_auto) {
+        /* It is clear that for DOOM and auto-init this value
+           shouldn't take stereo into account, while Miles Sound Systems
+           setsound.exe with single transfer mode wouldn't work without it
+           wonders of SB16 yet again */
+        s->block_size <<= s->fmt_stereo;
+    }
+
+    ldebug ("freq %d, stereo %d, sign %d, bits %d, "
+            "dma %d, auto %d, fifo %d, high %d\n",
+            s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
+            s->block_size, s->dma_auto, s->fifo, s->highspeed);
+
+    if (16 == s->fmt_bits) {
+        if (s->fmt_signed) {
+            s->fmt = AUD_FMT_S16;
+        }
+        else {
+            s->fmt = AUD_FMT_U16;
+        }
+    }
+    else {
+        if (s->fmt_signed) {
+            s->fmt = AUD_FMT_S8;
+        }
+        else {
+            s->fmt = AUD_FMT_U8;
+        }
+    }
+
+    s->left_till_irq = s->block_size;
+
+    s->bytes_per_second = (s->freq << s->fmt_stereo) << (s->fmt_bits == 16);
+    s->highspeed = 0;
+    s->align = (1 << (s->fmt_stereo + (s->fmt_bits == 16))) - 1;
+    if (s->block_size & s->align)
+        dolog ("warning: unaligned buffer\n");
+
+    if (s->freq)
+        s->voice = AUD_open (s->voice, "sb16", s->freq,
+                             1 << s->fmt_stereo, s->fmt);
+
+    control (s, 1);
+    speaker (s, 1);
+}
+
+static inline void dsp_out_data (SB16State *s, uint8_t val)
+{
+    ldebug ("outdata %#x\n", val);
+    if (s->out_data_len < sizeof (s->out_data))
+        s->out_data[s->out_data_len++] = val;
+}
+
+static inline uint8_t dsp_get_data (SB16State *s)
+{
+    if (s->in_index)
+        return s->in2_data[--s->in_index];
+    else {
+        dolog ("buffer underflow\n");
+        return 0;
+    }
+}
+
+static void command (SB16State *s, uint8_t cmd)
+{
+    ldebug ("command %#x\n", cmd);
+
+    if (cmd > 0xaf && cmd < 0xd0) {
+        if (cmd & 8) {
+            dolog ("ADC not yet supported (command %#x)\n", cmd);
+        }
+
+        switch (cmd >> 4) {
+        case 11:
+        case 12:
+            break;
+        default:
+            dolog ("%#x wrong bits\n", cmd);
+        }
+        s->needed_bytes = 3;
+    }
+    else {
+        switch (cmd) {
+        case 0x03:
+            dsp_out_data (s, 0x10); /* s->csp_param); */
+            goto warn;
+
+        case 0x04:
+            s->needed_bytes = 1;
+            goto warn;
+
+        case 0x05:
+            s->needed_bytes = 2;
+            goto warn;
+
+        case 0x08:
+            /* __asm__ ("int3"); */
+            goto warn;
+
+        case 0x0e:
+            s->needed_bytes = 2;
+            goto warn;
+
+        case 0x09:
+            dsp_out_data (s, 0xf8);
+            goto warn;
+
+        case 0x0f:
+            s->needed_bytes = 1;
+            goto warn;
+
+        case 0x10:
+            s->needed_bytes = 1;
+            goto warn;
+
+        case 0x14:
+            s->needed_bytes = 2;
+            s->block_size = 0;
+            break;
+
+        case 0x1c:              /* Auto-Initialize DMA DAC, 8-bit */
+            control (s, 1);
+            break;
+
+        case 0x20:              /* Direct ADC, Juice/PL */
+            dsp_out_data (s, 0xff);
+            goto warn;
+
+        case 0x35:
+            dolog ("MIDI command(0x35) not implemented\n");
+            break;
+
+        case 0x40:
+            s->freq = -1;
+            s->time_const = -1;
+            s->needed_bytes = 1;
+            break;
+
+        case 0x41:
+            s->freq = -1;
+            s->time_const = -1;
+            s->needed_bytes = 2;
+            break;
+
+        case 0x42:
+            s->freq = -1;
+            s->time_const = -1;
+            s->needed_bytes = 2;
+            goto warn;
+
+        case 0x45:
+            dsp_out_data (s, 0xaa);
+            goto warn;
+
+        case 0x47:                /* Continue Auto-Initialize DMA 16bit */
+            break;
+
+        case 0x48:
+            s->needed_bytes = 2;
+            break;
+
+        case 0x80:
+            s->needed_bytes = 2;
+            break;
+
+        case 0x90:
+        case 0x91:
+            dma_cmd8 (s, ((cmd & 1) == 0) | DMA8_HIGH, -1);
+            break;
+
+        case 0xd0:              /* halt DMA operation. 8bit */
+            control (s, 0);
+            break;
+
+        case 0xd1:              /* speaker on */
+            speaker (s, 1);
+            break;
+
+        case 0xd3:              /* speaker off */
+            speaker (s, 0);
+            break;
+
+        case 0xd4:              /* continue DMA operation. 8bit */
+            control (s, 1);
+            break;
+
+        case 0xd5:              /* halt DMA operation. 16bit */
+            control (s, 0);
+            break;
+
+        case 0xd6:              /* continue DMA operation. 16bit */
+            control (s, 1);
+            break;
+
+        case 0xd9:              /* exit auto-init DMA after this block. 16bit */
+            s->dma_auto = 0;
+            break;
+
+        case 0xda:              /* exit auto-init DMA after this block. 8bit */
+            s->dma_auto = 0;
+            break;
+
+        case 0xe0:
+            s->needed_bytes = 1;
+            goto warn;
+
+        case 0xe1:
+            dsp_out_data (s, s->ver & 0xff);
+            dsp_out_data (s, s->ver >> 8);
+            break;
+
+        case 0xe2:
+            s->needed_bytes = 1;
+            goto warn;
+
+        case 0xe3:
+            {
+                int i;
+                for (i = sizeof (e3) - 1; i >= 0; --i)
+                    dsp_out_data (s, e3[i]);
+            }
+            break;
+
+        case 0xe4:              /* write test reg */
+            s->needed_bytes = 1;
+            break;
+
+        case 0xe7:
+            dolog ("Attempt to probe for ESS (0xe7)?\n");
+            return;
+
+        case 0xe8:              /* read test reg */
+            dsp_out_data (s, s->test_reg);
+            break;
+
+        case 0xf2:
+        case 0xf3:
+            dsp_out_data (s, 0xaa);
+            s->mixer_regs[0x82] |= (cmd == 0xf2) ? 1 : 2;
+            pic_set_irq (s->irq, 1);
+            break;
+
+        case 0xf9:
+            s->needed_bytes = 1;
+            goto warn;
+
+        case 0xfa:
+            dsp_out_data (s, 0);
+            goto warn;
+
+        case 0xfc:              /* FIXME */
+            dsp_out_data (s, 0);
+            goto warn;
+
+        default:
+            dolog ("unrecognized command %#x\n", cmd);
+            return;
+        }
+    }
+
+    s->cmd = cmd;
+    if (!s->needed_bytes)
+        ldebug ("\n");
+    return;
+
+ warn:
+    dolog ("warning: command %#x,%d is not trully understood yet\n",
+           cmd, s->needed_bytes);
+    s->cmd = cmd;
+    return;
+}
+
+static uint16_t dsp_get_lohi (SB16State *s)
+{
+    uint8_t hi = dsp_get_data (s);
+    uint8_t lo = dsp_get_data (s);
+    return (hi << 8) | lo;
+}
+
+static uint16_t dsp_get_hilo (SB16State *s)
+{
+    uint8_t lo = dsp_get_data (s);
+    uint8_t hi = dsp_get_data (s);
+    return (hi << 8) | lo;
+}
+
+static void complete (SB16State *s)
+{
+    int d0, d1, d2;
+    ldebug ("complete command %#x, in_index %d, needed_bytes %d\n",
+            s->cmd, s->in_index, s->needed_bytes);
+
+    if (s->cmd > 0xaf && s->cmd < 0xd0) {
+        d2 = dsp_get_data (s);
+        d1 = dsp_get_data (s);
+        d0 = dsp_get_data (s);
+
+        if (s->cmd & 8) {
+            dolog ("ADC params cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
+                   s->cmd, d0, d1, d2);
+        }
+        else {
+            ldebug ("cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
+                    s->cmd, d0, d1, d2);
+            dma_cmd (s, s->cmd, d0, d1 + (d2 << 8));
+        }
+    }
+    else {
+        switch (s->cmd) {
+        case 0x04:
+            s->csp_mode = dsp_get_data (s);
+            s->csp_reg83r = 0;
+            s->csp_reg83w = 0;
+            ldebug ("CSP command 0x04: mode=%#x\n", s->csp_mode);
+            break;
+
+        case 0x05:
+            s->csp_param = dsp_get_data (s);
+            s->csp_value = dsp_get_data (s);
+            ldebug ("CSP command 0x05: param=%#x value=%#x\n",
+                    s->csp_param,
+                    s->csp_value);
+            break;
+
+        case 0x0e:
+            d0 = dsp_get_data (s);
+            d1 = dsp_get_data (s);
+            ldebug ("write CSP register %d <- %#x\n", d1, d0);
+            if (d1 == 0x83) {
+                ldebug ("0x83[%d] <- %#x\n", s->csp_reg83r, d0);
+                s->csp_reg83[s->csp_reg83r % 4] = d0;
+                s->csp_reg83r += 1;
+            }
+            else
+                s->csp_regs[d1] = d0;
+            break;
+
+        case 0x0f:
+            d0 = dsp_get_data (s);
+            ldebug ("read CSP register %#x -> %#x, mode=%#x\n",
+                    d0, s->csp_regs[d0], s->csp_mode);
+            if (d0 == 0x83) {
+                ldebug ("0x83[%d] -> %#x\n",
+                        s->csp_reg83w,
+                        s->csp_reg83[s->csp_reg83w % 4]);
+                dsp_out_data (s, s->csp_reg83[s->csp_reg83w % 4]);
+                s->csp_reg83w += 1;
+            }
+            else
+                dsp_out_data (s, s->csp_regs[d0]);
+            break;
+
+        case 0x10:
+            d0 = dsp_get_data (s);
+            dolog ("cmd 0x10 d0=%#x\n", d0);
+            break;
+
+        case 0x14:
+            dma_cmd8 (s, 0, dsp_get_lohi (s) + 1);
+            break;
+
+        case 0x40:
+            s->time_const = dsp_get_data (s);
+            ldebug ("set time const %d\n", s->time_const);
+            break;
+
+        case 0x42:              /* FT2 sets output freq with this, go figure */
+            dolog ("cmd 0x42 might not do what it think it should\n");
+
+        case 0x41:
+            s->freq = dsp_get_hilo (s);
+            ldebug ("set freq %d\n", s->freq);
+            break;
+
+        case 0x48:
+            s->block_size = dsp_get_lohi (s) + 1;
+            ldebug ("set dma block len %d\n", s->block_size);
+            break;
+
+        case 0x80:
+            {
+                int freq, samples, bytes;
+                int64_t ticks;
+
+                freq = s->freq > 0 ? s->freq : 11025;
+                samples = dsp_get_lohi (s) + 1;
+                bytes = samples << s->fmt_stereo << (s->fmt_bits == 16);
+                ticks = (bytes * ticks_per_sec) / freq;
+                if (ticks < ticks_per_sec / 1024)
+                    pic_set_irq (s->irq, 1);
+                else
+                    qemu_mod_timer (s->aux_ts, qemu_get_clock (vm_clock) + ticks);
+                ldebug ("mix silence %d %d %lld\n", samples, bytes, ticks);
+            }
+            break;
+
+        case 0xe0:
+            d0 = dsp_get_data (s);
+            s->out_data_len = 0;
+            ldebug ("E0 data = %#x\n", d0);
+            dsp_out_data(s, ~d0);
+            break;
+
+        case 0xe2:
+            d0 = dsp_get_data (s);
+            ldebug ("E2 = %#x\n", d0);
+            break;
+
+        case 0xe4:
+            s->test_reg = dsp_get_data (s);
+            break;
+
+        case 0xf9:
+            d0 = dsp_get_data (s);
+            ldebug ("command 0xf9 with %#x\n", d0);
+            switch (d0) {
+            case 0x0e:
+                dsp_out_data (s, 0xff);
+                break;
+
+            case 0x0f:
+                dsp_out_data (s, 0x07);
+                break;
+
+            case 0x37:
+                dsp_out_data (s, 0x38);
+                break;
+
+            default:
+                dsp_out_data (s, 0x00);
+                break;
+            }
+            break;
+
+        default:
+            dolog ("complete: unrecognized command %#x\n", s->cmd);
+            return;
+        }
+    }
+
+    ldebug ("\n");
+    s->cmd = -1;
+    return;
+}
+
+static void reset (SB16State *s)
+{
+    pic_set_irq (s->irq, 0);
+    if (s->dma_auto) {
+        pic_set_irq (s->irq, 1);
+        pic_set_irq (s->irq, 0);
+    }
+
+    s->mixer_regs[0x82] = 0;
+    s->dma_auto = 0;
+    s->in_index = 0;
+    s->out_data_len = 0;
+    s->left_till_irq = 0;
+    s->needed_bytes = 0;
+    s->block_size = -1;
+    s->nzero = 0;
+    s->highspeed = 0;
+    s->v2x6 = 0;
+
+    dsp_out_data(s, 0xaa);
+    speaker (s, 0);
+    control (s, 0);
+}
+
+static IO_WRITE_PROTO (dsp_write)
+{
+    SB16State *s = opaque;
+    int iport;
+
+    iport = nport - s->port;
+
+    ldebug ("write %#x <- %#x\n", nport, val);
+    switch (iport) {
+    case 0x06:
+        switch (val) {
+        case 0x00:
+            if (s->v2x6 == 1) {
+                if (0 && s->highspeed) {
+                    s->highspeed = 0;
+                    pic_set_irq (s->irq, 0);
+                    control (s, 0);
+                }
+                else
+                    reset (s);
+            }
+            s->v2x6 = 0;
+            break;
+
+        case 0x01:
+        case 0x03:              /* FreeBSD kludge */
+            s->v2x6 = 1;
+            break;
+
+        case 0xc6:
+            s->v2x6 = 0;        /* Prince of Persia, csp.sys, diagnose.exe */
+            break;
+
+        case 0xb8:              /* Panic */
+            reset (s);
+            break;
+
+        case 0x39:
+            dsp_out_data (s, 0x38);
+            reset (s);
+            s->v2x6 = 0x39;
+            break;
+
+        default:
+            s->v2x6 = val;
+            break;
+        }
+        break;
+
+    case 0x0c:                  /* write data or command | write status */
+/*         if (s->highspeed) */
+/*             break; */
+
+        if (0 == s->needed_bytes) {
+            command (s, val);
+#if 0
+            if (0 == s->needed_bytes) {
+                log_dsp (s);
+            }
+#endif
+        }
+        else {
+            if (s->in_index == sizeof (s->in2_data)) {
+                dolog ("in data overrun\n");
+            }
+            else {
+                s->in2_data[s->in_index++] = val;
+                if (s->in_index == s->needed_bytes) {
+                    s->needed_bytes = 0;
+                    complete (s);
+#if 0
+                    log_dsp (s);
+#endif
+                }
+            }
+        }
+        break;
+
+    default:
+        ldebug ("(nport=%#x, val=%#x)\n", nport, val);
+        break;
+    }
+}
+
+static IO_READ_PROTO (dsp_read)
+{
+    SB16State *s = opaque;
+    int iport, retval, ack = 0;
+
+    iport = nport - s->port;
+
+    switch (iport) {
+    case 0x06:                  /* reset */
+        retval = 0xff;
+        break;
+
+    case 0x0a:                  /* read data */
+        if (s->out_data_len) {
+            retval = s->out_data[--s->out_data_len];
+            s->last_read_byte = retval;
+        }
+        else {
+            dolog ("empty output buffer\n");
+            retval = s->last_read_byte;
+            /* goto error; */
+        }
+        break;
+
+    case 0x0c:                  /* 0 can write */
+        retval = s->can_write ? 0 : 0x80;
+        break;
+
+    case 0x0d:                  /* timer interrupt clear */
+        /* dolog ("timer interrupt clear\n"); */
+        retval = 0;
+        break;
+
+    case 0x0e:                  /* data available status | irq 8 ack */
+        retval = (!s->out_data_len || s->highspeed) ? 0 : 0x80;
+        if (s->mixer_regs[0x82] & 1) {
+            ack = 1;
+            s->mixer_regs[0x82] &= 1;
+            pic_set_irq (s->irq, 0);
+        }
+        break;
+
+    case 0x0f:                  /* irq 16 ack */
+        retval = 0xff;
+        if (s->mixer_regs[0x82] & 2) {
+            ack = 1;
+            s->mixer_regs[0x82] &= 2;
+            pic_set_irq (s->irq, 0);
+        }
+        break;
+
+    default:
+        goto error;
+    }
+
+    if (!ack)
+        ldebug ("read %#x -> %#x\n", nport, retval);
+
+    return retval;
+
+ error:
+    dolog ("WARNING dsp_read %#x error\n", nport);
+    return 0xff;
+}
+
+static void reset_mixer (SB16State *s)
+{
+    int i;
+
+    memset (s->mixer_regs, 0xff, 0x7f);
+    memset (s->mixer_regs + 0x83, 0xff, sizeof (s->mixer_regs) - 0x83);
+
+    s->mixer_regs[0x02] = 4;    /* master volume 3bits */
+    s->mixer_regs[0x06] = 4;    /* MIDI volume 3bits */
+    s->mixer_regs[0x08] = 0;    /* CD volume 3bits */
+    s->mixer_regs[0x0a] = 0;    /* voice volume 2bits */
+
+    /* d5=input filt, d3=lowpass filt, d1,d2=input source */
+    s->mixer_regs[0x0c] = 0;
+
+    /* d5=output filt, d1=stereo switch */
+    s->mixer_regs[0x0e] = 0;
+
+    /* voice volume L d5,d7, R d1,d3 */
+    s->mixer_regs[0x04] = (4 << 5) | (4 << 1);
+    /* master ... */
+    s->mixer_regs[0x22] = (4 << 5) | (4 << 1);
+    /* MIDI ... */
+    s->mixer_regs[0x26] = (4 << 5) | (4 << 1);
+
+    for (i = 0x30; i < 0x48; i++) {
+        s->mixer_regs[i] = 0x20;
+    }
+}
+
+static IO_WRITE_PROTO(mixer_write_indexb)
+{
+    SB16State *s = opaque;
+    s->mixer_nreg = val;
+}
+
+static IO_WRITE_PROTO(mixer_write_datab)
+{
+    SB16State *s = opaque;
+
+    ldebug ("mixer_write [%#x] <- %#x\n", s->mixer_nreg, val);
+    if (s->mixer_nreg > sizeof (s->mixer_regs))
+        return;
+
+    switch (s->mixer_nreg) {
+    case 0x00:
+        reset_mixer (s);
+        break;
+
+    case 0x80:
+        {
+            int irq = irq_of_magic (val);
+            ldebug ("setting irq to %d (val=%#x)\n", irq, val);
+            if (irq > 0)
+                s->irq = irq;
+        }
+        break;
+
+    case 0x81:
+        {
+            int dma, hdma;
+
+            dma = lsbindex (val & 0xf);
+            hdma = lsbindex (val & 0xf0);
+            dolog ("attempt to set DMA register 8bit %d, 16bit %d (val=%#x)\n",
+                   dma, hdma, val);
+#if 0
+            s->dma = dma;
+            s->hdma = hdma;
+#endif
+        }
+        break;
+
+    case 0x82:
+        dolog ("attempt to write into IRQ status register (val=%#x)\n",
+               val);
+        return;
+
+    default:
+        if (s->mixer_nreg >= 0x80)
+            dolog ("attempt to write mixer[%#x] <- %#x\n", s->mixer_nreg, val);
+        break;
+    }
+
+    s->mixer_regs[s->mixer_nreg] = val;
+}
+
+static IO_WRITE_PROTO(mixer_write_indexw)
+{
+    mixer_write_indexb (opaque, nport, val & 0xff);
+    mixer_write_datab (opaque, nport, (val >> 8) & 0xff);
+}
+
+static IO_READ_PROTO(mixer_read)
+{
+    SB16State *s = opaque;
+#ifndef DEBUG_SB16_MOST
+    if (s->mixer_nreg != 0x82)
+#endif
+    ldebug ("mixer_read[%#x] -> %#x\n",
+            s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
+    return s->mixer_regs[s->mixer_nreg];
+}
+
+static int write_audio (SB16State *s, int nchan, int dma_pos,
+                        int dma_len, int len)
+{
+    int temp, net;
+    uint8_t tmpbuf[4096];
+
+    temp = len;
+    net = 0;
+
+    while (temp) {
+        int left = dma_len - dma_pos;
+        int to_copy, copied;
+
+        to_copy = audio_MIN (temp, left);
+        if (to_copy > sizeof(tmpbuf))
+            to_copy = sizeof(tmpbuf);
+
+        copied = DMA_read_memory (nchan, tmpbuf, dma_pos, to_copy);
+        copied = AUD_write (s->voice, tmpbuf, copied);
+
+        temp -= copied;
+        dma_pos = (dma_pos + copied) % dma_len;
+        net += copied;
+
+        if (!copied)
+            break;
+    }
+
+    return net;
+}
+
+static int SB_read_DMA (void *opaque, int nchan, int dma_pos, int dma_len)
+{
+    SB16State *s = opaque;
+    int free, rfree, till, copy, written, elapsed;
+
+    if (s->left_till_irq < 0) {
+        s->left_till_irq = s->block_size;
+    }
+
+    elapsed = AUD_calc_elapsed (s->voice);
+    free = elapsed;/* AUD_get_free (s->voice); */
+    rfree = free;
+    free = audio_MIN (free, elapsed) & ~s->align;
+
+    if ((free <= 0) || !dma_len) {
+        return dma_pos;
+    }
+
+    copy = free;
+    till = s->left_till_irq;
+
+#ifdef DEBUG_SB16_MOST
+    dolog ("pos:%06d free:%d,%d till:%d len:%d\n",
+           dma_pos, free, AUD_get_free (s->voice), till, dma_len);
+#endif
+
+    if (till <= copy) {
+        if (0 == s->dma_auto) {
+            copy = till;
+        }
+    }
+
+    written = write_audio (s, nchan, dma_pos, dma_len, copy);
+    dma_pos = (dma_pos + written) % dma_len;
+    s->left_till_irq -= written;
+
+    if (s->left_till_irq <= 0) {
+        s->mixer_regs[0x82] |= (nchan & 4) ? 2 : 1;
+        pic_set_irq (s->irq, 1);
+        if (0 == s->dma_auto) {
+            control (s, 0);
+            speaker (s, 0);
+        }
+    }
+
+#ifdef DEBUG_SB16_MOST
+    ldebug ("pos %5d free %5d size %5d till % 5d copy %5d written %5d size %5d\n",
+            dma_pos, free, dma_len, s->left_till_irq, copy, written,
+            s->block_size);
+#endif
+
+    while (s->left_till_irq <= 0) {
+        s->left_till_irq = s->block_size + s->left_till_irq;
+    }
+
+    AUD_adjust (s->voice, written);
+    return dma_pos;
+}
+
+void SB_timer (void *opaque)
+{
+    SB16State *s = opaque;
+    AUD_run ();
+    qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + 1);
+}
+
+static void SB_save (QEMUFile *f, void *opaque)
+{
+    SB16State *s = opaque;
+
+    qemu_put_be32s (f, &s->irq);
+    qemu_put_be32s (f, &s->dma);
+    qemu_put_be32s (f, &s->hdma);
+    qemu_put_be32s (f, &s->port);
+    qemu_put_be32s (f, &s->ver);
+    qemu_put_be32s (f, &s->in_index);
+    qemu_put_be32s (f, &s->out_data_len);
+    qemu_put_be32s (f, &s->fmt_stereo);
+    qemu_put_be32s (f, &s->fmt_signed);
+    qemu_put_be32s (f, &s->fmt_bits);
+    qemu_put_be32s (f, &s->fmt);
+    qemu_put_be32s (f, &s->dma_auto);
+    qemu_put_be32s (f, &s->block_size);
+    qemu_put_be32s (f, &s->fifo);
+    qemu_put_be32s (f, &s->freq);
+    qemu_put_be32s (f, &s->time_const);
+    qemu_put_be32s (f, &s->speaker);
+    qemu_put_be32s (f, &s->needed_bytes);
+    qemu_put_be32s (f, &s->cmd);
+    qemu_put_be32s (f, &s->use_hdma);
+    qemu_put_be32s (f, &s->highspeed);
+    qemu_put_be32s (f, &s->can_write);
+    qemu_put_be32s (f, &s->v2x6);
+
+    qemu_put_8s (f, &s->csp_param);
+    qemu_put_8s (f, &s->csp_value);
+    qemu_put_8s (f, &s->csp_mode);
+    qemu_put_8s (f, &s->csp_param);
+    qemu_put_buffer (f, s->csp_regs, 256);
+    qemu_put_8s (f, &s->csp_index);
+    qemu_put_buffer (f, s->csp_reg83, 4);
+    qemu_put_be32s (f, &s->csp_reg83r);
+    qemu_put_be32s (f, &s->csp_reg83w);
+
+    qemu_put_buffer (f, s->in2_data, sizeof (s->in2_data));
+    qemu_put_buffer (f, s->out_data, sizeof (s->out_data));
+    qemu_put_8s (f, &s->test_reg);
+    qemu_put_8s (f, &s->last_read_byte);
+
+    qemu_put_be32s (f, &s->nzero);
+    qemu_put_be32s (f, &s->left_till_irq);
+    qemu_put_be32s (f, &s->dma_running);
+    qemu_put_be32s (f, &s->bytes_per_second);
+    qemu_put_be32s (f, &s->align);
+
+    qemu_put_be32s (f, &s->mixer_nreg);
+    qemu_put_buffer (f, s->mixer_regs, 256);
+}
+
+static int SB_load (QEMUFile *f, void *opaque, int version_id)
+{
+    SB16State *s = opaque;
+
+    if (version_id != 1)
+        return -EINVAL;
+
+    qemu_get_be32s (f, &s->irq);
+    qemu_get_be32s (f, &s->dma);
+    qemu_get_be32s (f, &s->hdma);
+    qemu_get_be32s (f, &s->port);
+    qemu_get_be32s (f, &s->ver);
+    qemu_get_be32s (f, &s->in_index);
+    qemu_get_be32s (f, &s->out_data_len);
+    qemu_get_be32s (f, &s->fmt_stereo);
+    qemu_get_be32s (f, &s->fmt_signed);
+    qemu_get_be32s (f, &s->fmt_bits);
+    qemu_get_be32s (f, &s->fmt);
+    qemu_get_be32s (f, &s->dma_auto);
+    qemu_get_be32s (f, &s->block_size);
+    qemu_get_be32s (f, &s->fifo);
+    qemu_get_be32s (f, &s->freq);
+    qemu_get_be32s (f, &s->time_const);
+    qemu_get_be32s (f, &s->speaker);
+    qemu_get_be32s (f, &s->needed_bytes);
+    qemu_get_be32s (f, &s->cmd);
+    qemu_get_be32s (f, &s->use_hdma);
+    qemu_get_be32s (f, &s->highspeed);
+    qemu_get_be32s (f, &s->can_write);
+    qemu_get_be32s (f, &s->v2x6);
+
+    qemu_get_8s (f, &s->csp_param);
+    qemu_get_8s (f, &s->csp_value);
+    qemu_get_8s (f, &s->csp_mode);
+    qemu_get_8s (f, &s->csp_param);
+    qemu_get_buffer (f, s->csp_regs, 256);
+    qemu_get_8s (f, &s->csp_index);
+    qemu_get_buffer (f, s->csp_reg83, 4);
+    qemu_get_be32s (f, &s->csp_reg83r);
+    qemu_get_be32s (f, &s->csp_reg83w);
+
+    qemu_get_buffer (f, s->in2_data, sizeof (s->in2_data));
+    qemu_get_buffer (f, s->out_data, sizeof (s->out_data));
+    qemu_get_8s (f, &s->test_reg);
+    qemu_get_8s (f, &s->last_read_byte);
+
+    qemu_get_be32s (f, &s->nzero);
+    qemu_get_be32s (f, &s->left_till_irq);
+    qemu_get_be32s (f, &s->dma_running);
+    qemu_get_be32s (f, &s->bytes_per_second);
+    qemu_get_be32s (f, &s->align);
+
+    qemu_get_be32s (f, &s->mixer_nreg);
+    qemu_get_buffer (f, s->mixer_regs, 256);
+
+    if (s->voice) {
+        AUD_close (s->voice);
+        s->voice = NULL;
+    }
+
+    if (s->dma_running) {
+        if (s->freq)
+            s->voice = AUD_open (s->voice, "sb16", s->freq,
+                                 1 << s->fmt_stereo, s->fmt);
+
+        control (s, 1);
+        speaker (s, s->speaker);
+    }
+    return 0;
+}
+
+void SB16_init (void)
+{
+    SB16State *s = &dsp;
+    int i;
+    static const uint8_t dsp_write_ports[] = {0x6, 0xc};
+    static const uint8_t dsp_read_ports[] = {0x6, 0xa, 0xc, 0xd, 0xe, 0xf};
+
+    s->ts = qemu_new_timer (vm_clock, SB_timer, s);
+    if (!s->ts)
+        return;
+
+    s->irq = conf.irq;
+    s->dma = conf.dma;
+    s->hdma = conf.hdma;
+    s->port = conf.port;
+    s->ver = conf.ver_lo | (conf.ver_hi << 8);
+
+    s->mixer_regs[0x80] = magic_of_irq (s->irq);
+    s->mixer_regs[0x81] = (1 << s->dma) | (1 << s->hdma);
+    s->mixer_regs[0x82] = 2 << 5;
+
+    s->csp_regs[5] = 1;
+    s->csp_regs[9] = 0xf8;
+
+    reset_mixer (s);
+    s->aux_ts = qemu_new_timer (vm_clock, aux_timer, s);
+    if (!s->aux_ts)
+        return;
+
+    for (i = 0; i < LENOFA (dsp_write_ports); i++) {
+        register_ioport_write (s->port + dsp_write_ports[i], 1, 1, dsp_write, s);
+    }
+
+    for (i = 0; i < LENOFA (dsp_read_ports); i++) {
+        register_ioport_read (s->port + dsp_read_ports[i], 1, 1, dsp_read, s);
+    }
+
+    register_ioport_write (s->port + 0x4, 1, 1, mixer_write_indexb, s);
+    register_ioport_write (s->port + 0x4, 1, 2, mixer_write_indexw, s);
+    register_ioport_read (s->port + 0x5, 1, 1, mixer_read, s);
+    register_ioport_write (s->port + 0x5, 1, 1, mixer_write_datab, s);
+
+    DMA_register_channel (s->hdma, SB_read_DMA, s);
+    DMA_register_channel (s->dma, SB_read_DMA, s);
+    s->can_write = 1;
+
+    qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + 1);
+    register_savevm ("sb16", 0, 1, SB_save, SB_load, s);
+}
diff --git a/tools/ioemu/hw/sched.c b/tools/ioemu/hw/sched.c
new file mode 100644 (file)
index 0000000..2ab966d
--- /dev/null
@@ -0,0 +1,268 @@
+/*
+ * QEMU interrupt controller emulation
+ * 
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+//#define DEBUG_IRQ_COUNT
+
+/* These registers are used for sending/receiving irqs from/to
+ * different cpu's.
+ */
+struct sun4m_intreg_percpu {
+       unsigned int tbt;        /* Intrs pending for this cpu, by PIL. */
+       /* These next two registers are WRITE-ONLY and are only
+        * "on bit" sensitive, "off bits" written have NO affect.
+        */
+       unsigned int clear;  /* Clear this cpus irqs here. */
+       unsigned int set;    /* Set this cpus irqs here. */
+};
+/*
+ * djhr
+ * Actually the clear and set fields in this struct are misleading..
+ * according to the SLAVIO manual (and the same applies for the SEC)
+ * the clear field clears bits in the mask which will ENABLE that IRQ
+ * the set field sets bits in the mask to DISABLE the IRQ.
+ *
+ * Also the undirected_xx address in the SLAVIO is defined as
+ * RESERVED and write only..
+ *
+ * DAVEM_NOTE: The SLAVIO only specifies behavior on uniprocessor
+ *             sun4m machines, for MP the layout makes more sense.
+ */
+struct sun4m_intreg_master {
+       unsigned int tbt;        /* IRQ's that are pending, see sun4m masks. */
+       unsigned int irqs;       /* Master IRQ bits. */
+
+       /* Again, like the above, two these registers are WRITE-ONLY. */
+       unsigned int clear;      /* Clear master IRQ's by setting bits here. */
+       unsigned int set;        /* Set master IRQ's by setting bits here. */
+
+       /* This register is both READ and WRITE. */
+       unsigned int undirected_target;  /* Which cpu gets undirected irqs. */
+};
+
+#define SUN4M_INT_ENABLE        0x80000000
+#define SUN4M_INT_E14           0x00000080
+#define SUN4M_INT_E10           0x00080000
+
+#define SUN4M_HARD_INT(x)       (0x000000001 << (x))
+#define SUN4M_SOFT_INT(x)       (0x000010000 << (x))
+
+#define SUN4M_INT_MASKALL       0x80000000        /* mask all interrupts */
+#define SUN4M_INT_MODULE_ERR    0x40000000        /* module error */
+#define SUN4M_INT_M2S_WRITE     0x20000000        /* write buffer error */
+#define SUN4M_INT_ECC           0x10000000        /* ecc memory error */
+#define SUN4M_INT_FLOPPY        0x00400000        /* floppy disk */
+#define SUN4M_INT_MODULE        0x00200000        /* module interrupt */
+#define SUN4M_INT_VIDEO         0x00100000        /* onboard video */
+#define SUN4M_INT_REALTIME      0x00080000        /* system timer */
+#define SUN4M_INT_SCSI          0x00040000        /* onboard scsi */
+#define SUN4M_INT_AUDIO         0x00020000        /* audio/isdn */
+#define SUN4M_INT_ETHERNET      0x00010000        /* onboard ethernet */
+#define SUN4M_INT_SERIAL        0x00008000        /* serial ports */
+#define SUN4M_INT_SBUSBITS      0x00003F80        /* sbus int bits */
+
+#define SUN4M_INT_SBUS(x)       (1 << (x+7))
+#define SUN4M_INT_VME(x)        (1 << (x))
+
+typedef struct SCHEDState {
+    uint32_t addr, addrg;
+    uint32_t intreg_pending;
+    uint32_t intreg_enabled;
+    uint32_t intregm_pending;
+    uint32_t intregm_enabled;
+} SCHEDState;
+
+static SCHEDState *ps;
+
+#ifdef DEBUG_IRQ_COUNT
+static uint64_t irq_count[32];
+#endif
+
+static uint32_t intreg_mem_readl(void *opaque, target_phys_addr_t addr)
+{
+    SCHEDState *s = opaque;
+    uint32_t saddr;
+
+    saddr = (addr - s->addr) >> 2;
+    switch (saddr) {
+    case 0:
+       return s->intreg_pending;
+       break;
+    default:
+       break;
+    }
+    return 0;
+}
+
+static void intreg_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
+{
+    SCHEDState *s = opaque;
+    uint32_t saddr;
+
+    saddr = (addr - s->addr) >> 2;
+    switch (saddr) {
+    case 0:
+       s->intreg_pending = val;
+       break;
+    case 1: // clear
+       s->intreg_enabled &= ~val;
+       break;
+    case 2: // set
+       s->intreg_enabled |= val;
+       break;
+    default:
+       break;
+    }
+}
+
+static CPUReadMemoryFunc *intreg_mem_read[3] = {
+    intreg_mem_readl,
+    intreg_mem_readl,
+    intreg_mem_readl,
+};
+
+static CPUWriteMemoryFunc *intreg_mem_write[3] = {
+    intreg_mem_writel,
+    intreg_mem_writel,
+    intreg_mem_writel,
+};
+
+static uint32_t intregm_mem_readl(void *opaque, target_phys_addr_t addr)
+{
+    SCHEDState *s = opaque;
+    uint32_t saddr;
+
+    saddr = (addr - s->addrg) >> 2;
+    switch (saddr) {
+    case 0:
+       return s->intregm_pending;
+       break;
+    case 1:
+       return s->intregm_enabled;
+       break;
+    default:
+       break;
+    }
+    return 0;
+}
+
+static void intregm_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
+{
+    SCHEDState *s = opaque;
+    uint32_t saddr;
+
+    saddr = (addr - s->addrg) >> 2;
+    switch (saddr) {
+    case 0:
+       s->intregm_pending = val;
+       break;
+    case 1:
+       s->intregm_enabled = val;
+       break;
+    case 2: // clear
+       s->intregm_enabled &= ~val;
+       break;
+    case 3: // set
+       s->intregm_enabled |= val;
+       break;
+    default:
+       break;
+    }
+}
+
+static CPUReadMemoryFunc *intregm_mem_read[3] = {
+    intregm_mem_readl,
+    intregm_mem_readl,
+    intregm_mem_readl,
+};
+
+static CPUWriteMemoryFunc *intregm_mem_write[3] = {
+    intregm_mem_writel,
+    intregm_mem_writel,
+    intregm_mem_writel,
+};
+
+void pic_info(void)
+{
+    term_printf("per-cpu: pending 0x%08x, enabled 0x%08x\n", ps->intreg_pending, ps->intreg_enabled);
+    term_printf("master: pending 0x%08x, enabled 0x%08x\n", ps->intregm_pending, ps->intregm_enabled);
+}
+
+void irq_info(void)
+{
+#ifndef DEBUG_IRQ_COUNT
+    term_printf("irq statistic code not compiled.\n");
+#else
+    int i;
+    int64_t count;
+
+    term_printf("IRQ statistics:\n");
+    for (i = 0; i < 32; i++) {
+        count = irq_count[i];
+        if (count > 0)
+            term_printf("%2d: %lld\n", i, count);
+    }
+#endif
+}
+
+static const unsigned int intr_to_mask[16] = {
+       0,      0,      0,      0,      0,      0, SUN4M_INT_ETHERNET,  0,
+       0,      0,      0,      0,      0,      0,      0,      0,
+};
+
+void pic_set_irq(int irq, int level)
+{
+    if (irq < 16) {
+       unsigned int mask = intr_to_mask[irq];
+       ps->intreg_pending |= 1 << irq;
+       if (ps->intregm_enabled & mask) {
+           cpu_single_env->interrupt_index = irq;
+           cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HARD);
+       }
+    }
+#ifdef DEBUG_IRQ_COUNT
+    if (level == 1)
+       irq_count[irq]++;
+#endif
+}
+
+void sched_init(uint32_t addr, uint32_t addrg)
+{
+    int intreg_io_memory, intregm_io_memory;
+    SCHEDState *s;
+
+    s = qemu_mallocz(sizeof(SCHEDState));
+    if (!s)
+        return;
+    s->addr = addr;
+    s->addrg = addrg;
+
+    intreg_io_memory = cpu_register_io_memory(0, intreg_mem_read, intreg_mem_write, s);
+    cpu_register_physical_memory(addr, 3, intreg_io_memory);
+
+    intregm_io_memory = cpu_register_io_memory(0, intregm_mem_read, intregm_mem_write, s);
+    cpu_register_physical_memory(addrg, 5, intregm_io_memory);
+
+    ps = s;
+}
+
diff --git a/tools/ioemu/hw/serial.c b/tools/ioemu/hw/serial.c
new file mode 100644 (file)
index 0000000..3fe482c
--- /dev/null
@@ -0,0 +1,279 @@
+/*
+ * QEMU 16450 UART emulation
+ * 
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+
+//#define DEBUG_SERIAL
+
+#define UART_LCR_DLAB  0x80    /* Divisor latch access bit */
+
+#define UART_IER_MSI   0x08    /* Enable Modem status interrupt */
+#define UART_IER_RLSI  0x04    /* Enable receiver line status interrupt */
+#define UART_IER_THRI  0x02    /* Enable Transmitter holding register int. */
+#define UART_IER_RDI   0x01    /* Enable receiver data interrupt */
+
+#define UART_IIR_NO_INT        0x01    /* No interrupts pending */
+#define UART_IIR_ID    0x06    /* Mask for the interrupt ID */
+
+#define UART_IIR_MSI   0x00    /* Modem status interrupt */
+#define UART_IIR_THRI  0x02    /* Transmitter holding register empty */
+#define UART_IIR_RDI   0x04    /* Receiver data interrupt */
+#define UART_IIR_RLSI  0x06    /* Receiver line status interrupt */
+
+/*
+ * These are the definitions for the Modem Control Register
+ */
+#define UART_MCR_LOOP  0x10    /* Enable loopback test mode */
+#define UART_MCR_OUT2  0x08    /* Out2 complement */
+#define UART_MCR_OUT1  0x04    /* Out1 complement */
+#define UART_MCR_RTS   0x02    /* RTS complement */
+#define UART_MCR_DTR   0x01    /* DTR complement */
+
+/*
+ * These are the definitions for the Modem Status Register
+ */
+#define UART_MSR_DCD   0x80    /* Data Carrier Detect */
+#define UART_MSR_RI    0x40    /* Ring Indicator */
+#define UART_MSR_DSR   0x20    /* Data Set Ready */
+#define UART_MSR_CTS   0x10    /* Clear to Send */
+#define UART_MSR_DDCD  0x08    /* Delta DCD */
+#define UART_MSR_TERI  0x04    /* Trailing edge ring indicator */
+#define UART_MSR_DDSR  0x02    /* Delta DSR */
+#define UART_MSR_DCTS  0x01    /* Delta CTS */
+#define UART_MSR_ANY_DELTA 0x0F        /* Any of the delta bits! */
+
+#define UART_LSR_TEMT  0x40    /* Transmitter empty */
+#define UART_LSR_THRE  0x20    /* Transmit-hold-register empty */
+#define UART_LSR_BI    0x10    /* Break interrupt indicator */
+#define UART_LSR_FE    0x08    /* Frame error indicator */
+#define UART_LSR_PE    0x04    /* Parity error indicator */
+#define UART_LSR_OE    0x02    /* Overrun error indicator */
+#define UART_LSR_DR    0x01    /* Receiver data ready */
+
+struct SerialState {
+    uint8_t divider;
+    uint8_t rbr; /* receive register */
+    uint8_t ier;
+    uint8_t iir; /* read only */
+    uint8_t lcr;
+    uint8_t mcr;
+    uint8_t lsr; /* read only */
+    uint8_t msr;
+    uint8_t scr;
+    /* NOTE: this hidden state is necessary for tx irq generation as
+       it can be reset while reading iir */
+    int thr_ipending;
+    int irq;
+    CharDriverState *chr;
+};
+
+static void serial_update_irq(SerialState *s)
+{
+    if ((s->lsr & UART_LSR_DR) && (s->ier & UART_IER_RDI)) {
+        s->iir = UART_IIR_RDI;
+    } else if (s->thr_ipending && (s->ier & UART_IER_THRI)) {
+        s->iir = UART_IIR_THRI;
+    } else {
+        s->iir = UART_IIR_NO_INT;
+    }
+    if (s->iir != UART_IIR_NO_INT) {
+        pic_set_irq(s->irq, 1);
+    } else {
+        pic_set_irq(s->irq, 0);
+    }
+}
+
+static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+{
+    SerialState *s = opaque;
+    unsigned char ch;
+    
+    addr &= 7;
+#ifdef DEBUG_SERIAL
+    printf("serial: write addr=0x%02x val=0x%02x\n", addr, val);
+#endif
+    switch(addr) {
+    default:
+    case 0:
+        if (s->lcr & UART_LCR_DLAB) {
+            s->divider = (s->divider & 0xff00) | val;
+        } else {
+            s->thr_ipending = 0;
+            s->lsr &= ~UART_LSR_THRE;
+            serial_update_irq(s);
+            ch = val;
+            qemu_chr_write(s->chr, &ch, 1);
+            s->thr_ipending = 1;
+            s->lsr |= UART_LSR_THRE;
+            s->lsr |= UART_LSR_TEMT;
+            serial_update_irq(s);
+        }
+        break;
+    case 1:
+        if (s->lcr & UART_LCR_DLAB) {
+            s->divider = (s->divider & 0x00ff) | (val << 8);
+        } else {
+            s->ier = val & 0x0f;
+            if (s->lsr & UART_LSR_THRE) {
+                s->thr_ipending = 1;
+            }
+            serial_update_irq(s);
+        }
+        break;
+    case 2:
+        break;
+    case 3:
+        s->lcr = val;
+        break;
+    case 4:
+        s->mcr = val & 0x1f;
+        break;
+    case 5:
+        break;
+    case 6:
+        s->msr = val;
+        break;
+    case 7:
+        s->scr = val;
+        break;
+    }
+}
+
+static uint32_t serial_ioport_read(void *opaque, uint32_t addr)
+{
+    SerialState *s = opaque;
+    uint32_t ret;
+
+    addr &= 7;
+    switch(addr) {
+    default:
+    case 0:
+        if (s->lcr & UART_LCR_DLAB) {
+            ret = s->divider & 0xff; 
+        } else {
+            ret = s->rbr;
+            s->lsr &= ~(UART_LSR_DR | UART_LSR_BI);
+            serial_update_irq(s);
+        }
+        break;
+    case 1:
+        if (s->lcr & UART_LCR_DLAB) {
+            ret = (s->divider >> 8) & 0xff;
+        } else {
+            ret = s->ier;
+        }
+        break;
+    case 2:
+        ret = s->iir;
+        /* reset THR pending bit */
+        if ((ret & 0x7) == UART_IIR_THRI)
+            s->thr_ipending = 0;
+        serial_update_irq(s);
+        break;
+    case 3:
+        ret = s->lcr;
+        break;
+    case 4:
+        ret = s->mcr;
+        break;
+    case 5:
+        ret = s->lsr;
+        break;
+    case 6:
+        if (s->mcr & UART_MCR_LOOP) {
+            /* in loopback, the modem output pins are connected to the
+               inputs */
+            ret = (s->mcr & 0x0c) << 4;
+            ret |= (s->mcr & 0x02) << 3;
+            ret |= (s->mcr & 0x01) << 5;
+        } else {
+            ret = s->msr;
+        }
+        break;
+    case 7:
+        ret = s->scr;
+        break;
+    }
+#ifdef DEBUG_SERIAL
+    printf("serial: read addr=0x%02x val=0x%02x\n", addr, ret);
+#endif
+    return ret;
+}
+
+static int serial_can_receive(SerialState *s)
+{
+    return !(s->lsr & UART_LSR_DR);
+}
+
+static void serial_receive_byte(SerialState *s, int ch)
+{
+    s->rbr = ch;
+    s->lsr |= UART_LSR_DR;
+    serial_update_irq(s);
+}
+
+static void serial_receive_break(SerialState *s)
+{
+    s->rbr = 0;
+    s->lsr |= UART_LSR_BI | UART_LSR_DR;
+    serial_update_irq(s);
+}
+
+static int serial_can_receive1(void *opaque)
+{
+    SerialState *s = opaque;
+    return serial_can_receive(s);
+}
+
+static void serial_receive1(void *opaque, const uint8_t *buf, int size)
+{
+    SerialState *s = opaque;
+    serial_receive_byte(s, buf[0]);
+}
+
+static void serial_event(void *opaque, int event)
+{
+    SerialState *s = opaque;
+    if (event == CHR_EVENT_BREAK)
+        serial_receive_break(s);
+}
+
+/* If fd is zero, it means that the serial device uses the console */
+SerialState *serial_init(int base, int irq, CharDriverState *chr)
+{
+    SerialState *s;
+
+    s = qemu_mallocz(sizeof(SerialState));
+    if (!s)
+        return NULL;
+    s->irq = irq;
+    s->lsr = UART_LSR_TEMT | UART_LSR_THRE;
+    s->iir = UART_IIR_NO_INT;
+
+    register_ioport_write(base, 8, 1, serial_ioport_write, s);
+    register_ioport_read(base, 8, 1, serial_ioport_read, s);
+    s->chr = chr;
+    qemu_chr_add_read_handler(chr, serial_can_receive1, serial_receive1, s);
+    qemu_chr_add_event_handler(chr, serial_event);
+    return s;
+}
diff --git a/tools/ioemu/hw/sun4m.c b/tools/ioemu/hw/sun4m.c
new file mode 100644 (file)
index 0000000..80305e0
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * QEMU Sun4m System Emulator
+ * 
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+#include "m48t08.h"
+
+#define KERNEL_LOAD_ADDR     0x00004000
+#define MMU_CONTEXT_TBL      0x00003000
+#define MMU_L1PTP            (MMU_CONTEXT_TBL + 0x0400)
+#define MMU_L2PTP            (MMU_CONTEXT_TBL + 0x0800)
+#define PROM_ADDR           0xffd04000
+#define PROM_FILENAMEB      "proll.bin"
+#define PROM_FILENAMEE      "proll.elf"
+#define PROLL_MAGIC_ADDR 0x20000000
+#define PHYS_JJ_EEPROM 0x71200000      /* [2000] MK48T08 */
+#define PHYS_JJ_IDPROM_OFF     0x1FD8
+#define PHYS_JJ_EEPROM_SIZE    0x2000
+#define PHYS_JJ_IOMMU  0x10000000      /* First page of sun4m IOMMU */
+#define PHYS_JJ_TCX_FB 0x50800000      /* Start address, frame buffer body */
+#define PHYS_JJ_TCX_0E 0x5E000000      /* Top address, one byte used. */
+#define PHYS_JJ_IOMMU  0x10000000      /* First page of sun4m IOMMU */
+#define PHYS_JJ_LEDMA   0x78400010      /* ledma, off by 10 from unused SCSI */
+#define PHYS_JJ_LE      0x78C00000      /* LANCE, typical sun4m */
+#define PHYS_JJ_LE_IRQ  6
+#define PHYS_JJ_CLOCK  0x71D00000
+#define PHYS_JJ_CLOCK_IRQ  10
+#define PHYS_JJ_CLOCK1 0x71D10000
+#define PHYS_JJ_CLOCK1_IRQ  14
+#define PHYS_JJ_INTR0  0x71E00000      /* CPU0 interrupt control registers */
+#define PHYS_JJ_INTR_G 0x71E10000      /* Master interrupt control registers */
+
+/* TSC handling */
+
+uint64_t cpu_get_tsc()
+{
+    return qemu_get_clock(vm_clock);
+}
+
+void DMA_run() {}
+void SB16_run() {}
+int serial_can_receive(SerialState *s) { return 0; }
+void serial_receive_byte(SerialState *s, int ch) {}
+void serial_receive_break(SerialState *s) {}
+
+static m48t08_t *nvram;
+
+/* Sun4m hardware initialisation */
+void sun4m_init(int ram_size, int vga_ram_size, int boot_device,
+             DisplayState *ds, const char **fd_filename, int snapshot,
+             const char *kernel_filename, const char *kernel_cmdline,
+             const char *initrd_filename)
+{
+    char buf[1024];
+    int ret, linux_boot;
+    unsigned long bios_offset;
+
+    linux_boot = (kernel_filename != NULL);
+
+    /* allocate RAM */
+    cpu_register_physical_memory(0, ram_size, 0);
+    bios_offset = ram_size;
+
+    iommu_init(PHYS_JJ_IOMMU);
+    sched_init(PHYS_JJ_INTR0, PHYS_JJ_INTR_G);
+    tcx_init(ds, PHYS_JJ_TCX_FB);
+    lance_init(&nd_table[0], PHYS_JJ_LE_IRQ, PHYS_JJ_LE, PHYS_JJ_LEDMA);
+    nvram = m48t08_init(PHYS_JJ_EEPROM, PHYS_JJ_EEPROM_SIZE, &nd_table[0].macaddr);
+    timer_init(PHYS_JJ_CLOCK, PHYS_JJ_CLOCK_IRQ);
+    timer_init(PHYS_JJ_CLOCK1, PHYS_JJ_CLOCK1_IRQ);
+    magic_init(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR, PROLL_MAGIC_ADDR);
+
+    /* We load Proll as the kernel and start it. It will issue a magic
+       IO to load the real kernel */
+    if (linux_boot) {
+       snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAMEB);
+        ret = load_kernel(buf, 
+                      phys_ram_base + KERNEL_LOAD_ADDR);
+        if (ret < 0) {
+            fprintf(stderr, "qemu: could not load kernel '%s'\n", 
+                    buf);
+            exit(1);
+        }
+    }
+    /* Setup a MMU entry for entire address space */
+    stl_raw(phys_ram_base + MMU_CONTEXT_TBL, (MMU_L1PTP >> 4) | 1);
+    stl_raw(phys_ram_base + MMU_L1PTP, (MMU_L2PTP >> 4) | 1);
+    stl_raw(phys_ram_base + MMU_L1PTP + (0x01 << 2), (MMU_L2PTP >> 4) | 1); // 01.. == 00..
+    stl_raw(phys_ram_base + MMU_L1PTP + (0xff << 2), (MMU_L2PTP >> 4) | 1); // ff.. == 00..
+    stl_raw(phys_ram_base + MMU_L1PTP + (0xf0 << 2), (MMU_L2PTP >> 4) | 1); // f0.. == 00..
+    /* 3 = U:RWX S:RWX */
+    stl_raw(phys_ram_base + MMU_L2PTP, (3 << PTE_ACCESS_SHIFT) | 2);
+    stl_raw(phys_ram_base + MMU_L2PTP, ((0x01 << PTE_PPN_SHIFT) >> 4 ) | (3 << PTE_ACCESS_SHIFT) | 2);
+}
diff --git a/tools/ioemu/hw/tcx.c b/tools/ioemu/hw/tcx.c
new file mode 100644 (file)
index 0000000..7f97994
--- /dev/null
@@ -0,0 +1,207 @@
+/*
+ * QEMU Sun4m System Emulator
+ * 
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+
+#define MAXX 1024
+#define MAXY 768
+#define XSZ (8*80)
+#define YSZ (24*11)
+#define XOFF (MAXX-XSZ)
+#define YOFF (MAXY-YSZ)
+
+typedef struct TCXState {
+    uint32_t addr;
+    DisplayState *ds;
+    uint8_t *vram;
+} TCXState;
+
+static TCXState *ts;
+
+void vga_update_display()
+{
+    dpy_update(ts->ds, 0, 0, XSZ, YSZ);
+}
+
+void vga_invalidate_display() {}
+
+static uint32_t tcx_mem_readb(void *opaque, target_phys_addr_t addr)
+{
+    TCXState *s = opaque;
+    uint32_t saddr;
+    unsigned int x, y;
+
+    saddr = addr - s->addr - YOFF*MAXX - XOFF;
+    y = saddr / MAXX;
+    x = saddr - y * MAXX;
+    if (x < XSZ && y < YSZ) {
+       return s->vram[y * XSZ + x];
+    }
+    return 0;
+}
+
+static uint32_t tcx_mem_readw(void *opaque, target_phys_addr_t addr)
+{
+    uint32_t v;
+#ifdef TARGET_WORDS_BIGENDIAN
+    v = tcx_mem_readb(opaque, addr) << 8;
+    v |= tcx_mem_readb(opaque, addr + 1);
+#else
+    v = tcx_mem_readb(opaque, addr);
+    v |= tcx_mem_readb(opaque, addr + 1) << 8;
+#endif
+    return v;
+}
+
+static uint32_t tcx_mem_readl(void *opaque, target_phys_addr_t addr)
+{
+    uint32_t v;
+#ifdef TARGET_WORDS_BIGENDIAN
+    v = tcx_mem_readb(opaque, addr) << 24;
+    v |= tcx_mem_readb(opaque, addr + 1) << 16;
+    v |= tcx_mem_readb(opaque, addr + 2) << 8;
+    v |= tcx_mem_readb(opaque, addr + 3);
+#else
+    v = tcx_mem_readb(opaque, addr);
+    v |= tcx_mem_readb(opaque, addr + 1) << 8;
+    v |= tcx_mem_readb(opaque, addr + 2) << 16;
+    v |= tcx_mem_readb(opaque, addr + 3) << 24;
+#endif
+    return v;
+}
+
+static void tcx_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
+{
+    TCXState *s = opaque;
+    uint32_t saddr;
+    unsigned int x, y;
+    char *sptr;
+
+    saddr = addr - s->addr - YOFF*MAXX - XOFF;
+    y = saddr / MAXX;
+    x = saddr - y * MAXX;
+    if (x < XSZ && y < YSZ) {
+       sptr =  s->ds->data;
+       if (sptr) {
+           if (s->ds->depth == 24 || s->ds->depth == 32) {
+               /* XXX need to do CLUT translation */
+               sptr[y * s->ds->linesize + x*4] = val & 0xff;
+               sptr[y * s->ds->linesize + x*4+1] = val & 0xff;
+               sptr[y * s->ds->linesize + x*4+2] = val & 0xff;
+           }
+           else if (s->ds->depth == 8) {
+               sptr[y * s->ds->linesize + x] = val & 0xff;
+           }
+       }
+       cpu_physical_memory_set_dirty(addr);
+       s->vram[y * XSZ + x] = val & 0xff;
+    }
+}
+
+static void tcx_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
+{
+#ifdef TARGET_WORDS_BIGENDIAN
+    tcx_mem_writeb(opaque, addr, (val >> 8) & 0xff);
+    tcx_mem_writeb(opaque, addr + 1, val & 0xff);
+#else
+    tcx_mem_writeb(opaque, addr, val & 0xff);
+    tcx_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
+#endif
+}
+
+static void tcx_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
+{
+#ifdef TARGET_WORDS_BIGENDIAN
+    tcx_mem_writeb(opaque, addr, (val >> 24) & 0xff);
+    tcx_mem_writeb(opaque, addr + 1, (val >> 16) & 0xff);
+    tcx_mem_writeb(opaque, addr + 2, (val >> 8) & 0xff);
+    tcx_mem_writeb(opaque, addr + 3, val & 0xff);
+#else
+    tcx_mem_writeb(opaque, addr, val & 0xff);
+    tcx_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
+    tcx_mem_writeb(opaque, addr + 2, (val >> 16) & 0xff);
+    tcx_mem_writeb(opaque, addr + 3, (val >> 24) & 0xff);
+#endif
+}
+
+static CPUReadMemoryFunc *tcx_mem_read[3] = {
+    tcx_mem_readb,
+    tcx_mem_readw,
+    tcx_mem_readl,
+};
+
+static CPUWriteMemoryFunc *tcx_mem_write[3] = {
+    tcx_mem_writeb,
+    tcx_mem_writew,
+    tcx_mem_writel,
+};
+
+void tcx_init(DisplayState *ds, uint32_t addr)
+{
+    TCXState *s;
+    int tcx_io_memory;
+
+    s = qemu_mallocz(sizeof(TCXState));
+    if (!s)
+        return;
+    s->ds = ds;
+    s->addr = addr;
+    ts = s;
+    tcx_io_memory = cpu_register_io_memory(0, tcx_mem_read, tcx_mem_write, s);
+    cpu_register_physical_memory(addr, 0x100000, 
+                                 tcx_io_memory);
+    s->vram = qemu_mallocz(XSZ*YSZ);
+    dpy_resize(s->ds, XSZ, YSZ);
+}
+
+void vga_screen_dump(const char *filename)
+{
+    TCXState *s = ts;
+    FILE *f;
+    uint8_t *d, *d1;
+    unsigned int v;
+    int y, x;
+
+    f = fopen(filename, "wb");
+    if (!f)
+        return -1;
+    fprintf(f, "P6\n%d %d\n%d\n",
+            XSZ, YSZ, 255);
+    d1 = s->vram;
+    for(y = 0; y < YSZ; y++) {
+        d = d1;
+        for(x = 0; x < XSZ; x++) {
+            v = *d;
+            fputc((v) & 0xff, f);
+            fputc((v) & 0xff, f);
+            fputc((v) & 0xff, f);
+            d++;
+        }
+        d1 += XSZ;
+    }
+    fclose(f);
+    return;
+}
+
+
+
diff --git a/tools/ioemu/hw/timer.c b/tools/ioemu/hw/timer.c
new file mode 100644 (file)
index 0000000..e393fa3
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * QEMU Sparc timer controller emulation
+ * 
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+
+/*
+ * Registers of hardware timer in sun4m.
+ */
+struct sun4m_timer_percpu {
+       volatile unsigned int l14_timer_limit; /* Initial value is 0x009c4000 */
+       volatile unsigned int l14_cur_count;
+};
+
+struct sun4m_timer_global {
+        volatile unsigned int l10_timer_limit;
+        volatile unsigned int l10_cur_count;
+};
+
+typedef struct TIMERState {
+    uint32_t addr;
+    uint32_t timer_regs[2];
+    int irq;
+} TIMERState;
+
+static uint32_t timer_mem_readl(void *opaque, target_phys_addr_t addr)
+{
+    TIMERState *s = opaque;
+    uint32_t saddr;
+
+    saddr = (addr - s->addr) >> 2;
+    switch (saddr) {
+    default:
+       return s->timer_regs[saddr];
+       break;
+    }
+    return 0;
+}
+
+static void timer_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
+{
+    TIMERState *s = opaque;
+    uint32_t saddr;
+
+    saddr = (addr - s->addr) >> 2;
+    switch (saddr) {
+    default:
+       s->timer_regs[saddr] = val;
+       break;
+    }
+}
+
+static CPUReadMemoryFunc *timer_mem_read[3] = {
+    timer_mem_readl,
+    timer_mem_readl,
+    timer_mem_readl,
+};
+
+static CPUWriteMemoryFunc *timer_mem_write[3] = {
+    timer_mem_writel,
+    timer_mem_writel,
+    timer_mem_writel,
+};
+
+void timer_init(uint32_t addr, int irq)
+{
+    int timer_io_memory;
+    TIMERState *s;
+
+    s = qemu_mallocz(sizeof(TIMERState));
+    if (!s)
+        return;
+    s->addr = addr;
+    s->irq = irq;
+
+    timer_io_memory = cpu_register_io_memory(0, timer_mem_read, timer_mem_write, s);
+    cpu_register_physical_memory(addr, 2, timer_io_memory);
+}
diff --git a/tools/ioemu/hw/vga.c b/tools/ioemu/hw/vga.c
new file mode 100644 (file)
index 0000000..d6358d9
--- /dev/null
@@ -0,0 +1,2059 @@
+/*
+ * QEMU VGA Emulator.
+ * 
+ * Copyright (c) 2003 Fabrice Bellard
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+#include "vga_int.h"
+
+//#define DEBUG_VGA
+//#define DEBUG_VGA_MEM
+//#define DEBUG_VGA_REG
+
+//#define DEBUG_S3
+//#define DEBUG_BOCHS_VBE
+
+/* S3 VGA is deprecated - another graphic card will be emulated */
+//#define CONFIG_S3VGA
+
+/* force some bits to zero */
+const uint8_t sr_mask[8] = {
+    (uint8_t)~0xfc,
+    (uint8_t)~0xc2,
+    (uint8_t)~0xf0,
+    (uint8_t)~0xc0,
+    (uint8_t)~0xf1,
+    (uint8_t)~0xff,
+    (uint8_t)~0xff,
+    (uint8_t)~0x00,
+};
+
+const uint8_t gr_mask[16] = {
+    (uint8_t)~0xf0, /* 0x00 */
+    (uint8_t)~0xf0, /* 0x01 */
+    (uint8_t)~0xf0, /* 0x02 */
+    (uint8_t)~0xe0, /* 0x03 */
+    (uint8_t)~0xfc, /* 0x04 */
+    (uint8_t)~0x84, /* 0x05 */
+    (uint8_t)~0xf0, /* 0x06 */
+    (uint8_t)~0xf0, /* 0x07 */
+    (uint8_t)~0x00, /* 0x08 */
+    (uint8_t)~0xff, /* 0x09 */
+    (uint8_t)~0xff, /* 0x0a */
+    (uint8_t)~0xff, /* 0x0b */
+    (uint8_t)~0xff, /* 0x0c */
+    (uint8_t)~0xff, /* 0x0d */
+    (uint8_t)~0xff, /* 0x0e */
+    (uint8_t)~0xff, /* 0x0f */
+};
+
+#define cbswap_32(__x) \
+((uint32_t)( \
+               (((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \
+               (((uint32_t)(__x) & (uint32_t)0x0000ff00UL) <<  8) | \
+               (((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >>  8) | \
+               (((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) ))
+
+#ifdef WORDS_BIGENDIAN
+#define PAT(x) cbswap_32(x)
+#else
+#define PAT(x) (x)
+#endif
+
+#ifdef WORDS_BIGENDIAN
+#define BIG 1
+#else
+#define BIG 0
+#endif
+
+#ifdef WORDS_BIGENDIAN
+#define GET_PLANE(data, p) (((data) >> (24 - (p) * 8)) & 0xff)
+#else
+#define GET_PLANE(data, p) (((data) >> ((p) * 8)) & 0xff)
+#endif
+
+static const uint32_t mask16[16] = {
+    PAT(0x00000000),
+    PAT(0x000000ff),
+    PAT(0x0000ff00),
+    PAT(0x0000ffff),
+    PAT(0x00ff0000),
+    PAT(0x00ff00ff),
+    PAT(0x00ffff00),
+    PAT(0x00ffffff),
+    PAT(0xff000000),
+    PAT(0xff0000ff),
+    PAT(0xff00ff00),
+    PAT(0xff00ffff),
+    PAT(0xffff0000),
+    PAT(0xffff00ff),
+    PAT(0xffffff00),
+    PAT(0xffffffff),
+};
+
+#undef PAT
+
+#ifdef WORDS_BIGENDIAN
+#define PAT(x) (x)
+#else
+#define PAT(x) cbswap_32(x)
+#endif
+
+static const uint32_t dmask16[16] = {
+    PAT(0x00000000),
+    PAT(0x000000ff),
+    PAT(0x0000ff00),
+    PAT(0x0000ffff),
+    PAT(0x00ff0000),
+    PAT(0x00ff00ff),
+    PAT(0x00ffff00),
+    PAT(0x00ffffff),
+    PAT(0xff000000),
+    PAT(0xff0000ff),
+    PAT(0xff00ff00),
+    PAT(0xff00ffff),
+    PAT(0xffff0000),
+    PAT(0xffff00ff),
+    PAT(0xffffff00),
+    PAT(0xffffffff),
+};
+
+static const uint32_t dmask4[4] = {
+    PAT(0x00000000),
+    PAT(0x0000ffff),
+    PAT(0xffff0000),
+    PAT(0xffffffff),
+};
+
+static uint32_t expand4[256];
+static uint16_t expand2[256];
+static uint8_t expand4to8[16];
+
+VGAState *vga_state;
+int vga_io_memory;
+
+static uint32_t vga_ioport_read(void *opaque, uint32_t addr)
+{
+    VGAState *s = opaque;
+    int val, index;
+
+    /* check port range access depending on color/monochrome mode */
+    if ((addr >= 0x3b0 && addr <= 0x3bf && (s->msr & MSR_COLOR_EMULATION)) ||
+        (addr >= 0x3d0 && addr <= 0x3df && !(s->msr & MSR_COLOR_EMULATION))) {
+        val = 0xff;
+    } else {
+        switch(addr) {
+        case 0x3c0:
+            if (s->ar_flip_flop == 0) {
+                val = s->ar_index;
+            } else {
+                val = 0;
+            }
+            break;
+        case 0x3c1:
+            index = s->ar_index & 0x1f;
+            if (index < 21) 
+                val = s->ar[index];
+            else
+                val = 0;
+            break;
+        case 0x3c2:
+            val = s->st00;
+            break;
+        case 0x3c4:
+            val = s->sr_index;
+            break;
+        case 0x3c5:
+            val = s->sr[s->sr_index];
+#ifdef DEBUG_VGA_REG
+            printf("vga: read SR%x = 0x%02x\n", s->sr_index, val);
+#endif
+            break;
+        case 0x3c7:
+            val = s->dac_state;
+            break;
+       case 0x3c8:
+           val = s->dac_write_index;
+           break;
+        case 0x3c9:
+            val = s->palette[s->dac_read_index * 3 + s->dac_sub_index];
+            if (++s->dac_sub_index == 3) {
+                s->dac_sub_index = 0;
+                s->dac_read_index++;
+            }
+            break;
+        case 0x3ca:
+            val = s->fcr;
+            break;
+        case 0x3cc:
+            val = s->msr;
+            break;
+        case 0x3ce:
+            val = s->gr_index;
+            break;
+        case 0x3cf:
+            val = s->gr[s->gr_index];
+#ifdef DEBUG_VGA_REG
+            printf("vga: read GR%x = 0x%02x\n", s->gr_index, val);
+#endif
+            break;
+        case 0x3b4:
+        case 0x3d4:
+            val = s->cr_index;
+            break;
+        case 0x3b5:
+        case 0x3d5:
+            val = s->cr[s->cr_index];
+#ifdef DEBUG_VGA_REG
+            printf("vga: read CR%x = 0x%02x\n", s->cr_index, val);
+#endif
+#ifdef DEBUG_S3
+            if (s->cr_index >= 0x20)
+                printf("S3: CR read index=0x%x val=0x%x\n",
+                       s->cr_index, val);
+#endif
+            break;
+        case 0x3ba:
+        case 0x3da:
+            /* just toggle to fool polling */
+            s->st01 ^= ST01_V_RETRACE | ST01_DISP_ENABLE;
+            val = s->st01;
+            s->ar_flip_flop = 0;
+            break;
+        default:
+            val = 0x00;
+            break;
+        }
+    }
+#if defined(DEBUG_VGA)
+    printf("VGA: read addr=0x%04x data=0x%02x\n", addr, val);
+#endif
+    return val;
+}
+
+static void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+{
+    VGAState *s = opaque;
+    int index;
+
+    /* check port range access depending on color/monochrome mode */
+    if ((addr >= 0x3b0 && addr <= 0x3bf && (s->msr & MSR_COLOR_EMULATION)) ||
+        (addr >= 0x3d0 && addr <= 0x3df && !(s->msr & MSR_COLOR_EMULATION)))
+        return;
+
+#ifdef DEBUG_VGA
+    printf("VGA: write addr=0x%04x data=0x%02x\n", addr, val);
+#endif
+
+    switch(addr) {
+    case 0x3c0:
+        if (s->ar_flip_flop == 0) {
+            val &= 0x3f;
+            s->ar_index = val;
+        } else {
+            index = s->ar_index & 0x1f;
+            switch(index) {
+            case 0x00 ... 0x0f:
+                s->ar[index] = val & 0x3f;
+                break;
+            case 0x10:
+                s->ar[index] = val & ~0x10;
+                break;
+            case 0x11:
+                s->ar[index] = val;
+                break;
+            case 0x12:
+                s->ar[index] = val & ~0xc0;
+                break;
+            case 0x13:
+                s->ar[index] = val & ~0xf0;
+                break;
+            case 0x14:
+                s->ar[index] = val & ~0xf0;
+                break;
+            default:
+                break;
+            }
+        }
+        s->ar_flip_flop ^= 1;
+        break;
+    case 0x3c2:
+        s->msr = val & ~0x10;
+        break;
+    case 0x3c4:
+        s->sr_index = val & 7;
+        break;
+    case 0x3c5:
+#ifdef DEBUG_VGA_REG
+        printf("vga: write SR%x = 0x%02x\n", s->sr_index, val);
+#endif
+        s->sr[s->sr_index] = val & sr_mask[s->sr_index];
+        break;
+    case 0x3c7:
+        s->dac_read_index = val;
+        s->dac_sub_index = 0;
+        s->dac_state = 3;
+        break;
+    case 0x3c8:
+        s->dac_write_index = val;
+        s->dac_sub_index = 0;
+        s->dac_state = 0;
+        break;
+    case 0x3c9:
+        s->dac_cache[s->dac_sub_index] = val;
+        if (++s->dac_sub_index == 3) {
+            memcpy(&s->palette[s->dac_write_index * 3], s->dac_cache, 3);
+            s->dac_sub_index = 0;
+            s->dac_write_index++;
+        }
+        break;
+    case 0x3ce:
+        s->gr_index = val & 0x0f;
+        break;
+    case 0x3cf:
+#ifdef DEBUG_VGA_REG
+        printf("vga: write GR%x = 0x%02x\n", s->gr_index, val);
+#endif
+        s->gr[s->gr_index] = val & gr_mask[s->gr_index];
+        break;
+    case 0x3b4:
+    case 0x3d4:
+        s->cr_index = val;
+        break;
+    case 0x3b5:
+    case 0x3d5:
+#ifdef DEBUG_VGA_REG
+        printf("vga: write CR%x = 0x%02x\n", s->cr_index, val);
+#endif
+        /* handle CR0-7 protection */
+        if ((s->cr[0x11] & 0x80) && s->cr_index <= 7) {
+            /* can always write bit 4 of CR7 */
+            if (s->cr_index == 7)
+                s->cr[7] = (s->cr[7] & ~0x10) | (val & 0x10);
+            return;
+        }
+        switch(s->cr_index) {
+        case 0x01: /* horizontal display end */
+        case 0x07:
+        case 0x09:
+        case 0x0c:
+        case 0x0d:
+        case 0x12: /* veritcal display end */
+            s->cr[s->cr_index] = val;
+            break;
+
+#ifdef CONFIG_S3VGA
+            /* S3 registers */
+        case 0x2d:
+        case 0x2e:
+        case 0x2f:
+        case 0x30:
+            /* chip ID, cannot write */
+            break;
+        case 0x31:
+            /* update start address */
+            {
+                int v;
+                s->cr[s->cr_index] = val;
+                v = (val >> 4) & 3;
+                s->cr[0x69] = (s->cr[69] & ~0x03) | v;
+            }
+            break;
+        case 0x51:
+            /* update start address */
+            {
+                int v;
+                s->cr[s->cr_index] = val;
+                v = val & 3;
+                s->cr[0x69] = (s->cr[69] & ~0x0c) | (v << 2);
+            }
+            break;
+#endif
+        default:
+            s->cr[s->cr_index] = val;
+            break;
+        }
+#ifdef DEBUG_S3
+        if (s->cr_index >= 0x20)
+            printf("S3: CR write index=0x%x val=0x%x\n",
+                   s->cr_index, val);
+#endif
+        break;
+    case 0x3ba:
+    case 0x3da:
+        s->fcr = val & 0x10;
+        break;
+    }
+}
+
+#ifdef CONFIG_BOCHS_VBE
+static uint32_t vbe_ioport_read_index(void *opaque, uint32_t addr)
+{
+    VGAState *s = opaque;
+    uint32_t val;
+    val = s->vbe_index;
+    return val;
+}
+
+static uint32_t vbe_ioport_read_data(void *opaque, uint32_t addr)
+{
+    VGAState *s = opaque;
+    uint32_t val;
+
+    if (s->vbe_index <= VBE_DISPI_INDEX_NB)
+        val = s->vbe_regs[s->vbe_index];
+    else
+        val = 0;
+#ifdef DEBUG_BOCHS_VBE
+    printf("VBE: read index=0x%x val=0x%x\n", s->vbe_index, val);
+#endif
+    return val;
+}
+
+static void vbe_ioport_write_index(void *opaque, uint32_t addr, uint32_t val)
+{
+    VGAState *s = opaque;
+    s->vbe_index = val;
+}
+
+static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
+{
+    VGAState *s = opaque;
+
+    if (s->vbe_index <= VBE_DISPI_INDEX_NB) {
+#ifdef DEBUG_BOCHS_VBE
+        printf("VBE: write index=0x%x val=0x%x\n", s->vbe_index, val);
+#endif
+        switch(s->vbe_index) {
+        case VBE_DISPI_INDEX_ID:
+            if (val == VBE_DISPI_ID0 ||
+                val == VBE_DISPI_ID1 ||
+                val == VBE_DISPI_ID2) {
+                s->vbe_regs[s->vbe_index] = val;
+            }
+            break;
+        case VBE_DISPI_INDEX_XRES:
+            if ((val <= VBE_DISPI_MAX_XRES) && ((val & 7) == 0)) {
+                s->vbe_regs[s->vbe_index] = val;
+            }
+            break;
+        case VBE_DISPI_INDEX_YRES:
+            if (val <= VBE_DISPI_MAX_YRES) {
+                s->vbe_regs[s->vbe_index] = val;
+            }
+            break;
+        case VBE_DISPI_INDEX_BPP:
+            if (val == 0)
+                val = 8;
+            if (val == 4 || val == 8 || val == 15 || 
+                val == 16 || val == 24 || val == 32) {
+                s->vbe_regs[s->vbe_index] = val;
+            }
+            break;
+        case VBE_DISPI_INDEX_BANK:
+            val &= s->vbe_bank_mask;
+            s->vbe_regs[s->vbe_index] = val;
+            s->bank_offset = (val << 16);
+            break;
+        case VBE_DISPI_INDEX_ENABLE:
+            if (val & VBE_DISPI_ENABLED) {
+                int h, shift_control;
+
+                s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = 
+                    s->vbe_regs[VBE_DISPI_INDEX_XRES];
+                s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = 
+                    s->vbe_regs[VBE_DISPI_INDEX_YRES];
+                s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0;
+                s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0;
+                
+                if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4)
+                    s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 1;
+                else
+                    s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] * 
+                        ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
+                s->vbe_start_addr = 0;
+                
+                /* clear the screen (should be done in BIOS) */
+                if (!(val & VBE_DISPI_NOCLEARMEM)) {
+                    memset(s->vram_ptr, 0, 
+                           s->vbe_regs[VBE_DISPI_INDEX_YRES] * s->vbe_line_offset);
+                }
+                
+                /* we initialize the VGA graphic mode (should be done
+                   in BIOS) */
+                s->gr[0x06] = (s->gr[0x06] & ~0x0c) | 0x05; /* graphic mode + memory map 1 */
+                s->cr[0x17] |= 3; /* no CGA modes */
+                s->cr[0x13] = s->vbe_line_offset >> 3;
+                /* width */
+                s->cr[0x01] = (s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 3) - 1;
+                /* height */
+                h = s->vbe_regs[VBE_DISPI_INDEX_YRES] - 1;
+                s->cr[0x12] = h;
+                s->cr[0x07] = (s->cr[0x07] & ~0x42) | 
+                    ((h >> 7) & 0x02) | ((h >> 3) & 0x40);
+                /* line compare to 1023 */
+                s->cr[0x18] = 0xff;
+                s->cr[0x07] |= 0x10;
+                s->cr[0x09] |= 0x40;
+                
+                if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
+                    shift_control = 0;
+                    s->sr[0x01] &= ~8; /* no double line */
+                } else {
+                    shift_control = 2;
+                    s->sr[4] |= 0x08; /* set chain 4 mode */
+                    s->sr[2] |= 0x0f; /* activate all planes */
+                }
+                s->gr[0x05] = (s->gr[0x05] & ~0x60) | (shift_control << 5);
+                s->cr[0x09] &= ~0x9f; /* no double scan */
+            } else {
+                /* XXX: the bios should do that */
+                s->bank_offset = 0;
+            }
+            s->vbe_regs[s->vbe_index] = val;
+            break;
+        case VBE_DISPI_INDEX_VIRT_WIDTH:
+            {
+                int w, h, line_offset;
+
+                if (val < s->vbe_regs[VBE_DISPI_INDEX_XRES])
+                    return;
+                w = val;
+                if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4)
+                    line_offset = w >> 1;
+                else
+                    line_offset = w * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
+                h = s->vram_size / line_offset;
+                /* XXX: support weird bochs semantics ? */
+                if (h < s->vbe_regs[VBE_DISPI_INDEX_YRES])
+                    return;
+                s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = w;
+                s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = h;
+                s->vbe_line_offset = line_offset;
+            }
+            break;
+        case VBE_DISPI_INDEX_X_OFFSET:
+        case VBE_DISPI_INDEX_Y_OFFSET:
+            {
+                int x;
+                s->vbe_regs[s->vbe_index] = val;
+                s->vbe_start_addr = s->vbe_line_offset * s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET];
+                x = s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET];
+                if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4)
+                    s->vbe_start_addr += x >> 1;
+                else
+                    s->vbe_start_addr += x * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
+                s->vbe_start_addr >>= 2;
+            }
+            break;
+        default:
+            break;
+        }
+    }
+}
+#endif
+
+extern FILE *logfile;
+/* called for accesses between 0xa0000 and 0xc0000 */
+uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr)
+{
+    VGAState *s = opaque;
+    int memory_map_mode, plane;
+    uint32_t ret;
+    
+    /* convert to VGA memory offset */
+    memory_map_mode = (s->gr[6] >> 2) & 3;
+    addr &= 0x1ffff;
+    switch(memory_map_mode) {
+    case 0:
+        break;
+    case 1:
+        if (addr >= 0x10000)
+            return 0xff;
+        addr += s->bank_offset;
+        break;
+    case 2:
+        addr -= 0x10000;
+        if (addr >= 0x8000)
+            return 0xff;
+        break;
+    default:
+    case 3:
+        addr -= 0x18000;
+        if (addr >= 0x8000)
+            return 0xff;
+        break;
+    }
+    
+    if (s->sr[4] & 0x08) {
+        /* chain 4 mode : simplest access */
+        ret = s->vram_ptr[addr];
+    } else if (s->gr[5] & 0x10) {
+        /* odd/even mode (aka text mode mapping) */
+        plane = (s->gr[4] & 2) | (addr & 1);
+        ret = s->vram_ptr[((addr & ~1) << 1) | plane];
+    } else {
+        /* standard VGA latched access */
+        s->latch = ((uint32_t *)s->vram_ptr)[addr];
+
+        if (!(s->gr[5] & 0x08)) {
+            /* read mode 0 */
+            plane = s->gr[4];
+            ret = GET_PLANE(s->latch, plane);
+        } else {
+            /* read mode 1 */
+            ret = (s->latch ^ mask16[s->gr[2]]) & mask16[s->gr[7]];
+            ret |= ret >> 16;
+            ret |= ret >> 8;
+            ret = (~ret) & 0xff;
+        }
+    }
+    return ret;
+}
+
+static uint32_t vga_mem_readw(void *opaque, target_phys_addr_t addr)
+{
+    uint32_t v;
+#ifdef TARGET_WORDS_BIGENDIAN
+    v = vga_mem_readb(opaque, addr) << 8;
+    v |= vga_mem_readb(opaque, addr + 1);
+#else
+    v = vga_mem_readb(opaque, addr);
+    v |= vga_mem_readb(opaque, addr + 1) << 8;
+#endif
+    return v;
+}
+
+static uint32_t vga_mem_readl(void *opaque, target_phys_addr_t addr)
+{
+    uint32_t v;
+#ifdef TARGET_WORDS_BIGENDIAN
+    v = vga_mem_readb(opaque, addr) << 24;
+    v |= vga_mem_readb(opaque, addr + 1) << 16;
+    v |= vga_mem_readb(opaque, addr + 2) << 8;
+    v |= vga_mem_readb(opaque, addr + 3);
+#else
+    v = vga_mem_readb(opaque, addr);
+    v |= vga_mem_readb(opaque, addr + 1) << 8;
+    v |= vga_mem_readb(opaque, addr + 2) << 16;
+    v |= vga_mem_readb(opaque, addr + 3) << 24;
+#endif
+    return v;
+}
+
+/* called for accesses between 0xa0000 and 0xc0000 */
+void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
+{
+    VGAState *s = opaque;
+    int memory_map_mode, plane, write_mode, b, func_select, mask;
+    uint32_t write_mask, bit_mask, set_mask;
+
+#ifdef DEBUG_VGA_MEM
+    printf("vga: [0x%x] = 0x%02x\n", addr, val);
+#endif
+    /* convert to VGA memory offset */
+    memory_map_mode = (s->gr[6] >> 2) & 3;
+    addr &= 0x1ffff;
+    switch(memory_map_mode) {
+    case 0:
+        break;
+    case 1:
+        if (addr >= 0x10000)
+            return;
+        addr += s->bank_offset;
+        break;
+    case 2:
+        addr -= 0x10000;
+        if (addr >= 0x8000)
+            return;
+        break;
+    default:
+    case 3:
+        addr -= 0x18000;
+        if (addr >= 0x8000)
+            return;
+        break;
+    }
+    
+    if (s->sr[4] & 0x08) {
+        /* chain 4 mode : simplest access */
+        plane = addr & 3;
+        mask = (1 << plane);
+        if (s->sr[2] & mask) {
+            s->vram_ptr[addr] = val;
+#ifdef DEBUG_VGA_MEM
+            printf("vga: chain4: [0x%x]\n", addr);
+#endif
+            s->plane_updated |= mask; /* only used to detect font change */
+            cpu_physical_memory_set_dirty(s->vram_offset + addr);
+        }
+    } else if (s->gr[5] & 0x10) {
+        /* odd/even mode (aka text mode mapping) */
+        plane = (s->gr[4] & 2) | (addr & 1);
+        mask = (1 << plane);
+        if (s->sr[2] & mask) {
+            addr = ((addr & ~1) << 1) | plane;
+            s->vram_ptr[addr] = val;
+#ifdef DEBUG_VGA_MEM
+            printf("vga: odd/even: [0x%x]\n", addr);
+#endif
+            s->plane_updated |= mask; /* only used to detect font change */
+            cpu_physical_memory_set_dirty(s->vram_offset + addr);
+        }
+    } else {
+        /* standard VGA latched access */
+        write_mode = s->gr[5] & 3;
+        switch(write_mode) {
+        default:
+        case 0:
+            /* rotate */
+            b = s->gr[3] & 7;
+            val = ((val >> b) | (val << (8 - b))) & 0xff;
+            val |= val << 8;
+            val |= val << 16;
+
+            /* apply set/reset mask */
+            set_mask = mask16[s->gr[1]];
+            val = (val & ~set_mask) | (mask16[s->gr[0]] & set_mask);
+            bit_mask = s->gr[8];
+            break;
+        case 1:
+            val = s->latch;
+            goto do_write;
+        case 2:
+            val = mask16[val & 0x0f];
+            bit_mask = s->gr[8];
+            break;
+        case 3:
+            /* rotate */
+            b = s->gr[3] & 7;
+            val = (val >> b) | (val << (8 - b));
+
+            bit_mask = s->gr[8] & val;
+            val = mask16[s->gr[0]];
+            break;
+        }
+
+        /* apply logical operation */
+        func_select = s->gr[3] >> 3;
+        switch(func_select) {
+        case 0:
+        default:
+            /* nothing to do */
+            break;
+        case 1:
+            /* and */
+            val &= s->latch;
+            break;
+        case 2:
+            /* or */
+            val |= s->latch;
+            break;
+        case 3:
+            /* xor */
+            val ^= s->latch;
+            break;
+        }
+
+        /* apply bit mask */
+        bit_mask |= bit_mask << 8;
+        bit_mask |= bit_mask << 16;
+        val = (val & bit_mask) | (s->latch & ~bit_mask);
+
+    do_write:
+        /* mask data according to sr[2] */
+        mask = s->sr[2];
+        s->plane_updated |= mask; /* only used to detect font change */
+        write_mask = mask16[mask];
+        ((uint32_t *)s->vram_ptr)[addr] = 
+            (((uint32_t *)s->vram_ptr)[addr] & ~write_mask) | 
+            (val & write_mask);
+#ifdef DEBUG_VGA_MEM
+            printf("vga: latch: [0x%x] mask=0x%08x val=0x%08x\n", 
+                   addr * 4, write_mask, val);
+#endif
+            cpu_physical_memory_set_dirty(s->vram_offset + (addr << 2));
+    }
+}
+
+static void vga_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
+{
+#ifdef TARGET_WORDS_BIGENDIAN
+    vga_mem_writeb(opaque, addr, (val >> 8) & 0xff);
+    vga_mem_writeb(opaque, addr + 1, val & 0xff);
+#else
+    vga_mem_writeb(opaque, addr, val & 0xff);
+    vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
+#endif
+}
+
+static void vga_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
+{
+#ifdef TARGET_WORDS_BIGENDIAN
+    vga_mem_writeb(opaque, addr, (val >> 24) & 0xff);
+    vga_mem_writeb(opaque, addr + 1, (val >> 16) & 0xff);
+    vga_mem_writeb(opaque, addr + 2, (val >> 8) & 0xff);
+    vga_mem_writeb(opaque, addr + 3, val & 0xff);
+#else
+    vga_mem_writeb(opaque, addr, val & 0xff);
+    vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
+    vga_mem_writeb(opaque, addr + 2, (val >> 16) & 0xff);
+    vga_mem_writeb(opaque, addr + 3, (val >> 24) & 0xff);
+#endif
+}
+
+typedef void vga_draw_glyph8_func(uint8_t *d, int linesize,
+                             const uint8_t *font_ptr, int h,
+                             uint32_t fgcol, uint32_t bgcol);
+typedef void vga_draw_glyph9_func(uint8_t *d, int linesize,
+                                  const uint8_t *font_ptr, int h, 
+                                  uint32_t fgcol, uint32_t bgcol, int dup9);
+typedef void vga_draw_line_func(VGAState *s1, uint8_t *d, 
+                                const uint8_t *s, int width);
+
+static inline unsigned int rgb_to_pixel8(unsigned int r, unsigned int g, unsigned b)
+{
+    return ((r >> 5) << 5) | ((g >> 5) << 2) | (b >> 6);
+}
+
+static inline unsigned int rgb_to_pixel15(unsigned int r, unsigned int g, unsigned b)
+{
+    return ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3);
+}
+
+static inline unsigned int rgb_to_pixel16(unsigned int r, unsigned int g, unsigned b)
+{
+    return ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
+}
+
+static inline unsigned int rgb_to_pixel32(unsigned int r, unsigned int g, unsigned b)
+{
+    return (r << 16) | (g << 8) | b;
+}
+
+#define DEPTH 8
+#include "vga_template.h"
+
+#define DEPTH 15
+#include "vga_template.h"
+
+#define DEPTH 16
+#include "vga_template.h"
+
+#define DEPTH 32
+#include "vga_template.h"
+
+static unsigned int rgb_to_pixel8_dup(unsigned int r, unsigned int g, unsigned b)
+{
+    unsigned int col;
+    col = rgb_to_pixel8(r, g, b);
+    col |= col << 8;
+    col |= col << 16;
+    return col;
+}
+
+static unsigned int rgb_to_pixel15_dup(unsigned int r, unsigned int g, unsigned b)
+{
+    unsigned int col;
+    col = rgb_to_pixel15(r, g, b);
+    col |= col << 16;
+    return col;
+}
+
+static unsigned int rgb_to_pixel16_dup(unsigned int r, unsigned int g, unsigned b)
+{
+    unsigned int col;
+    col = rgb_to_pixel16(r, g, b);
+    col |= col << 16;
+    return col;
+}
+
+static unsigned int rgb_to_pixel32_dup(unsigned int r, unsigned int g, unsigned b)
+{
+    unsigned int col;
+    col = rgb_to_pixel32(r, g, b);
+    return col;
+}
+
+/* return true if the palette was modified */
+static int update_palette16(VGAState *s)
+{
+    int full_update, i;
+    uint32_t v, col, *palette;
+
+    full_update = 0;
+    palette = s->last_palette;
+    for(i = 0; i < 16; i++) {
+        v = s->ar[i];
+        if (s->ar[0x10] & 0x80)
+            v = ((s->ar[0x14] & 0xf) << 4) | (v & 0xf);
+        else
+            v = ((s->ar[0x14] & 0xc) << 4) | (v & 0x3f);
+        v = v * 3;
+        col = s->rgb_to_pixel(c6_to_8(s->palette[v]), 
+                              c6_to_8(s->palette[v + 1]), 
+                              c6_to_8(s->palette[v + 2]));
+        if (col != palette[i]) {
+            full_update = 1;
+            palette[i] = col;
+        }
+    }
+    return full_update;
+}
+
+/* return true if the palette was modified */
+static int update_palette256(VGAState *s)
+{
+    int full_update, i;
+    uint32_t v, col, *palette;
+
+    full_update = 0;
+    palette = s->last_palette;
+    v = 0;
+    for(i = 0; i < 256; i++) {
+        col = s->rgb_to_pixel(c6_to_8(s->palette[v]), 
+                              c6_to_8(s->palette[v + 1]), 
+                              c6_to_8(s->palette[v + 2]));
+        if (col != palette[i]) {
+            full_update = 1;
+            palette[i] = col;
+        }
+        v += 3;
+    }
+    return full_update;
+}
+
+static void vga_get_offsets(VGAState *s, 
+                            uint32_t *pline_offset, 
+                            uint32_t *pstart_addr)
+{
+    uint32_t start_addr, line_offset;
+#ifdef CONFIG_BOCHS_VBE
+    if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
+        line_offset = s->vbe_line_offset;
+        start_addr = s->vbe_start_addr;
+    } else
+#endif
+    {  
+        /* compute line_offset in bytes */
+        line_offset = s->cr[0x13];
+#ifdef CONFIG_S3VGA
+        {
+            uinr32_t v;
+            v = (s->cr[0x51] >> 4) & 3; /* S3 extension */
+            if (v == 0)
+                v = (s->cr[0x43] >> 2) & 1; /* S3 extension */
+            line_offset |= (v << 8);
+        }
+#endif
+        line_offset <<= 3;
+        
+        /* starting address */
+        start_addr = s->cr[0x0d] | (s->cr[0x0c] << 8);
+#ifdef CONFIG_S3VGA
+        start_addr |= (s->cr[0x69] & 0x1f) << 16; /* S3 extension */
+#endif
+    }
+    *pline_offset = line_offset;
+    *pstart_addr = start_addr;
+}
+
+/* update start_addr and line_offset. Return TRUE if modified */
+static int update_basic_params(VGAState *s)
+{
+    int full_update;
+    uint32_t start_addr, line_offset, line_compare;
+    
+    full_update = 0;
+
+    s->get_offsets(s, &line_offset, &start_addr);
+    /* line compare */
+    line_compare = s->cr[0x18] | 
+        ((s->cr[0x07] & 0x10) << 4) |
+        ((s->cr[0x09] & 0x40) << 3);
+
+    if (line_offset != s->line_offset ||
+        start_addr != s->start_addr ||
+        line_compare != s->line_compare) {
+        s->line_offset = line_offset;
+        s->start_addr = start_addr;
+        s->line_compare = line_compare;
+        full_update = 1;
+    }
+    return full_update;
+}
+
+static inline int get_depth_index(int depth)
+{
+    switch(depth) {
+    default:
+    case 8:
+        return 0;
+    case 15:
+        return 1;
+    case 16:
+        return 2;
+    case 32:
+        return 3;
+    }
+}
+
+static vga_draw_glyph8_func *vga_draw_glyph8_table[4] = {
+    vga_draw_glyph8_8,
+    vga_draw_glyph8_16,
+    vga_draw_glyph8_16,
+    vga_draw_glyph8_32,
+};
+
+static vga_draw_glyph8_func *vga_draw_glyph16_table[4] = {
+    vga_draw_glyph16_8,
+    vga_draw_glyph16_16,
+    vga_draw_glyph16_16,
+    vga_draw_glyph16_32,
+};
+
+static vga_draw_glyph9_func *vga_draw_glyph9_table[4] = {
+    vga_draw_glyph9_8,
+    vga_draw_glyph9_16,
+    vga_draw_glyph9_16,
+    vga_draw_glyph9_32,
+};
+    
+static const uint8_t cursor_glyph[32 * 4] = {
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+};    
+
+/* 
+ * Text mode update 
+ * Missing:
+ * - double scan
+ * - double width 
+ * - underline
+ * - flashing
+ */
+static void vga_draw_text(VGAState *s, int full_update)
+{
+    int cx, cy, cheight, cw, ch, cattr, height, width, ch_attr;
+    int cx_min, cx_max, linesize, x_incr;
+    uint32_t offset, fgcol, bgcol, v, cursor_offset;
+    uint8_t *d1, *d, *src, *s1, *dest, *cursor_ptr;
+    const uint8_t *font_ptr, *font_base[2];
+    int dup9, line_offset, depth_index;
+    uint32_t *palette;
+    uint32_t *ch_attr_ptr;
+    vga_draw_glyph8_func *vga_draw_glyph8;
+    vga_draw_glyph9_func *vga_draw_glyph9;
+
+    full_update |= update_palette16(s);
+    palette = s->last_palette;
+    
+    /* compute font data address (in plane 2) */
+    v = s->sr[3];
+    offset = (((v >> 4) & 1) | ((v << 1) & 6)) * 8192 * 4 + 2;
+    if (offset != s->font_offsets[0]) {
+        s->font_offsets[0] = offset;
+        full_update = 1;
+    }
+    font_base[0] = s->vram_ptr + offset;
+
+    offset = (((v >> 5) & 1) | ((v >> 1) & 6)) * 8192 * 4 + 2;
+    font_base[1] = s->vram_ptr + offset;
+    if (offset != s->font_offsets[1]) {
+        s->font_offsets[1] = offset;
+        full_update = 1;
+    }
+    if (s->plane_updated & (1 << 2)) {
+        /* if the plane 2 was modified since the last display, it
+           indicates the font may have been modified */
+        s->plane_updated = 0;
+        full_update = 1;
+    }
+    full_update |= update_basic_params(s);
+
+    line_offset = s->line_offset;
+    s1 = s->vram_ptr + (s->start_addr * 4);
+
+    /* total width & height */
+    cheight = (s->cr[9] & 0x1f) + 1;
+    cw = 8;
+    if (!(s->sr[1] & 0x01))
+        cw = 9;
+    if (s->sr[1] & 0x08)
+        cw = 16; /* NOTE: no 18 pixel wide */
+    x_incr = cw * ((s->ds->depth + 7) >> 3);
+    width = (s->cr[0x01] + 1);
+    if (s->cr[0x06] == 100) {
+        /* ugly hack for CGA 160x100x16 - explain me the logic */
+        height = 100;
+    } else {
+        height = s->cr[0x12] | 
+            ((s->cr[0x07] & 0x02) << 7) | 
+            ((s->cr[0x07] & 0x40) << 3);
+        height = (height + 1) / cheight;
+    }
+    if ((height * width) > CH_ATTR_SIZE) {
+        /* better than nothing: exit if transient size is too big */
+        return;
+    }
+
+    if (width != s->last_width || height != s->last_height ||
+        cw != s->last_cw || cheight != s->last_ch) {
+        s->last_scr_width = width * cw;
+        s->last_scr_height = height * cheight;
+        dpy_resize(s->ds, s->last_scr_width, s->last_scr_height);
+        s->last_width = width;
+        s->last_height = height;
+        s->last_ch = cheight;
+        s->last_cw = cw;
+        full_update = 1;
+    }
+    cursor_offset = ((s->cr[0x0e] << 8) | s->cr[0x0f]) - s->start_addr;
+    if (cursor_offset != s->cursor_offset ||
+        s->cr[0xa] != s->cursor_start ||
+        s->cr[0xb] != s->cursor_end) {
+      /* if the cursor position changed, we update the old and new
+         chars */
+        if (s->cursor_offset < CH_ATTR_SIZE)
+            s->last_ch_attr[s->cursor_offset] = -1;
+        if (cursor_offset < CH_ATTR_SIZE)
+            s->last_ch_attr[cursor_offset] = -1;
+        s->cursor_offset = cursor_offset;
+        s->cursor_start = s->cr[0xa];
+        s->cursor_end = s->cr[0xb];
+    }
+    cursor_ptr = s->vram_ptr + (s->start_addr + cursor_offset) * 4;
+    
+    depth_index = get_depth_index(s->ds->depth);
+    if (cw == 16)
+        vga_draw_glyph8 = vga_draw_glyph16_table[depth_index];
+    else
+        vga_draw_glyph8 = vga_draw_glyph8_table[depth_index];
+    vga_draw_glyph9 = vga_draw_glyph9_table[depth_index];
+    
+    dest = s->ds->data;
+    linesize = s->ds->linesize;
+    ch_attr_ptr = s->last_ch_attr;
+    for(cy = 0; cy < height; cy++) {
+        d1 = dest;
+        src = s1;
+        cx_min = width;
+        cx_max = -1;
+        for(cx = 0; cx < width; cx++) {
+            ch_attr = *(uint16_t *)src;
+            if (full_update || ch_attr != *ch_attr_ptr) {
+                if (cx < cx_min)
+                    cx_min = cx;
+                if (cx > cx_max)
+                    cx_max = cx;
+                *ch_attr_ptr = ch_attr;
+#ifdef WORDS_BIGENDIAN
+                ch = ch_attr >> 8;
+                cattr = ch_attr & 0xff;
+#else
+                ch = ch_attr & 0xff;
+                cattr = ch_attr >> 8;
+#endif
+                font_ptr = font_base[(cattr >> 3) & 1];
+                font_ptr += 32 * 4 * ch;
+                bgcol = palette[cattr >> 4];
+                fgcol = palette[cattr & 0x0f];
+                if (cw != 9) {
+                    vga_draw_glyph8(d1, linesize, 
+                                    font_ptr, cheight, fgcol, bgcol);
+                } else {
+                    dup9 = 0;
+                    if (ch >= 0xb0 && ch <= 0xdf && (s->ar[0x10] & 0x04))
+                        dup9 = 1;
+                    vga_draw_glyph9(d1, linesize, 
+                                    font_ptr, cheight, fgcol, bgcol, dup9);
+                }
+                if (src == cursor_ptr &&
+                    !(s->cr[0x0a] & 0x20)) {
+                    int line_start, line_last, h;
+                    /* draw the cursor */
+                    line_start = s->cr[0x0a] & 0x1f;
+                    line_last = s->cr[0x0b] & 0x1f;
+                    /* XXX: check that */
+                    if (line_last > cheight - 1)
+                        line_last = cheight - 1;
+                    if (line_last >= line_start && line_start < cheight) {
+                        h = line_last - line_start + 1;
+                        d = d1 + linesize * line_start;
+                        if (cw != 9) {
+                            vga_draw_glyph8(d, linesize, 
+                                            cursor_glyph, h, fgcol, bgcol);
+                        } else {
+                            vga_draw_glyph9(d, linesize, 
+                                            cursor_glyph, h, fgcol, bgcol, 1);
+                        }
+                    }
+                }
+            }
+            d1 += x_incr;
+            src += 4;
+            ch_attr_ptr++;
+        }
+        if (cx_max != -1) {
+            dpy_update(s->ds, cx_min * cw, cy * cheight, 
+                       (cx_max - cx_min + 1) * cw, cheight);
+        }
+        dest += linesize * cheight;
+        s1 += line_offset;
+    }
+}
+
+enum {
+    VGA_DRAW_LINE2,
+    VGA_DRAW_LINE2D2,
+    VGA_DRAW_LINE4,
+    VGA_DRAW_LINE4D2,
+    VGA_DRAW_LINE8D2,
+    VGA_DRAW_LINE8,
+    VGA_DRAW_LINE15,
+    VGA_DRAW_LINE16,
+    VGA_DRAW_LINE24,
+    VGA_DRAW_LINE32,
+    VGA_DRAW_LINE_NB,
+};
+
+static vga_draw_line_func *vga_draw_line_table[4 * VGA_DRAW_LINE_NB] = {
+    vga_draw_line2_8,
+    vga_draw_line2_16,
+    vga_draw_line2_16,
+    vga_draw_line2_32,
+
+    vga_draw_line2d2_8,
+    vga_draw_line2d2_16,
+    vga_draw_line2d2_16,
+    vga_draw_line2d2_32,
+
+    vga_draw_line4_8,
+    vga_draw_line4_16,
+    vga_draw_line4_16,
+    vga_draw_line4_32,
+
+    vga_draw_line4d2_8,
+    vga_draw_line4d2_16,
+    vga_draw_line4d2_16,
+    vga_draw_line4d2_32,
+
+    vga_draw_line8d2_8,
+    vga_draw_line8d2_16,
+    vga_draw_line8d2_16,
+    vga_draw_line8d2_32,
+
+    vga_draw_line8_8,
+    vga_draw_line8_16,
+    vga_draw_line8_16,
+    vga_draw_line8_32,
+
+    vga_draw_line15_8,
+    vga_draw_line15_15,
+    vga_draw_line15_16,
+    vga_draw_line15_32,
+
+    vga_draw_line16_8,
+    vga_draw_line16_15,
+    vga_draw_line16_16,
+    vga_draw_line16_32,
+
+    vga_draw_line24_8,
+    vga_draw_line24_15,
+    vga_draw_line24_16,
+    vga_draw_line24_32,
+
+    vga_draw_line32_8,
+    vga_draw_line32_15,
+    vga_draw_line32_16,
+    vga_draw_line32_32,
+};
+
+static int vga_get_bpp(VGAState *s)
+{
+    int ret;
+#ifdef CONFIG_BOCHS_VBE
+    if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
+        ret = s->vbe_regs[VBE_DISPI_INDEX_BPP];
+    } else 
+#endif
+    {
+        ret = 0;
+    }
+    return ret;
+}
+
+static void vga_get_resolution(VGAState *s, int *pwidth, int *pheight)
+{
+    int width, height;
+    
+    width = (s->cr[0x01] + 1) * 8;
+    height = s->cr[0x12] | 
+        ((s->cr[0x07] & 0x02) << 7) | 
+        ((s->cr[0x07] & 0x40) << 3);
+    height = (height + 1);
+    *pwidth = width;
+    *pheight = height;
+}
+
+void vga_invalidate_scanlines(VGAState *s, int y1, int y2)
+{
+    int y;
+    if (y1 >= VGA_MAX_HEIGHT)
+        return;
+    if (y2 >= VGA_MAX_HEIGHT)
+        y2 = VGA_MAX_HEIGHT;
+    for(y = y1; y < y2; y++) {
+        s->invalidated_y_table[y >> 5] |= 1 << (y & 0x1f);
+    }
+}
+
+/* 
+ * graphic modes
+ */
+static void vga_draw_graphic(VGAState *s, int full_update)
+{
+    int y1, y, update, page_min, page_max, linesize, y_start, double_scan, mask;
+    int width, height, shift_control, line_offset, page0, page1, bwidth;
+    int disp_width, multi_scan, multi_run;
+    uint8_t *d;
+    uint32_t v, addr1, addr;
+    vga_draw_line_func *vga_draw_line;
+    
+    full_update |= update_basic_params(s);
+
+    s->get_resolution(s, &width, &height);
+    disp_width = width;
+
+    shift_control = (s->gr[0x05] >> 5) & 3;
+    double_scan = (s->cr[0x09] >> 7);
+    if (shift_control != 1) {
+        multi_scan = (((s->cr[0x09] & 0x1f) + 1) << double_scan) - 1;
+    } else {
+        /* in CGA modes, multi_scan is ignored */
+        /* XXX: is it correct ? */
+        multi_scan = double_scan;
+    }
+    multi_run = multi_scan;
+    if (shift_control != s->shift_control ||
+        double_scan != s->double_scan) {
+        full_update = 1;
+        s->shift_control = shift_control;
+        s->double_scan = double_scan;
+    }
+    
+    if (shift_control == 0) {
+        full_update |= update_palette16(s);
+        if (s->sr[0x01] & 8) {
+            v = VGA_DRAW_LINE4D2;
+            disp_width <<= 1;
+        } else {
+            v = VGA_DRAW_LINE4;
+        }
+    } else if (shift_control == 1) {
+        full_update |= update_palette16(s);
+        if (s->sr[0x01] & 8) {
+            v = VGA_DRAW_LINE2D2;
+            disp_width <<= 1;
+        } else {
+            v = VGA_DRAW_LINE2;
+        }
+    } else {
+        switch(s->get_bpp(s)) {
+        default:
+        case 0:
+            full_update |= update_palette256(s);
+            v = VGA_DRAW_LINE8D2;
+            break;
+        case 8:
+            full_update |= update_palette256(s);
+            v = VGA_DRAW_LINE8;
+            break;
+        case 15:
+            v = VGA_DRAW_LINE15;
+            break;
+        case 16:
+            v = VGA_DRAW_LINE16;
+            break;
+        case 24:
+            v = VGA_DRAW_LINE24;
+            break;
+        case 32:
+            v = VGA_DRAW_LINE32;
+            break;
+        }
+    }
+    vga_draw_line = vga_draw_line_table[v * 4 + get_depth_index(s->ds->depth)];
+
+    if (disp_width != s->last_width ||
+        height != s->last_height) {
+        dpy_resize(s->ds, disp_width, height);
+        s->last_scr_width = disp_width;
+        s->last_scr_height = height;
+        s->last_width = disp_width;
+        s->last_height = height;
+        full_update = 1;
+    }
+    if (s->cursor_invalidate)
+        s->cursor_invalidate(s);
+    
+    line_offset = s->line_offset;
+#if 0
+    printf("w=%d h=%d v=%d line_offset=%d cr[0x09]=0x%02x cr[0x17]=0x%02x linecmp=%d sr[0x01]=0x%02x\n",
+           width, height, v, line_offset, s->cr[9], s->cr[0x17], s->line_compare, s->sr[0x01]);
+#endif
+    addr1 = (s->start_addr * 4);
+    bwidth = width * 4;
+    y_start = -1;
+    page_min = 0x7fffffff;
+    page_max = -1;
+    d = s->ds->data;
+    linesize = s->ds->linesize;
+    y1 = 0;
+    for(y = 0; y < height; y++) {
+        addr = addr1;
+        if (!(s->cr[0x17] & 1)) {
+            int shift;
+            /* CGA compatibility handling */
+            shift = 14 + ((s->cr[0x17] >> 6) & 1);
+            addr = (addr & ~(1 << shift)) | ((y1 & 1) << shift);
+        }
+        if (!(s->cr[0x17] & 2)) {
+            addr = (addr & ~0x8000) | ((y1 & 2) << 14);
+        }
+        page0 = s->vram_offset + (addr & TARGET_PAGE_MASK);
+        page1 = s->vram_offset + ((addr + bwidth - 1) & TARGET_PAGE_MASK);
+        update = full_update | cpu_physical_memory_is_dirty(page0) |
+            cpu_physical_memory_is_dirty(page1);
+        if ((page1 - page0) > TARGET_PAGE_SIZE) {
+            /* if wide line, can use another page */
+            update |= cpu_physical_memory_is_dirty(page0 + TARGET_PAGE_SIZE);
+        }
+        /* explicit invalidation for the hardware cursor */
+        update |= (s->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1;
+        if (update) {
+            if (y_start < 0)
+                y_start = y;
+            if (page0 < page_min)
+                page_min = page0;
+            if (page1 > page_max)
+                page_max = page1;
+            vga_draw_line(s, d, s->vram_ptr + addr, width);
+            if (s->cursor_draw_line)
+                s->cursor_draw_line(s, d, y);
+        } else {
+            if (y_start >= 0) {
+                /* flush to display */
+                dpy_update(s->ds, 0, y_start, 
+                           disp_width, y - y_start);
+                y_start = -1;
+            }
+        }
+        if (!multi_run) {
+            mask = (s->cr[0x17] & 3) ^ 3;
+            if ((y1 & mask) == mask)
+                addr1 += line_offset;
+            y1++;
+            multi_run = multi_scan;
+        } else {
+            multi_run--;
+        }
+        /* line compare acts on the displayed lines */
+        if (y == s->line_compare)
+            addr1 = 0;
+        d += linesize;
+    }
+    if (y_start >= 0) {
+        /* flush to display */
+        dpy_update(s->ds, 0, y_start, 
+                   disp_width, y - y_start);
+    }
+    /* reset modified pages */
+    if (page_max != -1) {
+        cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE);
+    }
+    memset(s->invalidated_y_table, 0, ((height + 31) >> 5) * 4);
+}
+
+static void vga_draw_blank(VGAState *s, int full_update)
+{
+    int i, w, val;
+    uint8_t *d;
+
+    if (!full_update)
+        return;
+    if (s->last_scr_width <= 0 || s->last_scr_height <= 0)
+        return;
+    if (s->ds->depth == 8) 
+        val = s->rgb_to_pixel(0, 0, 0);
+    else
+        val = 0;
+    w = s->last_scr_width * ((s->ds->depth + 7) >> 3);
+    d = s->ds->data;
+    for(i = 0; i < s->last_scr_height; i++) {
+        memset(d, val, w);
+        d += s->ds->linesize;
+    }
+    dpy_update(s->ds, 0, 0, 
+               s->last_scr_width, s->last_scr_height);
+}
+
+#define GMODE_TEXT     0
+#define GMODE_GRAPH    1
+#define GMODE_BLANK 2 
+
+void vga_update_display(void)
+{
+    VGAState *s = vga_state;
+    int full_update, graphic_mode;
+
+    if (s->ds->depth == 0) {
+        /* nothing to do */
+    } else {
+        switch(s->ds->depth) {
+        case 8:
+            s->rgb_to_pixel = rgb_to_pixel8_dup;
+            break;
+        case 15:
+            s->rgb_to_pixel = rgb_to_pixel15_dup;
+            break;
+        default:
+        case 16:
+            s->rgb_to_pixel = rgb_to_pixel16_dup;
+            break;
+        case 32:
+            s->rgb_to_pixel = rgb_to_pixel32_dup;
+            break;
+        }
+        
+        full_update = 0;
+        if (!(s->ar_index & 0x20)) {
+            graphic_mode = GMODE_BLANK;
+        } else {
+            graphic_mode = s->gr[6] & 1;
+        }
+        if (graphic_mode != s->graphic_mode) {
+            s->graphic_mode = graphic_mode;
+            full_update = 1;
+        }
+        switch(graphic_mode) {
+        case GMODE_TEXT:
+            vga_draw_text(s, full_update);
+            break;
+        case GMODE_GRAPH:
+            vga_draw_graphic(s, full_update);
+            break;
+        case GMODE_BLANK:
+        default:
+            vga_draw_blank(s, full_update);
+            break;
+        }
+    }
+}
+
+/* force a full display refresh */
+void vga_invalidate_display(void)
+{
+    VGAState *s = vga_state;
+    
+    s->last_width = -1;
+    s->last_height = -1;
+}
+
+static void vga_reset(VGAState *s)
+{
+    memset(s, 0, sizeof(VGAState));
+#ifdef CONFIG_S3VGA
+    /* chip ID for 8c968 */
+    s->cr[0x2d] = 0x88;
+    s->cr[0x2e] = 0xb0;
+    s->cr[0x2f] = 0x01; /* XXX: check revision code */
+    s->cr[0x30] = 0xe1;
+#endif
+    s->graphic_mode = -1; /* force full update */
+}
+
+static CPUReadMemoryFunc *vga_mem_read[3] = {
+    vga_mem_readb,
+    vga_mem_readw,
+    vga_mem_readl,
+};
+
+static CPUWriteMemoryFunc *vga_mem_write[3] = {
+    vga_mem_writeb,
+    vga_mem_writew,
+    vga_mem_writel,
+};
+
+static void vga_save(QEMUFile *f, void *opaque)
+{
+    VGAState *s = opaque;
+    int i;
+
+    qemu_put_be32s(f, &s->latch);
+    qemu_put_8s(f, &s->sr_index);
+    qemu_put_buffer(f, s->sr, 8);
+    qemu_put_8s(f, &s->gr_index);
+    qemu_put_buffer(f, s->gr, 16);
+    qemu_put_8s(f, &s->ar_index);
+    qemu_put_buffer(f, s->ar, 21);
+    qemu_put_be32s(f, &s->ar_flip_flop);
+    qemu_put_8s(f, &s->cr_index);
+    qemu_put_buffer(f, s->cr, 256);
+    qemu_put_8s(f, &s->msr);
+    qemu_put_8s(f, &s->fcr);
+    qemu_put_8s(f, &s->st00);
+    qemu_put_8s(f, &s->st01);
+
+    qemu_put_8s(f, &s->dac_state);
+    qemu_put_8s(f, &s->dac_sub_index);
+    qemu_put_8s(f, &s->dac_read_index);
+    qemu_put_8s(f, &s->dac_write_index);
+    qemu_put_buffer(f, s->dac_cache, 3);
+    qemu_put_buffer(f, s->palette, 768);
+
+    qemu_put_be32s(f, &s->bank_offset);
+#ifdef CONFIG_BOCHS_VBE
+    qemu_put_byte(f, 1);
+    qemu_put_be16s(f, &s->vbe_index);
+    for(i = 0; i < VBE_DISPI_INDEX_NB; i++)
+        qemu_put_be16s(f, &s->vbe_regs[i]);
+    qemu_put_be32s(f, &s->vbe_start_addr);
+    qemu_put_be32s(f, &s->vbe_line_offset);
+    qemu_put_be32s(f, &s->vbe_bank_mask);
+#else
+    qemu_put_byte(f, 0);
+#endif
+}
+
+static int vga_load(QEMUFile *f, void *opaque, int version_id)
+{
+    VGAState *s = opaque;
+    int is_vbe, i;
+
+    if (version_id != 1)
+        return -EINVAL;
+
+    qemu_get_be32s(f, &s->latch);
+    qemu_get_8s(f, &s->sr_index);
+    qemu_get_buffer(f, s->sr, 8);
+    qemu_get_8s(f, &s->gr_index);
+    qemu_get_buffer(f, s->gr, 16);
+    qemu_get_8s(f, &s->ar_index);
+    qemu_get_buffer(f, s->ar, 21);
+    qemu_get_be32s(f, &s->ar_flip_flop);
+    qemu_get_8s(f, &s->cr_index);
+    qemu_get_buffer(f, s->cr, 256);
+    qemu_get_8s(f, &s->msr);
+    qemu_get_8s(f, &s->fcr);
+    qemu_get_8s(f, &s->st00);
+    qemu_get_8s(f, &s->st01);
+
+    qemu_get_8s(f, &s->dac_state);
+    qemu_get_8s(f, &s->dac_sub_index);
+    qemu_get_8s(f, &s->dac_read_index);
+    qemu_get_8s(f, &s->dac_write_index);
+    qemu_get_buffer(f, s->dac_cache, 3);
+    qemu_get_buffer(f, s->palette, 768);
+
+    qemu_get_be32s(f, &s->bank_offset);
+    is_vbe = qemu_get_byte(f);
+#ifdef CONFIG_BOCHS_VBE
+    if (!is_vbe)
+        return -EINVAL;
+    qemu_get_be16s(f, &s->vbe_index);
+    for(i = 0; i < VBE_DISPI_INDEX_NB; i++)
+        qemu_get_be16s(f, &s->vbe_regs[i]);
+    qemu_get_be32s(f, &s->vbe_start_addr);
+    qemu_get_be32s(f, &s->vbe_line_offset);
+    qemu_get_be32s(f, &s->vbe_bank_mask);
+#else
+    if (is_vbe)
+        return -EINVAL;
+#endif
+
+    /* force refresh */
+    s->graphic_mode = -1;
+    return 0;
+}
+
+static void vga_map(PCIDevice *pci_dev, int region_num, 
+                    uint32_t addr, uint32_t size, int type)
+{
+    VGAState *s = vga_state;
+
+    cpu_register_physical_memory(addr, s->vram_size, s->vram_offset);
+}
+
+/* do the same job as vgabios before vgabios get ready */
+void vga_bios_init(VGAState *s)
+{
+    uint8_t palette_model[192] = {
+        0,   0,   0,   0,   0, 170,   0, 170,   0,   0, 170, 170, 170,   0,   0, 170,
+        0, 170, 170,  85,   0, 170, 170, 170,  85,  85,  85,  85,  85, 255,  85, 255,
+        85,  85, 255, 255, 255,  85,  85, 255,  85, 255, 255, 255,  85, 255, 255, 255,
+        0,  21,   0,   0,  21,  42,   0,  63,   0,   0,  63,  42,  42,  21,   0,  42,
+        21,  42,  42,  63,   0,  42,  63,  42,   0,  21,  21,   0,  21,  63,   0,  63, 
+        21,   0,  63,  63,  42,  21,  21,  42,  21,  63,  42,  63,  21,  42,  63,  63,
+        21,   0,   0,  21,   0,  42,  21,  42,   0,  21,  42,  42,  63,   0,   0,  63,
+        0,  42,  63,  42,   0,  63,  42,  42,  21,   0,  21,  21,   0,  63,  21,  42,
+        21,  21,  42,  63,  63,   0,  21,  63,   0,  63,  63,  42,  21,  63,  42,  63,
+        21,  21,   0,  21,  21,  42,  21,  63,   0,  21,  63,  42,  63,  21,   0,  63,
+        21,  42,  63,  63,   0,  63,  63,  42,  21,  21,  21,  21,  21,  63,  21,  63,
+        21,  21,  63,  63,  63,  21,  21,  63,  21,  63,  63,  63,  21,  63,  63,  63
+    };
+
+    s->latch =          0; 
+
+    s->sr_index =       3; 
+    s->sr[0] =          3;
+    s->sr[1] =          0;
+    s->sr[2] =          3;
+    s->sr[3] =          0;
+    s->sr[4] =          2;
+    s->sr[5] =          0;
+    s->sr[6] =          0;
+    s->sr[7] =          0;
+
+    s->gr_index =       5; 
+    s->gr[0] =          0;
+    s->gr[1] =          0;
+    s->gr[2] =          0;
+    s->gr[3] =          0;
+    s->gr[4] =          0;
+    s->gr[5] =          16;
+    s->gr[6] =          14;
+    s->gr[7] =          15;
+    s->gr[8] =          255;
+
+    /*changed by out 0x03c0*/
+    s->ar_index =       32;
+    s->ar[0] =          0;
+    s->ar[1] =          1;
+    s->ar[2] =          2;
+    s->ar[3] =          3;
+    s->ar[4] =          4;
+    s->ar[5] =          5;
+    s->ar[6] =          6;
+    s->ar[7] =          7;
+    s->ar[8] =          8;
+    s->ar[9] =          9;
+    s->ar[10] =         10;
+    s->ar[11] =         11;
+    s->ar[12] =         12;
+    s->ar[13] =         13;
+    s->ar[14] =         14;
+    s->ar[15] =         15;
+    s->ar[16] =         12;
+    s->ar[17] =         0;
+    s->ar[18] =         15;
+    s->ar[19] =         8;
+    s->ar[20] =         0;
+
+    s->ar_flip_flop =   1; 
+
+    s->cr_index =       15; 
+    s->cr[0] = 95;
+    s->cr[1] = 79;
+    s->cr[2] = 80;
+    s->cr[3] = 130;
+    s->cr[4] = 85;
+    s->cr[5] = 129;
+    s->cr[6] = 191;
+    s->cr[7] = 31;
+    s->cr[8] = 0;
+    s->cr[9] = 79;
+    s->cr[10] = 14;
+    s->cr[11] = 15;
+    s->cr[12] = 0;
+    s->cr[13] = 0;
+    s->cr[14] = 5;
+    s->cr[15] = 160;
+    s->cr[16] = 156;
+    s->cr[17] = 142;
+    s->cr[18] = 143;
+    s->cr[19] = 40;
+    s->cr[20] = 31;
+    s->cr[21] = 150;
+    s->cr[22] = 185;
+    s->cr[23] = 163;
+    s->cr[24] = 255;
+
+    s->msr = 103; 
+    s->fcr =   0; 
+    s->st00 =   0; 
+    s->st01 =   0; 
+
+    /*dac_* & platte will be initialized by os through out 0x03c8 & out 0c03c9(1:3) */
+    s->dac_state =   0; 
+    s->dac_sub_index =   0; 
+    s->dac_read_index =   0; 
+    s->dac_write_index =   16; 
+    s->dac_cache[0] =   255;
+    s->dac_cache[1] =   255;
+    s->dac_cache[2] =   255;
+
+    /*platte*/
+    memcpy(s->palette, palette_model, 192);
+
+    s->bank_offset=   0;
+    s->graphic_mode = -1;
+
+    /* TODO:add vbe support if enable it */
+
+    FILE *qemuf = fopen("/etc/xen/qemu-vgaram-bin", "rb");
+    if (!qemuf) {
+        fprintf(logfile, "open qemu vgaram binary failed!\n");
+    } else {
+        /*load vram contents, else vga console can't boot */
+        qemu_get_buffer(qemuf, s->vram_ptr, 256*1024);
+
+        fclose(qemuf);
+    }
+
+}
+
+void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base, 
+                     unsigned long vga_ram_offset, int vga_ram_size)
+{
+    int i, j, v, b;
+
+    for(i = 0;i < 256; i++) {
+        v = 0;
+        for(j = 0; j < 8; j++) {
+            v |= ((i >> j) & 1) << (j * 4);
+        }
+        expand4[i] = v;
+
+        v = 0;
+        for(j = 0; j < 4; j++) {
+            v |= ((i >> (2 * j)) & 3) << (j * 4);
+        }
+        expand2[i] = v;
+    }
+    for(i = 0; i < 16; i++) {
+        v = 0;
+        for(j = 0; j < 4; j++) {
+            b = ((i >> j) & 1);
+            v |= b << (2 * j);
+            v |= b << (2 * j + 1);
+        }
+        expand4to8[i] = v;
+    }
+
+    vga_reset(s);
+
+    /* qemu's vga mem is not detached from phys_ram_base and can cause DM abort
+     * when guest write vga mem, so allocate a new one */
+    s->vram_ptr = qemu_mallocz(256 * 1024);
+
+    s->vram_offset = vga_ram_offset;
+    s->vram_size = vga_ram_size;
+    s->ds = ds;
+    s->get_bpp = vga_get_bpp;
+    s->get_offsets = vga_get_offsets;
+    s->get_resolution = vga_get_resolution;
+    /* XXX: currently needed for display */
+    vga_state = s;
+}
+
+
+int vga_initialize(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base, 
+                   unsigned long vga_ram_offset, int vga_ram_size)
+{
+    VGAState *s;
+
+    s = qemu_mallocz(sizeof(VGAState));
+    if (!s)
+        return -1;
+
+    vga_common_init(s, ds, vga_ram_base, vga_ram_offset, vga_ram_size);
+
+    register_savevm("vga", 0, 1, vga_save, vga_load, s);
+
+    register_ioport_write(0x3c0, 16, 1, vga_ioport_write, s);
+
+    register_ioport_write(0x3b4, 2, 1, vga_ioport_write, s);
+    register_ioport_write(0x3d4, 2, 1, vga_ioport_write, s);
+    register_ioport_write(0x3ba, 1, 1, vga_ioport_write, s);
+    register_ioport_write(0x3da, 1, 1, vga_ioport_write, s);
+
+    register_ioport_read(0x3c0, 16, 1, vga_ioport_read, s);
+
+    register_ioport_read(0x3b4, 2, 1, vga_ioport_read, s);
+    register_ioport_read(0x3d4, 2, 1, vga_ioport_read, s);
+    register_ioport_read(0x3ba, 1, 1, vga_ioport_read, s);
+    register_ioport_read(0x3da, 1, 1, vga_ioport_read, s);
+    s->bank_offset = 0;
+
+#ifdef CONFIG_BOCHS_VBE
+    s->vbe_regs[VBE_DISPI_INDEX_ID] = VBE_DISPI_ID0;
+    s->vbe_bank_mask = ((s->vram_size >> 16) - 1);
+#if defined (TARGET_I386)
+    register_ioport_read(0x1ce, 1, 2, vbe_ioport_read_index, s);
+    register_ioport_read(0x1cf, 1, 2, vbe_ioport_read_data, s);
+
+    register_ioport_write(0x1ce, 1, 2, vbe_ioport_write_index, s);
+    register_ioport_write(0x1cf, 1, 2, vbe_ioport_write_data, s);
+
+    /* old Bochs IO ports */
+    register_ioport_read(0xff80, 1, 2, vbe_ioport_read_index, s);
+    register_ioport_read(0xff81, 1, 2, vbe_ioport_read_data, s);
+
+    register_ioport_write(0xff80, 1, 2, vbe_ioport_write_index, s);
+    register_ioport_write(0xff81, 1, 2, vbe_ioport_write_data, s); 
+#else
+    register_ioport_read(0x1ce, 1, 2, vbe_ioport_read_index, s);
+    register_ioport_read(0x1d0, 1, 2, vbe_ioport_read_data, s);
+
+    register_ioport_write(0x1ce, 1, 2, vbe_ioport_write_index, s);
+    register_ioport_write(0x1d0, 1, 2, vbe_ioport_write_data, s);
+#endif
+#endif /* CONFIG_BOCHS_VBE */
+
+    vga_io_memory = cpu_register_io_memory(0, vga_mem_read, vga_mem_write, s);
+    cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000, 
+                                 vga_io_memory);
+
+    if (bus) {
+        PCIDevice *d;
+        uint8_t *pci_conf;
+
+        d = pci_register_device(bus, "VGA", 
+                                sizeof(PCIDevice),
+                                -1, NULL, NULL);
+        pci_conf = d->config;
+        pci_conf[0x00] = 0x34; // dummy VGA (same as Bochs ID)
+        pci_conf[0x01] = 0x12;
+        pci_conf[0x02] = 0x11;
+        pci_conf[0x03] = 0x11;
+        pci_conf[0x0a] = 0x00; // VGA controller 
+        pci_conf[0x0b] = 0x03;
+        pci_conf[0x0e] = 0x00; // header_type
+
+        /* XXX: vga_ram_size must be a power of two */
+        pci_register_io_region(d, 0, vga_ram_size, 
+                               PCI_ADDRESS_SPACE_MEM_PREFETCH, vga_map);
+    } else {
+#ifdef CONFIG_BOCHS_VBE
+        /* XXX: use optimized standard vga accesses */
+        cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS, 
+                                     vga_ram_size, vga_ram_offset);
+#endif
+    }
+
+    vga_bios_init(s);
+    return 0;
+}
+
+/********************************************************/
+/* vga screen dump */
+
+static int vga_save_w, vga_save_h;
+
+static void vga_save_dpy_update(DisplayState *s, 
+                                int x, int y, int w, int h)
+{
+}
+
+static void vga_save_dpy_resize(DisplayState *s, int w, int h)
+{
+    s->linesize = w * 4;
+    s->data = qemu_malloc(h * s->linesize);
+    vga_save_w = w;
+    vga_save_h = h;
+}
+
+static void vga_save_dpy_refresh(DisplayState *s)
+{
+}
+
+static int ppm_save(const char *filename, uint8_t *data, 
+                    int w, int h, int linesize)
+{
+    FILE *f;
+    uint8_t *d, *d1;
+    unsigned int v;
+    int y, x;
+
+    f = fopen(filename, "wb");
+    if (!f)
+        return -1;
+    fprintf(f, "P6\n%d %d\n%d\n",
+            w, h, 255);
+    d1 = data;
+    for(y = 0; y < h; y++) {
+        d = d1;
+        for(x = 0; x < w; x++) {
+            v = *(uint32_t *)d;
+            fputc((v >> 16) & 0xff, f);
+            fputc((v >> 8) & 0xff, f);
+            fputc((v) & 0xff, f);
+            d += 4;
+        }
+        d1 += linesize;
+    }
+    fclose(f);
+    return 0;
+}
+
+/* save the vga display in a PPM image even if no display is
+   available */
+void vga_screen_dump(const char *filename)
+{
+    VGAState *s = vga_state;
+    DisplayState *saved_ds, ds1, *ds = &ds1;
+    
+    /* XXX: this is a little hackish */
+    vga_invalidate_display();
+    saved_ds = s->ds;
+
+    memset(ds, 0, sizeof(DisplayState));
+    ds->dpy_update = vga_save_dpy_update;
+    ds->dpy_resize = vga_save_dpy_resize;
+    ds->dpy_refresh = vga_save_dpy_refresh;
+    ds->depth = 32;
+
+    s->ds = ds;
+    s->graphic_mode = -1;
+    vga_update_display();
+    
+    if (ds->data) {
+        ppm_save(filename, ds->data, vga_save_w, vga_save_h, 
+                 s->ds->linesize);
+        qemu_free(ds->data);
+    }
+    s->ds = saved_ds;
+}
diff --git a/tools/ioemu/hw/vga_int.h b/tools/ioemu/hw/vga_int.h
new file mode 100644 (file)
index 0000000..3166882
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * QEMU internal VGA defines.
+ * 
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#define MSR_COLOR_EMULATION 0x01
+#define MSR_PAGE_SELECT     0x20
+
+#define ST01_V_RETRACE      0x08
+#define ST01_DISP_ENABLE    0x01
+
+/* bochs VBE support */
+//#define CONFIG_BOCHS_VBE
+
+#define VBE_DISPI_MAX_XRES              1024
+#define VBE_DISPI_MAX_YRES              768
+
+#define VBE_DISPI_INDEX_ID              0x0
+#define VBE_DISPI_INDEX_XRES            0x1
+#define VBE_DISPI_INDEX_YRES            0x2
+#define VBE_DISPI_INDEX_BPP             0x3
+#define VBE_DISPI_INDEX_ENABLE          0x4
+#define VBE_DISPI_INDEX_BANK            0x5
+#define VBE_DISPI_INDEX_VIRT_WIDTH      0x6
+#define VBE_DISPI_INDEX_VIRT_HEIGHT     0x7
+#define VBE_DISPI_INDEX_X_OFFSET        0x8
+#define VBE_DISPI_INDEX_Y_OFFSET        0x9
+#define VBE_DISPI_INDEX_NB              0xa
+      
+#define VBE_DISPI_ID0                   0xB0C0
+#define VBE_DISPI_ID1                   0xB0C1
+#define VBE_DISPI_ID2                   0xB0C2
+  
+#define VBE_DISPI_DISABLED              0x00
+#define VBE_DISPI_ENABLED               0x01
+#define VBE_DISPI_LFB_ENABLED           0x40
+#define VBE_DISPI_NOCLEARMEM            0x80
+  
+#define VBE_DISPI_LFB_PHYSICAL_ADDRESS  0xE0000000
+
+#ifdef CONFIG_BOCHS_VBE
+
+#define VGA_STATE_COMMON_BOCHS_VBE              \
+    uint16_t vbe_index;                         \
+    uint16_t vbe_regs[VBE_DISPI_INDEX_NB];      \
+    uint32_t vbe_start_addr;                    \
+    uint32_t vbe_line_offset;                   \
+    uint32_t vbe_bank_mask;
+
+#else
+
+#define VGA_STATE_COMMON_BOCHS_VBE
+
+#endif /* !CONFIG_BOCHS_VBE */
+
+#define CH_ATTR_SIZE (160 * 100)
+#define VGA_MAX_HEIGHT 1024
+
+#define VGA_STATE_COMMON                                                \
+    uint8_t *vram_ptr;                                                  \
+    unsigned long vram_offset;                                          \
+    unsigned int vram_size;                                             \
+    uint32_t latch;                                                     \
+    uint8_t sr_index;                                                   \
+    uint8_t sr[256];                                                    \
+    uint8_t gr_index;                                                   \
+    uint8_t gr[256];                                                    \
+    uint8_t ar_index;                                                   \
+    uint8_t ar[21];                                                     \
+    int ar_flip_flop;                                                   \
+    uint8_t cr_index;                                                   \
+    uint8_t cr[256]; /* CRT registers */                                \
+    uint8_t msr; /* Misc Output Register */                             \
+    uint8_t fcr; /* Feature Control Register */                         \
+    uint8_t st00; /* status 0 */                                        \
+    uint8_t st01; /* status 1 */                                        \
+    uint8_t dac_state;                                                  \
+    uint8_t dac_sub_index;                                              \
+    uint8_t dac_read_index;                                             \
+    uint8_t dac_write_index;                                            \
+    uint8_t dac_cache[3]; /* used when writing */                       \
+    uint8_t palette[768];                                               \
+    int32_t bank_offset;                                                \
+    int (*get_bpp)(struct VGAState *s);                                 \
+    void (*get_offsets)(struct VGAState *s,                             \
+                        uint32_t *pline_offset,                         \
+                        uint32_t *pstart_addr);                         \
+    void (*get_resolution)(struct VGAState *s,                          \
+                        int *pwidth,                                    \
+                        int *pheight);                                  \
+    VGA_STATE_COMMON_BOCHS_VBE                                          \
+    /* display refresh support */                                       \
+    DisplayState *ds;                                                   \
+    uint32_t font_offsets[2];                                           \
+    int graphic_mode;                                                   \
+    uint8_t shift_control;                                              \
+    uint8_t double_scan;                                                \
+    uint32_t line_offset;                                               \
+    uint32_t line_compare;                                              \
+    uint32_t start_addr;                                                \
+    uint32_t plane_updated;                                             \
+    uint8_t last_cw, last_ch;                                           \
+    uint32_t last_width, last_height; /* in chars or pixels */          \
+    uint32_t last_scr_width, last_scr_height; /* in pixels */           \
+    uint8_t cursor_start, cursor_end;                                   \
+    uint32_t cursor_offset;                                             \
+    unsigned int (*rgb_to_pixel)(unsigned int r,                        \
+                                 unsigned int g, unsigned b);           \
+    /* hardware mouse cursor support */                                 \
+    uint32_t invalidated_y_table[VGA_MAX_HEIGHT / 32];                  \
+    void (*cursor_invalidate)(struct VGAState *s);                      \
+    void (*cursor_draw_line)(struct VGAState *s, uint8_t *d, int y);    \
+    /* tell for each page if it has been updated since the last time */ \
+    uint32_t last_palette[256];                                         \
+    uint32_t last_ch_attr[CH_ATTR_SIZE]; /* XXX: make it dynamic */
+
+
+typedef struct VGAState {
+    VGA_STATE_COMMON
+} VGAState;
+
+static inline int c6_to_8(int v)
+{
+    int b;
+    v &= 0x3f;
+    b = v & 1;
+    return (v << 2) | (b << 1) | b;
+}
+
+void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base, 
+                     unsigned long vga_ram_offset, int vga_ram_size);
+uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr);
+void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val);
+void vga_invalidate_scanlines(VGAState *s, int y1, int y2);
+
+void vga_draw_cursor_line_8(uint8_t *d1, const uint8_t *src1, 
+                            int poffset, int w, 
+                            unsigned int color0, unsigned int color1,
+                            unsigned int color_xor);
+void vga_draw_cursor_line_16(uint8_t *d1, const uint8_t *src1, 
+                             int poffset, int w, 
+                             unsigned int color0, unsigned int color1,
+                             unsigned int color_xor);
+void vga_draw_cursor_line_32(uint8_t *d1, const uint8_t *src1, 
+                             int poffset, int w, 
+                             unsigned int color0, unsigned int color1,
+                             unsigned int color_xor);
+
+extern const uint8_t sr_mask[8];
+extern const uint8_t gr_mask[16];
diff --git a/tools/ioemu/hw/vga_template.h b/tools/ioemu/hw/vga_template.h
new file mode 100644 (file)
index 0000000..909571e
--- /dev/null
@@ -0,0 +1,519 @@
+/*
+ * QEMU VGA Emulator templates
+ * 
+ * Copyright (c) 2003 Fabrice Bellard
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#if DEPTH == 8
+#define BPP 1
+#define PIXEL_TYPE uint8_t 
+#elif DEPTH == 15 || DEPTH == 16
+#define BPP 2
+#define PIXEL_TYPE uint16_t 
+#elif DEPTH == 32
+#define BPP 4
+#define PIXEL_TYPE uint32_t 
+#else
+#error unsupport depth
+#endif
+
+#if DEPTH != 15
+
+static inline void glue(vga_draw_glyph_line_, DEPTH)(uint8_t *d, 
+                                                     uint32_t font_data,
+                                                     uint32_t xorcol, 
+                                                     uint32_t bgcol)
+{
+#if BPP == 1
+        ((uint32_t *)d)[0] = (dmask16[(font_data >> 4)] & xorcol) ^ bgcol;
+        ((uint32_t *)d)[1] = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol;
+#elif BPP == 2
+        ((uint32_t *)d)[0] = (dmask4[(font_data >> 6)] & xorcol) ^ bgcol;
+        ((uint32_t *)d)[1] = (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol;
+        ((uint32_t *)d)[2] = (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol;
+        ((uint32_t *)d)[3] = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol;
+#else
+        ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol;
+        ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol;
+        ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol;
+        ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol;
+        ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol;
+        ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol;
+        ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol;
+        ((uint32_t *)d)[7] = (-((font_data >> 0) & 1) & xorcol) ^ bgcol;
+#endif
+}
+
+static void glue(vga_draw_glyph8_, DEPTH)(uint8_t *d, int linesize,
+                                          const uint8_t *font_ptr, int h,
+                                          uint32_t fgcol, uint32_t bgcol)
+{
+    uint32_t font_data, xorcol;
+    
+    xorcol = bgcol ^ fgcol;
+    do {
+        font_data = font_ptr[0];
+        glue(vga_draw_glyph_line_, DEPTH)(d, font_data, xorcol, bgcol);
+        font_ptr += 4;
+        d += linesize;
+    } while (--h);
+}
+
+static void glue(vga_draw_glyph16_, DEPTH)(uint8_t *d, int linesize,
+                                          const uint8_t *font_ptr, int h,
+                                          uint32_t fgcol, uint32_t bgcol)
+{
+    uint32_t font_data, xorcol;
+    
+    xorcol = bgcol ^ fgcol;
+    do {
+        font_data = font_ptr[0];
+        glue(vga_draw_glyph_line_, DEPTH)(d, 
+                                          expand4to8[font_data >> 4], 
+                                          xorcol, bgcol);
+        glue(vga_draw_glyph_line_, DEPTH)(d + 8 * BPP, 
+                                          expand4to8[font_data & 0x0f], 
+                                          xorcol, bgcol);
+        font_ptr += 4;
+        d += linesize;
+    } while (--h);
+}
+
+static void glue(vga_draw_glyph9_, DEPTH)(uint8_t *d, int linesize,
+                                          const uint8_t *font_ptr, int h, 
+                                          uint32_t fgcol, uint32_t bgcol, int dup9)
+{
+    uint32_t font_data, xorcol, v;
+    
+    xorcol = bgcol ^ fgcol;
+    do {
+        font_data = font_ptr[0];
+#if BPP == 1
+        cpu_to_32wu((uint32_t *)d, (dmask16[(font_data >> 4)] & xorcol) ^ bgcol);
+        v = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol;
+        cpu_to_32wu(((uint32_t *)d)+1, v);
+        if (dup9)
+            ((uint8_t *)d)[8] = v >> (24 * (1 - BIG));
+        else
+            ((uint8_t *)d)[8] = bgcol;
+        
+#elif BPP == 2
+        cpu_to_32wu(((uint32_t *)d)+0, (dmask4[(font_data >> 6)] & xorcol) ^ bgcol);
+        cpu_to_32wu(((uint32_t *)d)+1, (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol);
+        cpu_to_32wu(((uint32_t *)d)+2, (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol);
+        v = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol;
+        cpu_to_32wu(((uint32_t *)d)+3, v);
+        if (dup9)
+            ((uint16_t *)d)[8] = v >> (16 * (1 - BIG));
+        else
+            ((uint16_t *)d)[8] = bgcol;
+#else
+        ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol;
+        ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol;
+        ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol;
+        ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol;
+        ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol;
+        ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol;
+        ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol;
+        v = (-((font_data >> 0) & 1) & xorcol) ^ bgcol;
+        ((uint32_t *)d)[7] = v;
+        if (dup9)
+            ((uint32_t *)d)[8] = v;
+        else
+            ((uint32_t *)d)[8] = bgcol;
+#endif
+        font_ptr += 4;
+        d += linesize;
+    } while (--h);
+}
+
+/* 
+ * 4 color mode
+ */
+static void glue(vga_draw_line2_, DEPTH)(VGAState *s1, uint8_t *d, 
+                                         const uint8_t *s, int width)
+{
+    uint32_t plane_mask, *palette, data, v;
+    int x;
+
+    palette = s1->last_palette;
+    plane_mask = mask16[s1->ar[0x12] & 0xf];
+    width >>= 3;
+    for(x = 0; x < width; x++) {
+        data = ((uint32_t *)s)[0];
+        data &= plane_mask;
+        v = expand2[GET_PLANE(data, 0)];
+        v |= expand2[GET_PLANE(data, 2)] << 2;
+        ((PIXEL_TYPE *)d)[0] = palette[v >> 12];
+        ((PIXEL_TYPE *)d)[1] = palette[(v >> 8) & 0xf];
+        ((PIXEL_TYPE *)d)[2] = palette[(v >> 4) & 0xf];
+        ((PIXEL_TYPE *)d)[3] = palette[(v >> 0) & 0xf];
+
+        v = expand2[GET_PLANE(data, 1)];
+        v |= expand2[GET_PLANE(data, 3)] << 2;
+        ((PIXEL_TYPE *)d)[4] = palette[v >> 12];
+        ((PIXEL_TYPE *)d)[5] = palette[(v >> 8) & 0xf];
+        ((PIXEL_TYPE *)d)[6] = palette[(v >> 4) & 0xf];
+        ((PIXEL_TYPE *)d)[7] = palette[(v >> 0) & 0xf];
+        d += BPP * 8;
+        s += 4;
+    }
+}
+
+#if BPP == 1
+#define PUT_PIXEL2(d, n, v) ((uint16_t *)d)[(n)] = (v)
+#elif BPP == 2
+#define PUT_PIXEL2(d, n, v) ((uint32_t *)d)[(n)] = (v)
+#else
+#define PUT_PIXEL2(d, n, v) \
+((uint32_t *)d)[2*(n)] = ((uint32_t *)d)[2*(n)+1] = (v)
+#endif
+
+/* 
+ * 4 color mode, dup2 horizontal
+ */
+static void glue(vga_draw_line2d2_, DEPTH)(VGAState *s1, uint8_t *d, 
+                                           const uint8_t *s, int width)
+{
+    uint32_t plane_mask, *palette, data, v;
+    int x;
+
+    palette = s1->last_palette;
+    plane_mask = mask16[s1->ar[0x12] & 0xf];
+    width >>= 3;
+    for(x = 0; x < width; x++) {
+        data = ((uint32_t *)s)[0];
+        data &= plane_mask;
+        v = expand2[GET_PLANE(data, 0)];
+        v |= expand2[GET_PLANE(data, 2)] << 2;
+        PUT_PIXEL2(d, 0, palette[v >> 12]);
+        PUT_PIXEL2(d, 1, palette[(v >> 8) & 0xf]);
+        PUT_PIXEL2(d, 2, palette[(v >> 4) & 0xf]);
+        PUT_PIXEL2(d, 3, palette[(v >> 0) & 0xf]);
+
+        v = expand2[GET_PLANE(data, 1)];
+        v |= expand2[GET_PLANE(data, 3)] << 2;
+        PUT_PIXEL2(d, 4, palette[v >> 12]);
+        PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]);
+        PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
+        PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
+        d += BPP * 16;
+        s += 4;
+    }
+}
+
+/* 
+ * 16 color mode
+ */
+static void glue(vga_draw_line4_, DEPTH)(VGAState *s1, uint8_t *d, 
+                                         const uint8_t *s, int width)
+{
+    uint32_t plane_mask, data, v, *palette;
+    int x;
+
+    palette = s1->last_palette;
+    plane_mask = mask16[s1->ar[0x12] & 0xf];
+    width >>= 3;
+    for(x = 0; x < width; x++) {
+        data = ((uint32_t *)s)[0];
+        data &= plane_mask;
+        v = expand4[GET_PLANE(data, 0)];
+        v |= expand4[GET_PLANE(data, 1)] << 1;
+        v |= expand4[GET_PLANE(data, 2)] << 2;
+        v |= expand4[GET_PLANE(data, 3)] << 3;
+        ((PIXEL_TYPE *)d)[0] = palette[v >> 28];
+        ((PIXEL_TYPE *)d)[1] = palette[(v >> 24) & 0xf];
+        ((PIXEL_TYPE *)d)[2] = palette[(v >> 20) & 0xf];
+        ((PIXEL_TYPE *)d)[3] = palette[(v >> 16) & 0xf];
+        ((PIXEL_TYPE *)d)[4] = palette[(v >> 12) & 0xf];
+        ((PIXEL_TYPE *)d)[5] = palette[(v >> 8) & 0xf];
+        ((PIXEL_TYPE *)d)[6] = palette[(v >> 4) & 0xf];
+        ((PIXEL_TYPE *)d)[7] = palette[(v >> 0) & 0xf];
+        d += BPP * 8;
+        s += 4;
+    }
+}
+
+/* 
+ * 16 color mode, dup2 horizontal
+ */
+static void glue(vga_draw_line4d2_, DEPTH)(VGAState *s1, uint8_t *d, 
+                                           const uint8_t *s, int width)
+{
+    uint32_t plane_mask, data, v, *palette;
+    int x;
+
+    palette = s1->last_palette;
+    plane_mask = mask16[s1->ar[0x12] & 0xf];
+    width >>= 3;
+    for(x = 0; x < width; x++) {
+        data = ((uint32_t *)s)[0];
+        data &= plane_mask;
+        v = expand4[GET_PLANE(data, 0)];
+        v |= expand4[GET_PLANE(data, 1)] << 1;
+        v |= expand4[GET_PLANE(data, 2)] << 2;
+        v |= expand4[GET_PLANE(data, 3)] << 3;
+        PUT_PIXEL2(d, 0, palette[v >> 28]);
+        PUT_PIXEL2(d, 1, palette[(v >> 24) & 0xf]);
+        PUT_PIXEL2(d, 2, palette[(v >> 20) & 0xf]);
+        PUT_PIXEL2(d, 3, palette[(v >> 16) & 0xf]);
+        PUT_PIXEL2(d, 4, palette[(v >> 12) & 0xf]);
+        PUT_PIXEL2(d, 5, palette[(v >> 8) & 0xf]);
+        PUT_PIXEL2(d, 6, palette[(v >> 4) & 0xf]);
+        PUT_PIXEL2(d, 7, palette[(v >> 0) & 0xf]);
+        d += BPP * 16;
+        s += 4;
+    }
+}
+
+/* 
+ * 256 color mode, double pixels
+ *
+ * XXX: add plane_mask support (never used in standard VGA modes)
+ */
+static void glue(vga_draw_line8d2_, DEPTH)(VGAState *s1, uint8_t *d, 
+                                           const uint8_t *s, int width)
+{
+    uint32_t *palette;
+    int x;
+
+    palette = s1->last_palette;
+    width >>= 3;
+    for(x = 0; x < width; x++) {
+        PUT_PIXEL2(d, 0, palette[s[0]]);
+        PUT_PIXEL2(d, 1, palette[s[1]]);
+        PUT_PIXEL2(d, 2, palette[s[2]]);
+        PUT_PIXEL2(d, 3, palette[s[3]]);
+        d += BPP * 8;
+        s += 4;
+    }
+}
+
+/* 
+ * standard 256 color mode
+ *
+ * XXX: add plane_mask support (never used in standard VGA modes)
+ */
+static void glue(vga_draw_line8_, DEPTH)(VGAState *s1, uint8_t *d, 
+                                         const uint8_t *s, int width)
+{
+    uint32_t *palette;
+    int x;
+
+    palette = s1->last_palette;
+    width >>= 3;
+    for(x = 0; x < width; x++) {
+        ((PIXEL_TYPE *)d)[0] = palette[s[0]];
+        ((PIXEL_TYPE *)d)[1] = palette[s[1]];
+        ((PIXEL_TYPE *)d)[2] = palette[s[2]];
+        ((PIXEL_TYPE *)d)[3] = palette[s[3]];
+        ((PIXEL_TYPE *)d)[4] = palette[s[4]];
+        ((PIXEL_TYPE *)d)[5] = palette[s[5]];
+        ((PIXEL_TYPE *)d)[6] = palette[s[6]];
+        ((PIXEL_TYPE *)d)[7] = palette[s[7]];
+        d += BPP * 8;
+        s += 8;
+    }
+}
+
+#endif /* DEPTH != 15 */
+
+
+/* XXX: optimize */
+
+/* 
+ * 15 bit color
+ */
+static void glue(vga_draw_line15_, DEPTH)(VGAState *s1, uint8_t *d, 
+                                          const uint8_t *s, int width)
+{
+#if DEPTH == 15 && defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
+    memcpy(d, s, width * 2);
+#else
+    int w;
+    uint32_t v, r, g, b;
+
+    w = width;
+    do {
+        v = lduw_raw((void *)s);
+        r = (v >> 7) & 0xf8;
+        g = (v >> 2) & 0xf8;
+        b = (v << 3) & 0xf8;
+        ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
+        s += 2;
+        d += BPP;
+    } while (--w != 0);
+#endif    
+}
+
+/* 
+ * 16 bit color
+ */
+static void glue(vga_draw_line16_, DEPTH)(VGAState *s1, uint8_t *d, 
+                                          const uint8_t *s, int width)
+{
+#if DEPTH == 16 && defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
+    memcpy(d, s, width * 2);
+#else
+    int w;
+    uint32_t v, r, g, b;
+
+    w = width;
+    do {
+        v = lduw_raw((void *)s);
+        r = (v >> 8) & 0xf8;
+        g = (v >> 3) & 0xfc;
+        b = (v << 3) & 0xf8;
+        ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
+        s += 2;
+        d += BPP;
+    } while (--w != 0);
+#endif    
+}
+
+/* 
+ * 24 bit color
+ */
+static void glue(vga_draw_line24_, DEPTH)(VGAState *s1, uint8_t *d, 
+                                          const uint8_t *s, int width)
+{
+    int w;
+    uint32_t r, g, b;
+
+    w = width;
+    do {
+#if defined(TARGET_WORDS_BIGENDIAN)
+        r = s[0];
+        g = s[1];
+        b = s[2];
+#else
+        b = s[0];
+        g = s[1];
+        r = s[2];
+#endif
+        ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
+        s += 3;
+        d += BPP;
+    } while (--w != 0);
+}
+
+/* 
+ * 32 bit color
+ */
+static void glue(vga_draw_line32_, DEPTH)(VGAState *s1, uint8_t *d, 
+                                          const uint8_t *s, int width)
+{
+#if DEPTH == 32 && defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
+    memcpy(d, s, width * 4);
+#else
+    int w;
+    uint32_t r, g, b;
+
+    w = width;
+    do {
+#if defined(TARGET_WORDS_BIGENDIAN)
+        r = s[1];
+        g = s[2];
+        b = s[3];
+#else
+        b = s[0];
+        g = s[1];
+        r = s[2];
+#endif
+        ((PIXEL_TYPE *)d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
+        s += 4;
+        d += BPP;
+    } while (--w != 0);
+#endif
+}
+
+#if DEPTH != 15
+void glue(vga_draw_cursor_line_, DEPTH)(uint8_t *d1, 
+                                        const uint8_t *src1, 
+                                        int poffset, int w,
+                                        unsigned int color0, 
+                                        unsigned int color1,
+                                        unsigned int color_xor)
+{
+    const uint8_t *plane0, *plane1;
+    int x, b0, b1;
+    uint8_t *d;
+
+    d = d1;
+    plane0 = src1;
+    plane1 = src1 + poffset;
+    for(x = 0; x < w; x++) {
+        b0 = (plane0[x >> 3] >> (7 - (x & 7))) & 1;
+        b1 = (plane1[x >> 3] >> (7 - (x & 7))) & 1;
+#if DEPTH == 8
+        switch(b0 | (b1 << 1)) {
+        case 0:
+            break;
+        case 1:
+            d[0] ^= color_xor;
+            break;
+        case 2:
+            d[0] = color0;
+            break;
+        case 3:
+            d[0] = color1;
+            break;
+        }
+#elif DEPTH == 16
+        switch(b0 | (b1 << 1)) {
+        case 0:
+            break;
+        case 1:
+            ((uint16_t *)d)[0] ^= color_xor;
+            break;
+        case 2:
+            ((uint16_t *)d)[0] = color0;
+            break;
+        case 3:
+            ((uint16_t *)d)[0] = color1;
+            break;
+        }
+#elif DEPTH == 32
+        switch(b0 | (b1 << 1)) {
+        case 0:
+            break;
+        case 1:
+            ((uint32_t *)d)[0] ^= color_xor;
+            break;
+        case 2:
+            ((uint32_t *)d)[0] = color0;
+            break;
+        case 3:
+            ((uint32_t *)d)[0] = color1;
+            break;
+        }
+#else
+#error unsupported depth
+#endif
+        d += BPP;
+    }
+}
+#endif
+
+#undef PUT_PIXEL2
+#undef DEPTH
+#undef BPP
+#undef PIXEL_TYPE
diff --git a/tools/ioemu/i386-vl.ld b/tools/ioemu/i386-vl.ld
new file mode 100644 (file)
index 0000000..428fe83
--- /dev/null
@@ -0,0 +1,140 @@
+/* ld script to make i386 Linux kernel
+ * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
+ */
+OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
+OUTPUT_ARCH(i386)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/alpha-unknown-linux-gnu/lib);
+ENTRY(_start)
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  . = 0xa8000000 + SIZEOF_HEADERS;
+  .interp     : { *(.interp)   }
+  .hash          : { *(.hash)          }
+  .dynsym        : { *(.dynsym)                }
+  .dynstr        : { *(.dynstr)                }
+  .gnu.version   : { *(.gnu.version)   }
+  .gnu.version_d   : { *(.gnu.version_d)       }
+  .gnu.version_r   : { *(.gnu.version_r)       }
+  .rel.text      :
+    { *(.rel.text) *(.rel.gnu.linkonce.t*) }
+  .rela.text     :
+    { *(.rela.text) *(.rela.gnu.linkonce.t*) }
+  .rel.data      :
+    { *(.rel.data) *(.rel.gnu.linkonce.d*) }
+  .rela.data     :
+    { *(.rela.data) *(.rela.gnu.linkonce.d*) }
+  .rel.rodata    :
+    { *(.rel.rodata) *(.rel.gnu.linkonce.r*) }
+  .rela.rodata   :
+    { *(.rela.rodata) *(.rela.gnu.linkonce.r*) }
+  .rel.got       : { *(.rel.got)               }
+  .rela.got      : { *(.rela.got)              }
+  .rel.ctors     : { *(.rel.ctors)     }
+  .rela.ctors    : { *(.rela.ctors)    }
+  .rel.dtors     : { *(.rel.dtors)     }
+  .rela.dtors    : { *(.rela.dtors)    }
+  .rel.init      : { *(.rel.init)      }
+  .rela.init     : { *(.rela.init)     }
+  .rel.fini      : { *(.rel.fini)      }
+  .rela.fini     : { *(.rela.fini)     }
+  .rel.bss       : { *(.rel.bss)               }
+  .rela.bss      : { *(.rela.bss)              }
+  .rel.plt       : { *(.rel.plt)               }
+  .rela.plt      : { *(.rela.plt)              }
+  .init          : { *(.init)  } =0x47ff041f
+  .text      :
+  {
+    *(.text)
+    /* .gnu.warning sections are handled specially by elf32.em.  */
+    *(.gnu.warning)
+    *(.gnu.linkonce.t*)
+  } =0x47ff041f
+  _etext = .;
+  PROVIDE (etext = .);
+  .fini      : { *(.fini)    } =0x47ff041f
+  .rodata    : { *(.rodata) *(.gnu.linkonce.r*) }
+  .rodata1   : { *(.rodata1) }
+  .reginfo : { *(.reginfo) }
+  __preinit_array_start = .;
+  .preinit_array : { *(.preinit_array) }
+  __preinit_array_end = .;
+  __init_array_start = .;
+  .init_array : { *(.init_array) }
+  __init_array_end = .;
+  __fini_array_start = .;
+  .fini_array : { *(.fini_array) }
+  __fini_array_end = .;
+
+  /* Adjust the address for the data segment.  We want to adjust up to
+     the same address within the page on the next page up.  */
+  . = ALIGN(0x100000) + (. & (0x100000 - 1));
+  .data    :
+  {
+    *(.data)
+    *(.gnu.linkonce.d*)
+    CONSTRUCTORS
+  }
+  .data1   : { *(.data1) }
+  .ctors         :
+  {
+    *(.ctors)
+  }
+  .dtors         :
+  {
+    *(.dtors)
+  }
+  .plt      : { *(.plt)        }
+  .got           : { *(.got.plt) *(.got) }
+  .dynamic       : { *(.dynamic) }
+  /* We want the small data sections together, so single-instruction offsets
+     can access them all, and initialized data all before uninitialized, so
+     we can shorten the on-disk segment size.  */
+  .sdata     : { *(.sdata) }
+  _edata  =  .;
+  PROVIDE (edata = .);
+  __bss_start = .;
+  .sbss      : { *(.sbss) *(.scommon) }
+  .bss       :
+  {
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+  }
+  _end = . ;
+  PROVIDE (end = .);
+  /* Stabs debugging sections.  */
+  .stab 0 : { *(.stab) }
+  .stabstr 0 : { *(.stabstr) }
+  .stab.excl 0 : { *(.stab.excl) }
+  .stab.exclstr 0 : { *(.stab.exclstr) }
+  .stab.index 0 : { *(.stab.index) }
+  .stab.indexstr 0 : { *(.stab.indexstr) }
+  .comment 0 : { *(.comment) }
+  /* DWARF debug sections.
+     Symbols in the DWARF debugging sections are relative to the beginning
+     of the section so we begin them at 0.  */
+  /* DWARF 1 */
+  .debug          0 : { *(.debug) }
+  .line           0 : { *(.line) }
+  /* GNU DWARF 1 extensions */
+  .debug_srcinfo  0 : { *(.debug_srcinfo) }
+  .debug_sfnames  0 : { *(.debug_sfnames) }
+  /* DWARF 1.1 and DWARF 2 */
+  .debug_aranges  0 : { *(.debug_aranges) }
+  .debug_pubnames 0 : { *(.debug_pubnames) }
+  /* DWARF 2 */
+  .debug_info     0 : { *(.debug_info) }
+  .debug_abbrev   0 : { *(.debug_abbrev) }
+  .debug_line     0 : { *(.debug_line) }
+  .debug_frame    0 : { *(.debug_frame) }
+  .debug_str      0 : { *(.debug_str) }
+  .debug_loc      0 : { *(.debug_loc) }
+  .debug_macinfo  0 : { *(.debug_macinfo) }
+  /* SGI/MIPS DWARF 2 extensions */
+  .debug_weaknames 0 : { *(.debug_weaknames) }
+  .debug_funcnames 0 : { *(.debug_funcnames) }
+  .debug_typenames 0 : { *(.debug_typenames) }
+  .debug_varnames  0 : { *(.debug_varnames) }
+  /* These must appear regardless of  .  */
+}
diff --git a/tools/ioemu/i386.ld b/tools/ioemu/i386.ld
new file mode 100644 (file)
index 0000000..d41c626
--- /dev/null
@@ -0,0 +1,140 @@
+/* ld script to make i386 Linux kernel
+ * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
+ */
+OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
+OUTPUT_ARCH(i386)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/alpha-unknown-linux-gnu/lib);
+ENTRY(_start)
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  . = 0x60000000 + SIZEOF_HEADERS;
+  .interp     : { *(.interp)   }
+  .hash          : { *(.hash)          }
+  .dynsym        : { *(.dynsym)                }
+  .dynstr        : { *(.dynstr)                }
+  .gnu.version   : { *(.gnu.version)   }
+  .gnu.version_d   : { *(.gnu.version_d)       }
+  .gnu.version_r   : { *(.gnu.version_r)       }
+  .rel.text      :
+    { *(.rel.text) *(.rel.gnu.linkonce.t*) }
+  .rela.text     :
+    { *(.rela.text) *(.rela.gnu.linkonce.t*) }
+  .rel.data      :
+    { *(.rel.data) *(.rel.gnu.linkonce.d*) }
+  .rela.data     :
+    { *(.rela.data) *(.rela.gnu.linkonce.d*) }
+  .rel.rodata    :
+    { *(.rel.rodata) *(.rel.gnu.linkonce.r*) }
+  .rela.rodata   :
+    { *(.rela.rodata) *(.rela.gnu.linkonce.r*) }
+  .rel.got       : { *(.rel.got)               }
+  .rela.got      : { *(.rela.got)              }
+  .rel.ctors     : { *(.rel.ctors)     }
+  .rela.ctors    : { *(.rela.ctors)    }
+  .rel.dtors     : { *(.rel.dtors)     }
+  .rela.dtors    : { *(.rela.dtors)    }
+  .rel.init      : { *(.rel.init)      }
+  .rela.init     : { *(.rela.init)     }
+  .rel.fini      : { *(.rel.fini)      }
+  .rela.fini     : { *(.rela.fini)     }
+  .rel.bss       : { *(.rel.bss)               }
+  .rela.bss      : { *(.rela.bss)              }
+  .rel.plt       : { *(.rel.plt)               }
+  .rela.plt      : { *(.rela.plt)              }
+  .init          : { *(.init)  } =0x47ff041f
+  .text      :
+  {
+    *(.text)
+    /* .gnu.warning sections are handled specially by elf32.em.  */
+    *(.gnu.warning)
+    *(.gnu.linkonce.t*)
+  } =0x47ff041f
+  _etext = .;
+  PROVIDE (etext = .);
+  .fini      : { *(.fini)    } =0x47ff041f
+  . = ALIGN(32 / 8);
+  PROVIDE (__preinit_array_start = .);
+  .preinit_array     : { *(.preinit_array) }
+  PROVIDE (__preinit_array_end = .);
+  PROVIDE (__init_array_start = .);
+  .init_array     : { *(.init_array) }
+  PROVIDE (__init_array_end = .);
+  PROVIDE (__fini_array_start = .);
+  .fini_array     : { *(.fini_array) }
+  PROVIDE (__fini_array_end = .);
+  .rodata    : { *(.rodata) *(.gnu.linkonce.r*) }
+  .rodata1   : { *(.rodata1) }
+  .reginfo : { *(.reginfo) }
+  /* Adjust the address for the data segment.  We want to adjust up to
+     the same address within the page on the next page up.  */
+  . = ALIGN(0x100000) + (. & (0x100000 - 1));
+  .data    :
+  {
+    *(.data)
+    *(.gnu.linkonce.d*)
+    CONSTRUCTORS
+  }
+  .data1   : { *(.data1) }
+  .ctors         :
+  {
+    *(.ctors)
+  }
+  .dtors         :
+  {
+    *(.dtors)
+  }
+  .plt      : { *(.plt)        }
+  .got           : { *(.got.plt) *(.got) }
+  .dynamic       : { *(.dynamic) }
+  /* We want the small data sections together, so single-instruction offsets
+     can access them all, and initialized data all before uninitialized, so
+     we can shorten the on-disk segment size.  */
+  .sdata     : { *(.sdata) }
+  _edata  =  .;
+  PROVIDE (edata = .);
+  __bss_start = .;
+  .sbss      : { *(.sbss) *(.scommon) }
+  .bss       :
+  {
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+  }
+  _end = . ;
+  PROVIDE (end = .);
+  /* Stabs debugging sections.  */
+  .stab 0 : { *(.stab) }
+  .stabstr 0 : { *(.stabstr) }
+  .stab.excl 0 : { *(.stab.excl) }
+  .stab.exclstr 0 : { *(.stab.exclstr) }
+  .stab.index 0 : { *(.stab.index) }
+  .stab.indexstr 0 : { *(.stab.indexstr) }
+  .comment 0 : { *(.comment) }
+  /* DWARF debug sections.
+     Symbols in the DWARF debugging sections are relative to the beginning
+     of the section so we begin them at 0.  */
+  /* DWARF 1 */
+  .debug          0 : { *(.debug) }
+  .line           0 : { *(.line) }
+  /* GNU DWARF 1 extensions */
+  .debug_srcinfo  0 : { *(.debug_srcinfo) }
+  .debug_sfnames  0 : { *(.debug_sfnames) }
+  /* DWARF 1.1 and DWARF 2 */
+  .debug_aranges  0 : { *(.debug_aranges) }
+  .debug_pubnames 0 : { *(.debug_pubnames) }
+  /* DWARF 2 */
+  .debug_info     0 : { *(.debug_info) }
+  .debug_abbrev   0 : { *(.debug_abbrev) }
+  .debug_line     0 : { *(.debug_line) }
+  .debug_frame    0 : { *(.debug_frame) }
+  .debug_str      0 : { *(.debug_str) }
+  .debug_loc      0 : { *(.debug_loc) }
+  .debug_macinfo  0 : { *(.debug_macinfo) }
+  /* SGI/MIPS DWARF 2 extensions */
+  .debug_weaknames 0 : { *(.debug_weaknames) }
+  .debug_funcnames 0 : { *(.debug_funcnames) }
+  .debug_typenames 0 : { *(.debug_typenames) }
+  .debug_varnames  0 : { *(.debug_varnames) }
+  /* These must appear regardless of  .  */
+}
diff --git a/tools/ioemu/include/bochs.h b/tools/ioemu/include/bochs.h
deleted file mode 100644 (file)
index 59b3067..0000000
+++ /dev/null
@@ -1,771 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: bochs.h,v 1.128.2.1 2004/02/06 22:14:25 danielg4 Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-//
-// bochs.h is the master header file for all C++ code.  It includes all 
-// the system header files needed by bochs, and also includes all the bochs
-// C++ header files.  Because bochs.h and the files that it includes has 
-// structure and class definitions, it cannot be called from C code.
-// 
-
-#ifndef BX_BOCHS_H
-#  define BX_BOCHS_H 1
-
-#include "config.h"      /* generated by configure script from config.h.in */
-
-extern "C" {
-
-#ifdef WIN32
-// In a win32 compile (including cygwin), windows.h is required for several
-// files in gui and iodev.  It is important to include it here in a header
-// file so that WIN32-specific data types can be used in fields of classes.
-#include <windows.h>
-#endif
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <errno.h>
-
-#ifndef WIN32
-#  include <unistd.h>
-#else
-#  include <io.h>
-#endif
-#include <time.h>
-#if BX_WITH_MACOS
-#define Float32 KLUDGE_Float32
-#define Float64 KLUDGE_Float64
-#  include <types.h>
-#undef Float32
-#undef Float64
-#  include <stat.h>
-#  include <cstdio>
-#  include <unistd.h>
-#elif BX_WITH_CARBON
-#  include <sys/types.h>
-#  include <sys/stat.h>
-#  include <sys/param.h> /* for MAXPATHLEN */
-#  include <utime.h>
-#else
-#  ifndef WIN32
-#    include <sys/time.h>
-#  endif
-#  include <sys/types.h>
-#  include <sys/stat.h>
-#endif
-#include <ctype.h>
-#include <string.h>
-#include <fcntl.h>
-#include <limits.h>
-#ifdef macintosh
-#  define SuperDrive "[fd:]"
-#endif
-}
-
-#include "osdep.h"       /* platform dependent includes and defines */ 
-#include "bxversion.h"
-
-#include "gui/siminterface.h"
-
-// prototypes
-int bx_begin_simulation (int argc, char *argv[]);
-
-//
-// some macros to interface the CPU and memory to external environment
-// so that these functions can be redirected to the debugger when
-// needed.
-//
-
-#if ((BX_DEBUGGER == 1) && (BX_NUM_SIMULATORS >= 2))
-// =-=-=-=-=-=-=- Redirected to cosimulation debugger -=-=-=-=-=-=-=
-#define DEV_vga_mem_read(addr)       bx_dbg_ucmem_read(addr)
-#define DEV_vga_mem_write(addr, val) bx_dbg_ucmem_write(addr, val)
-
-#if BX_SUPPORT_A20
-#  define A20ADDR(x)               ( (x) & bx_pc_system.a20_mask )
-#else
-#  define A20ADDR(x)                (x)
-#endif
-#define BX_INP(addr, len)           bx_dbg_inp(addr, len)
-#define BX_OUTP(addr, val, len)     bx_dbg_outp(addr, val, len)
-#define BX_HRQ                      (bx_pc_system.HRQ)
-#define BX_RAISE_HLDA()             bx_dbg_raise_HLDA()
-#define BX_TICK1()
-#define BX_INTR                     bx_pc_system.INTR
-#define BX_SET_INTR(b)              bx_dbg_set_INTR(b)
-#if BX_SIM_ID == 0
-#  define BX_CPU_C                  bx_cpu0_c
-#  define BX_CPU                    bx_cpu0
-#  define BX_MEM_C                  bx_mem0_c
-#  define BX_MEM                    bx_mem0
-#else
-#  define BX_CPU_C                  bx_cpu1_c
-#  define BX_CPU                    bx_cpu1
-#  define BX_MEM_C                  bx_mem1_c
-#  define BX_MEM                    bx_mem1
-#endif
-#define BX_SET_ENABLE_A20(enabled)  bx_dbg_async_pin_request(BX_DBG_ASYNC_PENDING_A20, \
-                                      enabled)
-#define BX_GET_ENABLE_A20()         bx_pc_system.get_enable_a20()
-#error FIXME: cosim mode not fixed yet
-
-#else
-
-// =-=-=-=-=-=-=- Normal optimized use -=-=-=-=-=-=-=-=-=-=-=-=-=-=
-#if BX_SUPPORT_A20
-#  define A20ADDR(x)               ( (x) & bx_pc_system.a20_mask )
-#else
-#  define A20ADDR(x)               (x)
-#endif
-//
-// some pc_systems functions just redirect to the IO devices so optimize
-// by eliminating call here
-//
-// #define BX_INP(addr, len)        bx_pc_system.inp(addr, len)
-// #define BX_OUTP(addr, val, len)  bx_pc_system.outp(addr, val, len)
-#define BX_INP(addr, len)           bx_devices.inp(addr, len)
-#define BX_OUTP(addr, val, len)     bx_devices.outp(addr, val, len)
-#define BX_TICK1()                  bx_pc_system.tick1()
-#define BX_TICKN(n)                 bx_pc_system.tickn(n)
-#define BX_INTR                     bx_pc_system.INTR
-#define BX_SET_INTR(b)              bx_pc_system.set_INTR(b)
-#define BX_CPU_C                    bx_cpu_c
-#define BX_MEM_C                    bx_mem_c
-#define BX_HRQ                      (bx_pc_system.HRQ)
-#define BX_MEM_READ_PHYSICAL(phy_addr, len, ptr) \
-  BX_MEM(0)->readPhysicalPage(BX_CPU(0), phy_addr, len, ptr)
-#define BX_MEM_WRITE_PHYSICAL(phy_addr, len, ptr) \
-  BX_MEM(0)->writePhysicalPage(BX_CPU(0), phy_addr, len, ptr)
-
-#if BX_SMP_PROCESSORS==1
-#define BX_CPU(x)                   (&bx_cpu)
-#define BX_MEM(x)                   (&bx_mem)
-#else
-#define BX_CPU(x)                   (bx_cpu_array[x])
-#define BX_MEM(x)                   (bx_mem_array[x])
-#endif
-
-#define BX_SET_ENABLE_A20(enabled)  bx_pc_system.set_enable_a20(enabled)
-#define BX_GET_ENABLE_A20()         bx_pc_system.get_enable_a20()
-
-#endif
-
-
-// you can't use static member functions on the CPU, if there are going
-// to be 2 cpus.  Check this early on.
-#if (BX_SMP_PROCESSORS>1)
-#  if (BX_USE_CPU_SMF!=0)
-#    error For SMP simulation, BX_USE_CPU_SMF must be 0.
-#  endif
-#endif
-
-
-// #define BX_IAC()                 bx_pc_system.IAC()
-//#define BX_IAC()                    bx_dbg_IAC()
-
-//
-// Ways for the the external environment to report back information
-// to the debugger.
-//
-
-#if BX_DEBUGGER
-#  define BX_DBG_ASYNC_INTR bx_guard.async.irq
-#  define BX_DBG_ASYNC_DMA  bx_guard.async.dma
-#if (BX_NUM_SIMULATORS > 1)
-// for multiple simulators, we always need this info, since we're
-// going to replay it.
-#  define BX_DBG_DMA_REPORT(addr, len, what, val) \
-        bx_dbg_dma_report(addr, len, what, val)
-#  define BX_DBG_IAC_REPORT(vector, irq) \
-        bx_dbg_iac_report(vector, irq)
-#  define BX_DBG_A20_REPORT(val) \
-        bx_dbg_a20_report(val)
-#  define BX_DBG_IO_REPORT(addr, size, op, val) \
-        bx_dbg_io_report(addr, size, op, val)
-#  define BX_DBG_UCMEM_REPORT(addr, size, op, val)
-#else
-// for a single simulator debug environment, we can optimize a little
-// by conditionally calling, as per requested.
-
-#  define BX_DBG_DMA_REPORT(addr, len, what, val) \
-        if (bx_guard.report.dma) bx_dbg_dma_report(addr, len, what, val)
-#  define BX_DBG_IAC_REPORT(vector, irq) \
-        if (bx_guard.report.irq) bx_dbg_iac_report(vector, irq)
-#  define BX_DBG_A20_REPORT(val) \
-        if (bx_guard.report.a20) bx_dbg_a20_report(val)
-#  define BX_DBG_IO_REPORT(addr, size, op, val) \
-        if (bx_guard.report.io) bx_dbg_io_report(addr, size, op, val)
-#  define BX_DBG_UCMEM_REPORT(addr, size, op, val) \
-        if (bx_guard.report.ucmem) bx_dbg_ucmem_report(addr, size, op, val)
-#endif  // #if (BX_NUM_SIMULATORS > 1)
-
-#else  // #if BX_DEBUGGER
-// debugger not compiled in, use empty stubs
-#  define BX_DBG_ASYNC_INTR 1
-#  define BX_DBG_ASYNC_DMA  1
-#  define BX_DBG_DMA_REPORT(addr, len, what, val)
-#  define BX_DBG_IAC_REPORT(vector, irq)
-#  define BX_DBG_A20_REPORT(val)
-#  define BX_DBG_IO_REPORT(addr, size, op, val)
-#  define BX_DBG_UCMEM_REPORT(addr, size, op, val)
-#endif  // #if BX_DEBUGGER
-
-#define MAGIC_LOGNUM 0x12345678
-
-typedef class BOCHSAPI logfunctions {
-       char *prefix;
-       int type;
-// values of onoff: 0=ignore, 1=report, 2=ask, 3=fatal
-#define ACT_IGNORE 0
-#define ACT_REPORT 1
-#define ACT_ASK    2
-#define ACT_FATAL  3
-#define N_ACT      4
-       int onoff[N_LOGLEV];
-       class iofunctions *logio;
-       // default log actions for all devices, declared and initialized
-       // in logio.cc.
-       BOCHSAPI_CYGONLY static int default_onoff[N_LOGLEV];
-public:
-       logfunctions(void);
-       logfunctions(class iofunctions *);
-       ~logfunctions(void);
-
-       void info(const char *fmt, ...)   BX_CPP_AttrPrintf(2, 3);
-       void error(const char *fmt, ...)  BX_CPP_AttrPrintf(2, 3);
-       void panic(const char *fmt, ...)  BX_CPP_AttrPrintf(2, 3);
-       void pass(const char *fmt, ...)   BX_CPP_AttrPrintf(2, 3);
-       void ldebug(const char *fmt, ...) BX_CPP_AttrPrintf(2, 3);
-       void fatal (const char *prefix, const char *fmt, va_list ap, int exit_status);
-#if BX_EXTERNAL_DEBUGGER
-       virtual void ask (int level, const char *prefix, const char *fmt, va_list ap);
-#else
-       void ask (int level, const char *prefix, const char *fmt, va_list ap);
-#endif
-       void put(char *);
-       void settype(int);
-       void setio(class iofunctions *);
-       void setonoff(int loglev, int value) {
-         assert (loglev >= 0 && loglev < N_LOGLEV);
-         onoff[loglev] = value; 
-       }
-       char *getprefix () { return prefix; }
-       int getonoff(int level) {
-         assert (level>=0 && level<N_LOGLEV);
-         return onoff[level]; 
-        }
-       static void set_default_action (int loglev, int action) {
-         assert (loglev >= 0 && loglev < N_LOGLEV);
-         assert (action >= 0 && action < N_ACT);
-         default_onoff[loglev] = action;
-       }
-       static int get_default_action (int loglev) {
-         assert (loglev >= 0 && loglev < N_LOGLEV);
-         return default_onoff[loglev];
-       }
-} logfunc_t;
-
-#define BX_LOGPREFIX_SIZE 51
-
-enum {
-  IOLOG=0, FDLOG, GENLOG, CMOSLOG, CDLOG, DMALOG, ETHLOG, G2HLOG, HDLOG, KBDLOG,
-  NE2KLOG, PARLOG, PCILOG, PICLOG, PITLOG, SB16LOG, SERLOG, VGALOG,
-  STLOG, // state_file.cc 
-  DEVLOG, MEMLOG, DISLOG, GUILOG, IOAPICLOG, APICLOG, CPU0LOG, CPU1LOG,
-  CPU2LOG, CPU3LOG, CPU4LOG, CPU5LOG, CPU6LOG, CPU7LOG, CPU8LOG, CPU9LOG,
-  CPU10LOG, CPU11LOG, CPU12LOG, CPU13LOG, CPU14LOG, CPU15LOG, CTRLLOG,
-  UNMAPLOG, SERRLOG, BIOSLOG, PIT81LOG, PIT82LOG, IODEBUGLOG, PCI2ISALOG,
-  PLUGINLOG, EXTFPUIRQLOG , PCIVGALOG, PCIUSBLOG, VTIMERLOG, STIMERLOG
-};
-
-class BOCHSAPI iofunctions {
-       int magic;
-       char logprefix[BX_LOGPREFIX_SIZE];
-       FILE *logfd;
-       class logfunctions *log;
-       void init(void);
-       void flush(void);
-
-// Log Class types
-public:
-       iofunctions(void);
-       iofunctions(FILE *);
-       iofunctions(int);
-       iofunctions(const char *);
-       ~iofunctions(void);
-
-       void out(int facility, int level, const char *pre, const char *fmt, va_list ap);
-
-       void init_log(const char *fn);
-       void init_log(int fd);
-       void init_log(FILE *fs);
-       void set_log_prefix(const char *prefix);
-       int get_n_logfns () { return n_logfn; }
-       logfunc_t *get_logfn (int index) { return logfn_list[index]; }
-       void add_logfn (logfunc_t *fn);
-       void set_log_action (int loglevel, int action);
-       const char *getlevel(int i) {
-               static const char *loglevel[N_LOGLEV] = {
-                       "DEBUG",
-                       "INFO",
-                       "ERROR",
-                       "PANIC",
-                       "PASS"
-               };
-                if (i>=0 && i<N_LOGLEV) return loglevel[i];
-                else return "?";
-       }
-       char *getaction(int i) {
-          static char *name[] = { "ignore", "report", "ask", "fatal" };
-          assert (i>=ACT_IGNORE && i<N_ACT);
-          return name[i];
-       }
-
-protected:
-       int n_logfn;
-#define MAX_LOGFNS 128
-       logfunc_t *logfn_list[MAX_LOGFNS];
-       char *logfn;
-
-
-};
-
-typedef class BOCHSAPI iofunctions iofunc_t;
-
-
-#define SAFE_GET_IOFUNC() \
-  ((io==NULL)? (io=new iofunc_t("/dev/stderr")) : io)
-#define SAFE_GET_GENLOG() \
-  ((genlog==NULL)? (genlog=new logfunc_t(SAFE_GET_IOFUNC())) : genlog)
-/* #define NO_LOGGING */
-#ifndef NO_LOGGING
-
-#define BX_INFO(x)  (LOG_THIS info) x
-#define BX_DEBUG(x) (LOG_THIS ldebug) x
-#define BX_ERROR(x) (LOG_THIS error) x
-#define BX_PANIC(x) (LOG_THIS panic) x
-#define BX_PASS(x) (LOG_THIS pass) x
-
-#else
-
-#define EMPTY do { } while(0)
-
-#define BX_INFO(x)  EMPTY
-#define BX_DEBUG(x) EMPTY
-#define BX_ERROR(x) EMPTY
-#define BX_PANIC(x) (LOG_THIS panic) x
-#define BX_PASS(x) (LOG_THIS pass) x
-
-#endif
-
-BOCHSAPI extern iofunc_t *io;
-BOCHSAPI extern logfunc_t *genlog;
-
-#include "state_file.h"
-
-#ifndef UNUSED
-#  define UNUSED(x) ((void)x)
-#endif
-
-#define uint8   Bit8u
-#define uint16  Bit16u
-#define uint32  Bit32u
-
-#ifdef BX_USE_VMX
-extern "C" {
-#include "xc.h"
-}
-
-extern void *shared_page;
-BOCHSAPI extern int xc_handle;
-#endif
-
-#if BX_PROVIDE_CPU_MEMORY==1
-#  include "cpu/cpu.h"
-#endif
-
-#if BX_EXTERNAL_DEBUGGER
-#  include "cpu/extdb.h"
-#endif
-
-#if BX_GDBSTUB
-// defines for GDB stub
-void bx_gdbstub_init(int argc, char* argv[]);
-int bx_gdbstub_check(unsigned int eip);
-#define GDBSTUB_STOP_NO_REASON   (0xac0)
-
-#if BX_SMP_PROCESSORS!=1
-#error GDB stub was written for single processor support.  If multiprocessor support is added, then we can remove this check.
-// The big problem is knowing which CPU gdb is referring to.  In other words,
-// what should we put for "n" in BX_CPU(n)->dbg_xlate_linear2phy() and
-// BX_CPU(n)->dword.eip, etc.
-#endif
-
-#endif
-
-#if BX_DISASM
-#  include "disasm/disasm.h"
-#endif
-
-typedef struct {
-  bx_bool floppy;
-  bx_bool keyboard;
-  bx_bool video;
-  bx_bool disk;
-  bx_bool pit;
-  bx_bool pic;
-  bx_bool bios;
-  bx_bool cmos;
-  bx_bool a20;
-  bx_bool interrupts;
-  bx_bool exceptions;
-  bx_bool unsupported;
-  bx_bool temp;
-  bx_bool reset;
-  bx_bool debugger;
-  bx_bool mouse;
-  bx_bool io;
-  bx_bool xms;
-  bx_bool v8086;
-  bx_bool paging;
-  bx_bool creg;
-  bx_bool dreg;
-  bx_bool dma;
-  bx_bool unsupported_io;
-  bx_bool serial;
-  bx_bool cdrom;
-#ifdef MAGIC_BREAKPOINT
-  bx_bool magic_break_enabled;
-#endif /* MAGIC_BREAKPOINT */
-#if BX_SUPPORT_APIC
-  bx_bool apic;
-  bx_bool ioapic;
-#endif
-#if BX_DEBUG_LINUX
-  bx_bool linux_syscall;
-#endif
-  void* record_io;
-  } bx_debug_t;
-
-#define BX_ASSERT(x) do {if (!(x)) BX_PANIC(("failed assertion \"%s\" at %s:%d\n", #x, __FILE__, __LINE__));} while (0)
-void bx_signal_handler (int signum);
-int bx_atexit(void);
-BOCHSAPI extern bx_debug_t bx_dbg;
-
-
-
-/* Already in gui/siminterface.h ??? 
-#define BX_FLOPPY_NONE   10 // floppy not present
-#define BX_FLOPPY_1_2    11 // 1.2M  5.25"
-#define BX_FLOPPY_1_44   12 // 1.44M 3.5"
-#define BX_FLOPPY_2_88   13 // 2.88M 3.5"
-#define BX_FLOPPY_720K   14 // 720K  3.5"
-#define BX_FLOPPY_360K   15 // 360K  5.25"
-#define BX_FLOPPY_LAST   15 // last one
-*/
-
-
-#define BX_READ    0
-#define BX_WRITE   1
-#define BX_RW      2
-
-
-
-
-
-#include "memory/memory.h"
-
-
-enum PCS_OP { PCS_CLEAR, PCS_SET, PCS_TOGGLE };
-
-#include "pc_system.h"
-#include "plugin.h"
-#include "gui/gui.h"
-#include "gui/textconfig.h"
-#include "gui/keymap.h"
-#include "iodev/iodev.h"
-
-
-
-
-
-
-
-/* --- EXTERNS --- */
-
-#if ( BX_PROVIDE_DEVICE_MODELS==1 )
-BOCHSAPI extern bx_devices_c   bx_devices;
-#endif
-
-#if BX_GUI_SIGHANDLER
-extern bx_bool bx_gui_sighandler;
-#endif
-
-// This value controls how often each I/O device's periodic() method
-// gets called.  The timer is set up in iodev/devices.cc.
-#define BX_IODEV_HANDLER_PERIOD 100    // microseconds
-//#define BX_IODEV_HANDLER_PERIOD 10    // microseconds
-
-char *bx_find_bochsrc (void);
-int bx_parse_cmdline (int arg, int argc, char *argv[]);
-int bx_read_configuration (char *rcfile);
-int bx_write_configuration (char *rcfile, int overwrite);
-void bx_reset_options (void);
-
-#define BX_PATHNAME_LEN 512
-
-typedef struct {
-  bx_param_bool_c *Opresent;
-  bx_param_num_c *Oioaddr1;
-  bx_param_num_c *Oioaddr2;
-  bx_param_num_c *Oirq;
-  } bx_ata_options;
-
-typedef struct {
-  bx_param_string_c *Opath;
-  bx_param_num_c *Oaddress;
-  } bx_rom_options;
-
-typedef struct {
-  bx_param_string_c *Opath;
-  } bx_vgarom_options;
-
-typedef struct {
-  bx_param_num_c *Osize;
-  } bx_mem_options;
-
-typedef struct {
-  bx_param_bool_c *Oenabled;
-  bx_param_string_c *Ooutfile;
-} bx_parport_options;
-
-typedef struct {
-  bx_param_string_c *Opath;
-  bx_param_bool_c *OcmosImage;
-  } bx_cmos_options;
-
-typedef struct {
-  bx_param_num_c   *Otime0;
-  bx_param_enum_c  *Osync;
-  } bx_clock_options;
-
-typedef struct {
-  bx_param_bool_c *Opresent;
-  bx_param_num_c *Oioaddr;
-  bx_param_num_c *Oirq;
-  bx_param_string_c *Omacaddr;
-  bx_param_enum_c *Oethmod;
-  bx_param_string_c *Oethdev;
-  bx_param_string_c *Oscript;
-  } bx_ne2k_options;
-
-typedef struct {
-// These options are used for a special hack to load a
-// 32bit OS directly into memory, so it can be run without
-// any of the 16bit real mode or BIOS assistance.  This
-// is for the development of plex86, so we don't have
-// to implement real mode up front.
-  bx_param_num_c *OwhichOS;
-  bx_param_string_c *Opath;
-  bx_param_string_c *Oiolog;
-  bx_param_string_c *Oinitrd;
-  } bx_load32bitOSImage_t;
-
-typedef struct {
-  bx_param_string_c *Ofilename;
-  bx_param_string_c *Oprefix;
-  bx_param_string_c *Odebugger_filename;
-} bx_log_options;
-
-typedef struct {
-  bx_param_bool_c *Opresent;
-  bx_param_string_c *Omidifile;
-  bx_param_string_c *Owavefile;
-  bx_param_string_c *Ologfile;
-  bx_param_num_c *Omidimode;
-  bx_param_num_c *Owavemode;
-  bx_param_num_c *Ologlevel;
-  bx_param_num_c *Odmatimer;
-  } bx_sb16_options;
-
-typedef struct {
-  unsigned int port;
-  unsigned int text_base;
-  unsigned int data_base;
-  unsigned int bss_base;
-  } bx_gdbstub_t;
-
-typedef struct {
-  bx_param_bool_c *OuseMapping;
-  bx_param_string_c *Okeymap;
-  } bx_keyboard_options;
-
-#define BX_KBD_XT_TYPE        0
-#define BX_KBD_AT_TYPE        1
-#define BX_KBD_MF_TYPE        2 
-
-#define BX_N_OPTROM_IMAGES 4
-#define BX_N_SERIAL_PORTS 1
-#define BX_N_PARALLEL_PORTS 1
-#define BX_N_USB_HUBS 1
-
-typedef struct BOCHSAPI {
-  bx_floppy_options floppya;
-  bx_floppy_options floppyb;
-  bx_ata_options    ata[BX_MAX_ATA_CHANNEL];
-  bx_atadevice_options  atadevice[BX_MAX_ATA_CHANNEL][2];
-  // bx_disk_options   diskc;
-  // bx_disk_options   diskd;
-  // bx_cdrom_options  cdromd; 
-  bx_serial_options com[BX_N_SERIAL_PORTS];
-  bx_usb_options    usb[BX_N_USB_HUBS];
-  bx_rom_options    rom;
-  bx_vgarom_options vgarom;
-  bx_rom_options    optrom[BX_N_OPTROM_IMAGES]; // Optional rom images 
-  bx_mem_options    memory;
-  bx_parport_options par[BX_N_PARALLEL_PORTS]; // parallel ports
-  bx_sb16_options   sb16;
-  bx_param_num_c    *Obootdrive;  
-  bx_param_bool_c   *OfloppySigCheck;
-  bx_param_num_c    *Ovga_update_interval;
-  bx_param_num_c    *Okeyboard_serial_delay;
-  bx_param_num_c    *Okeyboard_paste_delay;
-  bx_param_enum_c   *Okeyboard_type;
-  bx_param_num_c    *Ofloppy_command_delay;
-  bx_param_num_c    *Oips;
-  bx_param_bool_c   *Orealtime_pit;
-  bx_param_bool_c   *Otext_snapshot_check;
-  bx_param_bool_c   *Omouse_enabled;
-  bx_param_bool_c   *Oprivate_colormap;
-#if BX_WITH_AMIGAOS
-  bx_param_bool_c   *Ofullscreen;
-  bx_param_string_c *Oscreenmode;
-#endif
-  bx_param_bool_c   *Oi440FXSupport;
-  bx_cmos_options   cmos;
-  bx_clock_options  clock;
-  bx_ne2k_options   ne2k;
-  bx_param_bool_c   *OnewHardDriveSupport;
-  bx_load32bitOSImage_t load32bitOSImage;
-  bx_log_options    log;
-  bx_keyboard_options keyboard;
-  bx_param_string_c *Ouser_shortcut;
-  bx_gdbstub_t      gdbstub;
-  bx_param_enum_c *Osel_config;
-  bx_param_enum_c *Osel_displaylib;
-  } bx_options_t;
-
-BOCHSAPI extern bx_options_t bx_options;
-
-void bx_center_print (FILE *file, char *line, int maxwidth);
-
-#if BX_PROVIDE_CPU_MEMORY==1
-#else
-// #  include "external_interface.h"
-#endif
-
-#define BX_USE_PS2_MOUSE 1
-
-int bx_init_hardware ();
-
-#include "instrument.h"
-
-// These are some convenience macros which abstract out accesses between
-// a variable in native byte ordering to/from guest (x86) memory, which is
-// always in little endian format.  You must deal with alignment (if your
-// system cares) and endian rearranging.  Don't assume anything.  You could
-// put some platform specific asm() statements here, to make use of native
-// instructions to help perform these operations more efficiently than C++.
-
-
-#ifdef __i386__
-
-#define WriteHostWordToLittleEndian(hostPtr,  nativeVar16) \
-    *((Bit16u*)(hostPtr)) = (nativeVar16)
-#define WriteHostDWordToLittleEndian(hostPtr, nativeVar32) \
-    *((Bit32u*)(hostPtr)) = (nativeVar32)
-#define WriteHostQWordToLittleEndian(hostPtr, nativeVar64) \
-    *((Bit64u*)(hostPtr)) = (nativeVar64)
-#define ReadHostWordFromLittleEndian(hostPtr, nativeVar16) \
-    (nativeVar16) = *((Bit16u*)(hostPtr))
-#define ReadHostDWordFromLittleEndian(hostPtr, nativeVar32) \
-    (nativeVar32) = *((Bit32u*)(hostPtr))
-#define ReadHostQWordFromLittleEndian(hostPtr, nativeVar64) \
-    (nativeVar64) = *((Bit64u*)(hostPtr))
-
-#else
-
-#define WriteHostWordToLittleEndian(hostPtr,  nativeVar16) { \
-    ((Bit8u *)(hostPtr))[0] = (Bit8u)  (nativeVar16); \
-    ((Bit8u *)(hostPtr))[1] = (Bit8u) ((nativeVar16)>>8); \
-    }
-#define WriteHostDWordToLittleEndian(hostPtr, nativeVar32) { \
-    ((Bit8u *)(hostPtr))[0] = (Bit8u)  (nativeVar32); \
-    ((Bit8u *)(hostPtr))[1] = (Bit8u) ((nativeVar32)>>8); \
-    ((Bit8u *)(hostPtr))[2] = (Bit8u) ((nativeVar32)>>16); \
-    ((Bit8u *)(hostPtr))[3] = (Bit8u) ((nativeVar32)>>24); \
-    }
-#define WriteHostQWordToLittleEndian(hostPtr, nativeVar64) { \
-    ((Bit8u *)(hostPtr))[0] = (Bit8u)  (nativeVar64); \
-    ((Bit8u *)(hostPtr))[1] = (Bit8u) ((nativeVar64)>>8); \
-    ((Bit8u *)(hostPtr))[2] = (Bit8u) ((nativeVar64)>>16); \
-    ((Bit8u *)(hostPtr))[3] = (Bit8u) ((nativeVar64)>>24); \
-    ((Bit8u *)(hostPtr))[4] = (Bit8u) ((nativeVar64)>>32); \
-    ((Bit8u *)(hostPtr))[5] = (Bit8u) ((nativeVar64)>>40); \
-    ((Bit8u *)(hostPtr))[6] = (Bit8u) ((nativeVar64)>>48); \
-    ((Bit8u *)(hostPtr))[7] = (Bit8u) ((nativeVar64)>>56); \
-    }
-#define ReadHostWordFromLittleEndian(hostPtr, nativeVar16) { \
-    (nativeVar16) =  ((Bit16u) ((Bit8u *)(hostPtr))[0]) | \
-                    (((Bit16u) ((Bit8u *)(hostPtr))[1])<<8) ; \
-    }
-#define ReadHostDWordFromLittleEndian(hostPtr, nativeVar32) { \
-    (nativeVar32) =  ((Bit32u) ((Bit8u *)(hostPtr))[0]) | \
-                    (((Bit32u) ((Bit8u *)(hostPtr))[1])<<8) | \
-                    (((Bit32u) ((Bit8u *)(hostPtr))[2])<<16) | \
-                    (((Bit32u) ((Bit8u *)(hostPtr))[3])<<24); \
-    }
-#define ReadHostQWordFromLittleEndian(hostPtr, nativeVar64) { \
-    (nativeVar64) =  ((Bit64u) ((Bit8u *)(hostPtr))[0]) | \
-                    (((Bit64u) ((Bit8u *)(hostPtr))[1])<<8) | \
-                    (((Bit64u) ((Bit8u *)(hostPtr))[2])<<16) | \
-                    (((Bit64u) ((Bit8u *)(hostPtr))[3])<<24) | \
-                    (((Bit64u) ((Bit8u *)(hostPtr))[4])<<32) | \
-                    (((Bit64u) ((Bit8u *)(hostPtr))[5])<<40) | \
-                    (((Bit64u) ((Bit8u *)(hostPtr))[6])<<48) | \
-                    (((Bit64u) ((Bit8u *)(hostPtr))[7])<<56); \
-    }
-
-#endif
-
-#ifdef BX_USE_VMX
-extern int domid;
-extern unsigned long megabytes;
-#endif
-
-#endif  /* BX_BOCHS_H */
diff --git a/tools/ioemu/include/bxversion.h b/tools/ioemu/include/bxversion.h
deleted file mode 100644 (file)
index 1c640f9..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// This file is checked in as bxversion.h.in.  The configure script
-// substitutes variables and creates bxversion.h.
-/////////////////////////////////////////////////////////////////////////
-
-#define VER_STRING "2.1.1"
-#define REL_STRING "February 08, 2004"
diff --git a/tools/ioemu/include/config.h b/tools/ioemu/include/config.h
deleted file mode 100644 (file)
index 53a72b2..0000000
+++ /dev/null
@@ -1,919 +0,0 @@
-/* config.h.  Generated by configure.  */
-//  Copyright (C) 2001  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-//
-// config.h.in is distributed in the source TAR file.  When you run
-// the configure script, it generates config.h with some changes
-// according to your build environment.  For example, in config.h.in,
-// SIZEOF_UNSIGNED_CHAR is set to 0.  When configure produces config.h
-// it will change "0" to the detected value for your system.
-//
-// config.h contains ONLY preprocessor #defines and a few typedefs.
-// It must be included by both C and C++ files, so it must not
-// contain anything language dependent such as a class declaration.
-//
-
-#ifdef _BX_CONFIG_H_
-#else
-#define _BX_CONFIG_H_ 1
-
-///////////////////////////////////////////////////////////////////
-// USER CONFIGURABLE OPTIONS : EDIT ONLY OPTIONS IN THIS SECTION //
-///////////////////////////////////////////////////////////////////
-
-
-#if 1
-// quit_sim is defined in gui/siminterface.h
-#define BX_EXIT(x)  SIM->quit_sim (x)
-#else
-// provide the real main and the usual exit.
-#define BX_EXIT(x)  ::exit(x)
-#endif
-
-#define BX_USE_CONFIG_INTERFACE 0
-#define BX_USE_VMX 1
-
-// I have tested the following combinations:
-//  * processors=1, bootstrap=0, ioapic_id=1   (uniprocessor system)
-//  * processors=2, bootstrap=0, ioapic_id=2
-//  * processors=4, bootstrap=2, ioapic_id=4
-#define BX_SMP_PROCESSORS 1
-#define BX_BOOTSTRAP_PROCESSOR 0
-// choose IOAPIC id to be equal to the number of processors.  This leaves
-// one space for each processor to have an ID, starting with 0.
-#define BX_IOAPIC_DEFAULT_ID 1
-
-#define BX_ADDRESS_SPACES 1
-// controls how many instances of BX_MEM_C are created.  For
-// SMP, use several processors with one shared memory space.
-// For cosimulation, you could use two processors and two address
-// spaces.
-
-#define BX_SUPPORT_APIC 0
-// include in APIC models, required for a multiprocessor system.
-
-#if (BX_SMP_PROCESSORS>1 && !BX_SUPPORT_APIC)
-#error For multiprocessor simulation, BX_SUPPORT_APIC is required.
-#endif
-
-#define BX_DEBUG_LINUX 0
-// if simulating Linux, this provides a few more debugging options
-// such as tracing all system calls.
-
-#define HAVE_LIBREADLINE 0
-#define HAVE_READLINE_HISTORY_H 1
-// adds support for the GNU readline library in the debugger command
-// prompt.
-
-#define HAVE_LOCALE_H 0
-// Define to 1 if you have <locale.h>
-
-// I rebuilt the code which provides timers to IO devices.
-// Setting this to 1 will introduce a little code which
-// will panic out if cases which shouldn't happen occur.
-// Set this to 0 for optimal performance.
-#define BX_TIMER_DEBUG 1
-
-// Settable A20 line.  For efficiency, you can disable
-// having a settable A20 line, eliminating conditional
-// code for every physical memory access.  You'll have
-// to tell your software not to mess with the A20 line,
-// and accept it as always being on if you change this.
-//   1 = use settable A20 line. (normal)
-//   0 = A20 is like the rest of the address lines
-
-#define BX_SUPPORT_A20 1
-
-// Processor Instructions Per Second
-// To find out what value to use for the 'ips' directive
-// in your '.bochsrc' file, set BX_SHOW_IPS to 1, and
-// run the software in bochs you plan to use most.  Bochs
-// will print out periodic IPS ratings.  This will change
-// based on the processor mode at the time, and various
-// other factors.  You'll get a reasonable estimate though.
-// When you're done, reset BX_SHOW_IPS to 0, do a
-// 'make all-clean', then 'make' again.
-
-#define BX_SHOW_IPS         0
-
-
-#if (BX_SHOW_IPS) && defined(__MINGW32__)
-#define        SIGALRM         14
-#endif
-
-// Paging Options:
-// ---------------
-// Support Paging mechanism.
-//   0 = don't support paging at all (DOS & Minix don't require it)
-//   1 = support paging.  (Most other OS's require paging)
-// Use Translation Lookaside Buffer (TLB) for caching
-// paging translations.  This will make paging mode
-// more efficient.  If you're OS doesn't use paging,
-// then you won't need either.
-//   1 = Use a TLB for effiency
-//   0 = don't use a TLB, walk the page tables for every access
-// BX_TLB_SIZE: Number of entries in TLB
-// BX_TLB_INDEX_OF(lpf): This macro is passed the linear page frame
-//   (top 20 bits of the linear address.  It must map these bits to
-//   one of the TLB cache slots, given the size of BX_TLB_SIZE.
-//   There will be a many-to-one mapping to each TLB cache slot.
-//   When there are collisions, the old entry is overwritten with
-//   one for the newest access.
-
-#define BX_SUPPORT_PAGING     1
-#define BX_USE_TLB 1
-
-#define BX_TLB_SIZE 1024
-#define BX_TLB_INDEX_OF(lpf) (((lpf) & 0x003ff000) >> 12)
-
-#define BX_USE_QUICK_TLB_INVALIDATE 0
-
-// Compile in support for DMA & FLOPPY IO.  You'll need this
-// if you plan to use the floppy drive emulation.  But if
-// you're environment doesn't require it, you can change
-// it to 0.
-
-#define BX_DMA_FLOPPY_IO 1
-
-
-// Default number of Megs of memory to emulate.  The
-// 'megs:' directive in the '.bochsrc' file overrides this,
-// allowing per-run settings.
-
-#define BX_DEFAULT_MEM_MEGS 4
-
-
-// CPU level emulation.  Default level is set in
-// the configure script.  BX_CPU_LEVEL defines the CPU level
-// to emulate.  BX_CPU_LEVEL_HACKED is a hack to define the
-// level of some integer instructions, so they can be tested
-// before the rest of the emulation is up to that level.
-
-#define BX_CPU_LEVEL 5
-#define BX_CPU_LEVEL_HACKED 5
-
-// emulate x86-64 instruction set?
-#define BX_SUPPORT_X86_64 0
-
-// Virtual 8086 mode emulation.
-//   1 = compile in support for v8086 mode.
-//   0 = don't compile in support for v8086 mode.
-#define BX_SUPPORT_V8086_MODE 1
-
-// Defines if the simulation should reset on triple fault
-// if set to 0, the simulation will panic.
-#define BX_RESET_ON_TRIPLE_FAULT 1
-
-// Support shadowing of ROM from C0000 to FFFFF.
-// This allows that region to be written to.
-#define BX_SHADOW_RAM 0
-
-// Number of CMOS registers
-#define BX_NUM_CMOS_REGS 64
-//#define BX_NUM_CMOS_REGS 128
-
-// Use Greg Alexander's new PIT model (summer 2001) instead of the original.
-#define BX_USE_NEW_PIT 1
-
-#define BX_USE_SLOWDOWN_TIMER 0
-#define BX_HAVE_SLEEP 1
-#define BX_HAVE_MSLEEP 0
-#define BX_HAVE_USLEEP 1
-#define BX_HAVE_NANOSLEEP 1
-#define BX_HAVE_ABORT 1
-#define BX_HAVE_SOCKLEN_T 1
-#define BX_HAVE_SOCKADDR_IN_SIN_LEN 0
-#define BX_HAVE_GETTIMEOFDAY 1
-#if defined(WIN32)
-#define BX_HAVE_REALTIME_USEC 1
-#else
-#define BX_HAVE_REALTIME_USEC (BX_HAVE_GETTIMEOFDAY)
-#endif
-#define BX_HAVE_MKSTEMP 1
-#define BX_HAVE_SYS_MMAN_H 1
-#define BX_HAVE_XPM_H 1
-#define BX_HAVE_TIMELOCAL 1
-#define BX_HAVE_GMTIME 1
-#define BX_HAVE_MKTIME 1
-
-// This turns on Roland Mainz's idle hack.  Presently it is specific to the X11
-// gui. If people try to enable it elsewhere, give a compile error after the
-// gui definition so that they don't waste their time trying.
-#define BX_USE_IDLE_HACK 0
-
-// Minimum Emulated IPS.
-// This is used in the realtime PIT as well as for checking the
-// IPS value set in the config file.
-#define BX_MIN_IPS 200000
-
-// Use Static Member Funtions to eliminate 'this' pointer passing
-// If you want the efficiency of 'C', you can make all the
-// members of the C++ CPU class to be static.
-// This defaults to 1 since it should improve performance, but when
-// SMP mode is enabled, it will be turned off by configure.
-
-#define BX_USE_CPU_SMF 1
-
-// Use static member functions in IO DEVice emulation modules.
-// For efficiency, use C like functions for IO handling,
-// and declare a device instance at compile time,
-// instead of using 'new' and storing the pointer.  This
-// eliminates some overhead, especially for high-use IO
-// devices like the disk drive.
-//   1 = Use static member efficiency (normal)
-//   0 = Use nonstatic member functions (use only if you need
-//       multiple instances of a device class
-
-#define BX_USE_HD_SMF      1  // Hard drive
-#define BX_USE_BIOS_SMF    1  // BIOS
-#define BX_USE_CMOS_SMF    1  // CMOS
-#define BX_USE_DMA_SMF     1  // DMA
-#define BX_USE_FD_SMF      1  // Floppy
-#define BX_USE_KEY_SMF     1  // Keyboard
-#define BX_USE_PAR_SMF     1  // Parallel
-#define BX_USE_PIC_SMF     1  // PIC
-#define BX_USE_PIT_SMF     1  // PIT
-#define BX_USE_SER_SMF     1  // Serial
-#define BX_USE_UM_SMF      1  // Unmapped
-#define BX_USE_VGA_SMF     1  // VGA
-#define BX_USE_SB16_SMF    1  // Sound (SB 16)
-#define BX_USE_DEV_SMF     1  // System Devices (port92)
-#define BX_USE_PCI_SMF     1  // PCI
-#define BX_USE_P2I_SMF     1  // PCI-to-ISA bridge
-#define BX_USE_PCIVGA_SMF  1  // PCI-VGA
-#define BX_USE_PCIUSB_SMF  1  // USB hub
-#define BX_USE_NE2K_SMF    1  // NE2K
-#define BX_USE_EFI_SMF     1  // External FPU IRQ
-#define BX_USE_GAME_SMF    1  // Gameport
-
-#define BX_PLUGINS 0
-#define BX_HAVE_DLFCN_H 1
-
-#if BX_PLUGINS && \
-  (   !BX_USE_HD_SMF || !BX_USE_BIOS_SMF || !BX_USE_CMOS_SMF \
-   || !BX_USE_DMA_SMF || !BX_USE_FD_SMF || !BX_USE_KEY_SMF \
-   || !BX_USE_PAR_SMF || !BX_USE_PIC_SMF || !BX_USE_PIT_SMF \
-   || !BX_USE_SER_SMF || !BX_USE_UM_SMF || !BX_USE_VGA_SMF \
-   || !BX_USE_SB16_SMF || !BX_USE_DEV_SMF || !BX_USE_PCI_SMF \
-   || !BX_USE_P2I_SMF || !BX_USE_PCIVGA_SMF || !BX_USE_PCIUSB_SMF \
-   || !BX_USE_NE2K_SMF || !BX_USE_EFI_SMF || !BX_USE_GAME_SMF)
-#error You must use SMF to have plugins
-#endif
-
-#define BX_SUPPORT_SB16 0
-#define BX_SUPPORT_GAME 0
-
-#if BX_SUPPORT_SB16
-// Use virtual methods for the sound output functions
-#define BX_USE_SOUND_VIRTUAL  1
-// Determines which sound output class is to be used.
-// Currently the following are available:
-//    bx_sound_linux_c      Output for Linux, to /dev/dsp and /dev/midi00
-//    bx_sound_windows_c    Output for Windows midi and wave mappers
-//    bx_sound_output_c     Dummy functions, no output
-#define BX_SOUND_OUTPUT_C  bx_sound_output_c
-#endif
-
-#define USE_RAW_SERIAL 0
-
-#define BX_USE_SPECIFIED_TIME0 0
-
-// This enables writing to port 0xe9 and the output
-// is sent to the console.  Reading from port 0xe9
-// will return 0xe9 to let you know this is available.
-// Leave this 0 unless you have a reason to use it.
-#define BX_PORT_E9_HACK 1
-
-#define BX_GDBSTUB 0
-
-// This option enables compressed (zlib) hd support
-#define BX_COMPRESSED_HD_SUPPORT 0
-#define BX_HAVE_ZLIB 1
-
-#if BX_COMPRESSED_HD_SUPPORT && !BX_HAVE_ZLIB
-#error You must have zlib to enable compressed hd support
-#endif
-
-// This option defines the number of supported ATA channels.
-// There are up to two drives per ATA channel.
-#define BX_MAX_ATA_CHANNEL 4
-
-#if (BX_MAX_ATA_CHANNEL>4 || BX_MAX_ATA_CHANNEL<1)
-#  error "BX_MAX_ATA_CHANNEL should be between 1 and 4"
-#endif
-
-// =================================================================
-// BEGIN: OPTIONAL DEBUGGER SECTION
-//
-// These options are only used if you compile in support for the
-// native command line debugging environment.  Typically, the debugger
-// is not used, and this section can be ignored.
-// =================================================================
-
-#define BX_MAX_DIRTY_PAGE_TABLE_MEGS 1024
-
-// Compile in support for virtual/linear/physical breakpoints.
-// Set to 1, only those you need.  Recommend using only linear
-// breakpoints, unless you need others.  Less supported means
-// slightly faster execution time.
-#define BX_DBG_SUPPORT_VIR_BPOINT 1
-#define BX_DBG_SUPPORT_LIN_BPOINT 1
-#define BX_DBG_SUPPORT_PHY_BPOINT 1
-
-// You need only define one initial breakpoint into each
-// cpu simulator (emulator) here.  Each simulator sets callbacks
-// and variables which the debugger uses from then on.
-#define BX_SIM1_INIT bx_dbg_init_cpu_mem_env0
-#ifndef BX_SIM2_INIT
-#define BX_SIM2_INIT bx_dbg_init_cpu_mem_env1
-#endif
-//#define BX_SIM2_INIT sim2_init
-
-// max number of virtual/linear/physical breakpoints handled
-#define BX_DBG_MAX_VIR_BPOINTS 10
-#define BX_DBG_MAX_LIN_BPOINTS 10
-#define BX_DBG_MAX_PHY_BPOINTS 10
-
-// max file pathname size for debugger commands
-#define BX_MAX_PATH     256
-// max nesting level for debug scripts including other scripts
-#define BX_INFILE_DEPTH  10
-// use this command to include (nest) debug scripts
-#define BX_INCLUDE_CMD   "source"
-
-// Use either 32 or 64 bit instruction counter for
-// debugger purposes.  Uncomment one of these.
-//#define BX_DBG_ICOUNT_SIZE   32
-#define BX_DBG_ICOUNT_SIZE   64
-
-// Make a call to command line debugger extensions.  If set to 1,
-// a call is made.  An external routine has a chance to process
-// the command.  If it does, than the debugger ignores the command.
-#define BX_DBG_EXTENSIONS 0
-
-// =================================================================
-// END: OPTIONAL DEBUGGER SECTION
-// =================================================================
-
-
-//////////////////////////////////////////////////////////////////////
-// END OF USER CONFIGURABLE OPTIONS : DON'T EDIT ANYTHING BELOW !!! //
-// THIS IS GENERATED BY THE ./configure SCRIPT                      //
-//////////////////////////////////////////////////////////////////////
-
-
-#define BX_WITH_X11 1
-#define BX_WITH_BEOS 0
-#define BX_WITH_WIN32 0
-#define BX_WITH_MACOS 0
-#define BX_WITH_CARBON 0
-#define BX_WITH_NOGUI 0
-#define BX_WITH_TERM 1
-#define BX_WITH_RFB 1
-#define BX_WITH_AMIGAOS 0
-#define BX_WITH_SDL 0
-#define BX_WITH_SVGA 0
-#define BX_WITH_WX 0
-
-// add special export symbols for win32 DLL building.  The main code must
-// have __declspec(dllexport) on variables, functions, or classes that the
-// plugins can access.  The plugins should #define PLUGGABLE which will
-// activate the __declspec(dllimport) instead.
-#if defined(WIN32) || defined(__CYGWIN__)
-#  if BX_PLUGINS && defined(BX_PLUGGABLE)
-//   #warning I will import DLL symbols from Bochs main program.
-#    define BOCHSAPI __declspec(dllimport)
-#  else
-//   #warning I will export DLL symbols.
-#    define BOCHSAPI __declspec(dllexport)
-#  endif
-#endif
-#ifndef BOCHSAPI
-#  define BOCHSAPI
-#endif
-
-#if defined(__CYGWIN__)
-// Make BOCHSAPI_CYGONLY exactly the same as BOCHSAPI.  This symbol
-// will be used for any cases where Cygwin requires a special tag
-// but VC++ does not.
-#define BOCHSAPI_CYGONLY BOCHSAPI
-#else
-// define the symbol to be empty
-#define BOCHSAPI_CYGONLY /*empty*/
-#endif
-
-#define BX_DEFAULT_CONFIG_INTERFACE "defined_by_configure"
-#define BX_DEFAULT_DISPLAY_LIBRARY "defined_by_configure"
-
-// Roland Mainz's idle hack is presently specific to X11. If people try to
-// enable it elsewhere, give a compile error so that they don't waste their
-// time trying.
-#if (BX_USE_IDLE_HACK && !BX_WITH_X11)
-#  error IDLE_HACK will only work with the X11 gui. Correct configure args and retry.
-#endif
-
-#define WORDS_BIGENDIAN 0
-
-#define SIZEOF_UNSIGNED_CHAR 1
-#define SIZEOF_UNSIGNED_SHORT 2
-#define SIZEOF_UNSIGNED_INT 4
-#define SIZEOF_UNSIGNED_LONG 4
-#define SIZEOF_UNSIGNED_LONG_LONG 8
-#define SIZEOF_INT_P 4
-
-#define BX_64BIT_CONSTANTS_USE_LL 1
-#if BX_64BIT_CONSTANTS_USE_LL
-// doesn't work on Microsoft Visual C++, maybe others
-#define BX_CONST64(x)  (x##LL)
-#else
-#define BX_CONST64(x)  (x)
-#endif
-
-#if defined(WIN32)
-  typedef unsigned char      Bit8u;
-  typedef   signed char      Bit8s;
-  typedef unsigned short     Bit16u;
-  typedef   signed short     Bit16s;
-  typedef unsigned int       Bit32u;
-  typedef   signed int       Bit32s;
-#ifdef __MINGW32__
-  typedef unsigned long long Bit64u;
-  typedef   signed long long Bit64s;
-#include <sys/types.h>
-#else
-  typedef unsigned __int64   Bit64u;
-  typedef   signed __int64   Bit64s;
-#endif
-#elif BX_WITH_MACOS
-  typedef unsigned char      Bit8u;
-  typedef   signed char      Bit8s;
-  typedef unsigned short     Bit16u;
-  typedef   signed short     Bit16s;
-  typedef unsigned int       Bit32u;
-  typedef   signed int       Bit32s;
-  typedef unsigned long long Bit64u;
-  typedef   signed long long Bit64s;
-#else
-
-// Unix like platforms
-
-#if SIZEOF_UNSIGNED_CHAR != 1
-#  error "sizeof (unsigned char) != 1"
-#else
-  typedef unsigned char Bit8u;
-  typedef   signed char Bit8s;
-#endif
-
-#if SIZEOF_UNSIGNED_SHORT != 2
-#  error "sizeof (unsigned short) != 2"
-#else
-  typedef unsigned short Bit16u;
-  typedef   signed short Bit16s;
-#endif
-
-#if SIZEOF_UNSIGNED_INT == 4
-  typedef unsigned int Bit32u;
-  typedef   signed int Bit32s;
-#elif SIZEOF_UNSIGNED_LONG == 4
-  typedef unsigned long Bit32u;
-  typedef   signed long Bit32s;
-#else
-#  error "can't find sizeof(type) of 4 bytes!"
-#endif
-
-#if SIZEOF_UNSIGNED_LONG == 8
-  typedef unsigned long Bit64u;
-  typedef   signed long Bit64s;
-#elif SIZEOF_UNSIGNED_LONG_LONG == 8
-  typedef unsigned long long Bit64u;
-  typedef   signed long long Bit64s;
-#else
-#  error "can't find data type of 8 bytes"
-#endif
-
-#endif
-
-// now that Bit32u and Bit64u exist, defined bx_address
-#if BX_SUPPORT_X86_64
-typedef Bit64u bx_address;
-#else
-typedef Bit32u bx_address;
-#endif
-
-
-// technically, in an 8 bit signed the real minimum is -128, not -127.
-// But if you decide to negate -128 you tend to get -128 again, so it's
-// better not to use the absolute maximum in the signed range.
-#define BX_MAX_BIT64U ( (Bit64u) -1           )
-#define BX_MIN_BIT64U ( 0                     )
-#define BX_MAX_BIT64S ( ((Bit64u) -1) >> 1    )
-#define BX_MIN_BIT64S ( -(((Bit64u) -1) >> 1) )
-#define BX_MAX_BIT32U ( (Bit32u) -1           )
-#define BX_MIN_BIT32U ( 0                     )
-#define BX_MAX_BIT32S ( ((Bit32u) -1) >> 1    )
-#define BX_MIN_BIT32S ( -(((Bit32u) -1) >> 1) )
-#define BX_MAX_BIT16U ( (Bit16u) -1           )
-#define BX_MIN_BIT16U ( 0                     )
-#define BX_MAX_BIT16S ( ((Bit16u) -1) >> 1    )
-#define BX_MIN_BIT16S ( -(((Bit16u) -1) >> 1) )
-#define BX_MAX_BIT8U  ( (Bit8u) -1            )
-#define BX_MIN_BIT8U  ( 0                     )
-#define BX_MAX_BIT8S  ( ((Bit8u) -1) >> 1     )
-#define BX_MIN_BIT8S  ( -(((Bit8u) -1) >> 1)  )
-
-
-// create an unsigned integer type that is the same size as a pointer.
-// You can typecast a pointer to a bx_pr_equiv_t without losing any
-// bits (and without getting the compiler excited).  This is used in
-// the FPU emulation code, where pointers and integers are often
-// used interchangeably.
-#if SIZEOF_INT_P == 4
-  typedef Bit32u bx_ptr_equiv_t;
-#elif SIZEOF_INT_P == 8
-  typedef Bit64u bx_ptr_equiv_t;
-#else
-#  error "could not define bx_ptr_equiv_t to size of int*"
-#endif
-
-// Use a boolean type that will not conflict with the builtin type
-// on any system.
-typedef Bit32u bx_bool;
-
-#if BX_WITH_MACOS
-#  define bx_ptr_t char *
-#else
-#  define bx_ptr_t void *
-#endif
-
-#if defined(WIN32)
-#  define BX_LITTLE_ENDIAN
-#elif BX_WITH_MACOS
-#  define BX_BIG_ENDIAN
-#else
-#if WORDS_BIGENDIAN
-#  define BX_BIG_ENDIAN
-#else
-#  define BX_LITTLE_ENDIAN
-#endif
-#endif // defined(WIN32)
-
-
-#if BX_SUPPORT_X86_64
-#ifdef BX_LITTLE_ENDIAN
-typedef
-  struct {
-         Bit64u lo;
-         Bit64u hi;
-         } Bit128u;
-typedef
-  struct {
-         Bit64u lo;
-         Bit64s hi;
-         } Bit128s;
-#else   // must be Big Endian
-typedef
-  struct {
-         Bit64u hi;
-         Bit64u lo;
-         } Bit128u;
-typedef
-  struct {
-         Bit64s hi;
-         Bit64u lo;
-         } Bit128s;
-#endif
-#endif  // #if BX_SUPPORT_X86_64
-
-
-// for now only term.cc requires a GUI sighandler.
-#define BX_GUI_SIGHANDLER (BX_WITH_TERM)
-
-#define HAVE_SIGACTION 1
-
-// configure will change the definition of "inline" to the value
-// that the C compiler allows.  It tests the following keywords to
-// see if any is permitted: inline, __inline__, __inline.  If none
-// is permitted, it defines inline to be empty.
-#define inline inline
-
-// inline functions in headers that are compiled with C compiler
-// (e.g. fpu code) are declared with BX_C_INLINE macro.  Note that
-// the word "inline" itself may now be redefined by the above #define.
-// Many compilers are known to work with "static inline".  If the
-// compiler can put the function inline, it does so and never creates
-// a symbol for the function.  If optimization is off, or inline is
-// defined to be empty, the static keyword causes the function to create
-// a symbol that's visible only to that .c file.  Each .c file that
-// includes the header will produde another local version of the
-// BX_C_INLINE function (not ideal).  However without "static" you can
-// duplicate symbol problems which are even worse.
-#define BX_C_INLINE static inline
-
-// Use BX_CPP_INLINE for all C++ inline functions.  Note that the
-// word "inline" itself may now be redefined by the above #define.
-#define BX_CPP_INLINE inline
-
-#ifdef __GNUC__
-
-// Some helpful compiler hints for compilers that allow them; GCC for now.
-//
-// BX_CPP_AlignN(n):
-//   Align a construct on an n-byte boundary.
-//
-// BX_CPP_AttrPrintf(formatArg, firstArg):
-//   This function takes printf-like arguments, so the compiler can check
-//   the consistency of the format string and the matching arguments.
-//   'formatArg' is the parameter number (starting from 1) of the format
-//   string argument.  'firstArg' is the parameter number of the 1st argument
-//   to check against the string argument.  NOTE: For non-static member
-//   functions, the this-ptr is argument number 1 but is invisible on
-//   the function prototype declaration - but you still have to count it.
-//
-// BX_CPP_AttrNoReturn():
-//   This function never returns.  The compiler can optimize-out following
-//   code accordingly.
-
-#define BX_CPP_AlignN(n) __attribute__ ((aligned (n)))
-#define BX_CPP_AttrPrintf(formatArg, firstArg) \
-                          __attribute__ ((format (printf, formatArg, firstArg)))
-#define BX_CPP_AttrNoReturn() __attribute__ ((noreturn))
-
-#else
-
-#define BX_CPP_AlignN(n) /* Not supported. */
-#define BX_CPP_AttrPrintf(formatArg, firstArg)  /* Not supported. */
-#define BX_CPP_AttrNoReturn() /* Not supported. */
-
-#endif
-
-#define BX_DEBUGGER 0
-#define BX_DISASM 0
-
-#define BX_PROVIDE_CPU_MEMORY 1
-#define BX_PROVIDE_DEVICE_MODELS 1
-
-#define BX_SUPPORT_VBE 0
-
-#define BX_PROVIDE_MAIN       1
-
-#define BX_INSTRUMENTATION 0
-
-#define BX_USE_LOADER    0
-
-// for debugger, CPU simulator handle ID
-//   0 is the default, for using only one CPU simulator
-//   1 is for the 2nd CPU simulator
-#define BX_SIM_ID 0
-#define BX_NUM_SIMULATORS 1
-
-// limited i440FX PCI support
-#define BX_PCI_SUPPORT 1
-
-// Experimental VGA on PCI
-#define BX_PCI_VGA_SUPPORT 1
-
-// limited USB on PCI
-#define BX_PCI_USB_SUPPORT 1
-
-#if (BX_PCI_USB_SUPPORT && !BX_PCI_SUPPORT)
-#error To enable USB, you must also enable PCI
-#endif
-
-// Promise VLBIDE DC2300 Support
-#define BX_PDC20230C_VLBIDE_SUPPORT 0
-
-#define BX_SUPPORT_FPU 1
-#define BX_SUPPORT_MMX 1
-#define BX_SUPPORT_3DNOW 0
-#define BX_SUPPORT_SSE 0
-#define BX_SUPPORT_DAZ 0
-#define BX_SUPPORT_PNI 0
-#define BX_SUPPORT_SEP 0
-#define BX_SUPPORT_4MEG_PAGES 0
-
-#define BX_SupportGuest2HostTLB 0
-#define BX_SupportRepeatSpeedups 0
-#define BX_SupportGlobalPages 0
-#define BX_SupportPAE 0
-#define BX_SupportICache 0
-#define BX_SupportHostAsms 1
-
-
-// if 1, don't do gpf on MSRs that we don't implement
-#define BX_IGNORE_BAD_MSR 0
-
-// ========================================================
-// These are some very temporary hacks I made to the 64-bit
-// support to help Peter with debugging etc.  They will be removed
-// soon and there is no configure option for them (on purpose).
-// By default, they are not compiled in.
-
-// I set this to 1 to bail in instructions which may not be honoring
-// the 64-bit widths of RIP/RSP.  If I trip a panic, then I clean
-// the function up and remove the panic.  You don't have to use
-// these.
-#if 0
-#define BailBigRSP(s) \
-  if ( (RIP > 0xffffffff) || \
-       (RSP > 0xffffffff) ) \
-    BX_PANIC((s ": bailing due to big RSP value, mode==%u", \
-              BX_CPU_THIS_PTR cpu_mode))
-#else
-#define BailBigRSP(s)
-#endif
-// ========================================================
-
-
-#if (BX_SUPPORT_MMX && BX_CPU_LEVEL < 5)
-#error With CPU level < 5, you must disable MMX support.
-#endif
-
-#if (!BX_SUPPORT_FPU && BX_CPU_LEVEL >= 5)
-#error With CPU level >= 5, you must enable FPU support.
-#endif
-
-#if (BX_SUPPORT_MMX && !BX_SUPPORT_FPU)
-#error "MMX cannot be compiled without FPU support"
-#endif
-
-#if (BX_SUPPORT_3DNOW && !BX_SUPPORT_MMX)
-#error "3DNow! cannot be compiled without MMX support"
-#endif
-
-#if (BX_SUPPORT_SSE && !BX_SUPPORT_MMX)
-#error "SSE cannot be compiled without FPU+MMX support"
-#endif
-
-#if (BX_CPU_LEVEL<6 && BX_SUPPORT_SSE)
-#error SSE is only supported with CPU_LEVEL >= 6
-#endif
-
-#if (BX_SUPPORT_PNI && BX_SUPPORT_SSE <= 1)
-#error "PNI cannot be compiled without SSE/SSE2 support"
-#endif
-
-#if (BX_CPU_LEVEL<6 && BX_SUPPORT_SEP)
-#error SYSENTER/SYSEXIT only supported with CPU_LEVEL >= 6
-#endif
-
-#if BX_SUPPORT_X86_64
-// Sanity checks to ensure that you cannot accidently use conflicting options.
-
-#if BX_CPU_LEVEL < 5
-#error X86-64 requires cpu level 6 or greater
-#endif
-#if (BX_SUPPORT_SSE<2)
-#error X86-64 requires SSE2
-#endif
-#if !BX_SupportPAE
-#error X86-64 requires Physical Address Extensions (PAE)
-#endif
-#if !BX_SupportGlobalPages
-#error X86-64 requires Page Global Extension (PGE)
-#endif
-#if !BX_SUPPORT_4MEG_PAGES
-#error X86-64 requires Page Size Extension (PSE)
-#endif
-
-#if BX_SUPPORT_SEP
-#error SYSENTER/SYSEXIT not implemented for X86-64
-#endif
-
-#endif
-
-#define BX_HAVE_GETENV 1
-#define BX_HAVE_SETENV 1
-#define BX_HAVE_SELECT 1
-#define BX_HAVE_SNPRINTF 1
-#define BX_HAVE_STRTOULL 1
-#define BX_HAVE_STRTOUQ 1
-#define BX_HAVE_STRDUP 1
-#define BX_HAVE_STRREV 0
-#define BX_HAVE_STRUCT_TIMEVAL 1
-
-// used in term gui
-#define BX_HAVE_COLOR_SET 0
-#define BX_HAVE_MVHLINE 0
-#define BX_HAVE_MVVLINE 0
-
-
-// set if your compiler does not permit an empty struct
-#define BX_NO_EMPTY_STRUCTS 0
-
-// set if your compiler does not understand __attribute__ after a struct
-#define BX_NO_ATTRIBUTES 0
-#if BX_NO_ATTRIBUTES
-#define GCC_ATTRIBUTE(x) /* attribute not supported */
-#else
-#define GCC_ATTRIBUTE __attribute__
-#endif
-
-// set to use fast function calls
-#define BX_FAST_FUNC_CALL 0
-
-// On gcc2.95+ x86 only
-#if BX_FAST_FUNC_CALL && defined(__i386__) && defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95))
-#  define BX_CPP_AttrRegparmN(X) __attribute__((regparm(X)))
-#else
-#  define BX_CPP_AttrRegparmN(X) /* Not defined */
-#endif
-
-// set if your compiler does not allow label at the end of a {} block
-#define BX_NO_BLANK_LABELS 0
-
-// set if you do have <hash_map>, used in bx_debug/dbg_main.c
-#define BX_HAVE_HASH_MAP 0
-
-// set if you do have <hash_map.h>, used in bx_debug/dbg_main.c
-#define BX_HAVE_HASH_MAP_H 1
-
-// set if you do have <set>, used in bx_debug/dbg_main.c
-#define BX_HAVE_SET 1
-
-// set if you do have <set.h>, used in bx_debug/dbg_main.c
-#define BX_HAVE_SET_H 1
-
-// Support x86 hardware debugger registers and facilites.
-// These are the debug facilites offered by the x86 architecture,
-// not the optional built-in debugger.
-#define BX_X86_DEBUGGER 0
-
-#define BX_SUPPORT_CDROM 1
-
-#if BX_SUPPORT_CDROM
-   // This is the C++ class name to use if we are supporting
-   // low-level CDROM.
-#  define LOWLEVEL_CDROM cdrom_interface
-#endif
-
-// NE2K network emulation
-#define BX_NE2K_SUPPORT 1
-#define BX_ETH_NULL_LOGGING 1
-#define BX_ETH_FBSD_LOGGING 1
-
-// determine which NE2K packet mover modules will be enabled
-// (this was moved from iodev/eth.h)
-#define ETH_NULL  1
-#ifdef BX_USE_ETH_ARPBACK
-#  define ETH_ARPBACK 1
-#endif
-#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__)
-#define ETH_FBSD  1
-#endif
-#if defined(linux)
-#define ETH_LINUX 1
-#endif
-#if defined(WIN32)
-#define ETH_WIN32 1
-#endif
-
-// this enables Ethertap packet mover; determined by configure script
-#define HAVE_ETHERTAP 0
-
-// this enables TUN/TAP packet mover; determined by configure script
-#define HAVE_TUNTAP 1
-
-
-// I/O Interface to debug
-#define BX_IODEBUG_SUPPORT 0
-
-// External Debugger
-#define BX_EXTERNAL_DEBUGGER 0
-#define BX_OVERRIDE_ASK 0
-
-#ifdef WIN32
-#define BX_FLOPPY0_NAME "Floppy Disk A:"
-#define BX_FLOPPY1_NAME "Floppy Disk B:"
-#else
-#define BX_FLOPPY0_NAME "Floppy Disk 0"
-#define BX_FLOPPY1_NAME "Floppy Disk 1"
-#endif
-
-// This is handy for certain performance testing purposes, but otherwise
-// totally useless.  If you define BX_SCHEDULED_DIE_TIME then it enables code
-// in bx_pit_c::periodic that will cause Bochs to exit() after a certain number
-// of instructions.
-//#define BX_SCHEDULED_DIE_TIME 1162230000   // end of redhat6.0 boot
-
-
-#endif  // _BX_CONFIG_H
diff --git a/tools/ioemu/include/cpu/cpu.h b/tools/ioemu/include/cpu/cpu.h
deleted file mode 100644 (file)
index 0627ee3..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: cpu.h,v 1.155 2003/12/30 22:12:45 cbothamy Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2001  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-#ifndef BX_CPU_H
-#  define BX_CPU_H 1
-
-#include <setjmp.h>
-#ifdef BX_USE_VMX
-extern "C" {
-#include <io/ioreq.h>
-}
-#endif
-
-
-#if BX_SUPPORT_APIC
-#define BX_CPU_INTR             (BX_CPU_THIS_PTR INTR || BX_CPU_THIS_PTR local_apic.INTR)
-#else
-#define BX_CPU_INTR             BX_CPU_THIS_PTR INTR
-#endif
-
-class BX_CPU_C;
-class BX_MEM_C;
-
-#if BX_USE_CPU_SMF == 0
-// normal member functions.  This can ONLY be used within BX_CPU_C classes.
-// Anyone on the outside should use the BX_CPU macro (defined in bochs.h)
-// instead.
-#  define BX_CPU_THIS_PTR  this->
-#  define BX_CPU_THIS      this
-#  define BX_SMF
-#  define BX_CPU_C_PREFIX  BX_CPU_C::
-// with normal member functions, calling a member fn pointer looks like
-// object->*(fnptr)(arg, ...);
-// Since this is different from when SMF=1, encapsulate it in a macro.
-#  define BX_CPU_CALL_METHOD(func, args) \
-            (this->*((BxExecutePtr_t) (func))) args
-#  define BX_CPU_CALL_METHODR(func, args) \
-            (this->*((BxExecutePtr_tR) (func))) args
-#else
-// static member functions.  With SMF, there is only one CPU by definition.
-#  define BX_CPU_THIS_PTR  BX_CPU(0)->
-#  define BX_CPU_THIS      BX_CPU(0)
-#  define BX_SMF           static
-#  define BX_CPU_C_PREFIX
-#  define BX_CPU_CALL_METHOD(func, args) \
-            ((BxExecutePtr_t) (func)) args
-#  define BX_CPU_CALL_METHODR(func, args) \
-            ((BxExecutePtr_tR) (func)) args
-#endif
-
-#if BX_SMP_PROCESSORS==1
-// single processor simulation, so there's one of everything
-BOCHSAPI extern BX_CPU_C       bx_cpu;
-#else
-// multiprocessor simulation, we need an array of cpus and memories
-BOCHSAPI extern BX_CPU_C       *bx_cpu_array[BX_SMP_PROCESSORS];
-#endif
-
-class BOCHSAPI BX_CPU_C : public logfunctions {
-
-public: // for now...
-
-  volatile bx_bool async_event;
-  volatile bx_bool INTR;
-  volatile bx_bool kill_bochs_request;
-
-  // constructors & destructors...
-  BX_CPU_C();
-  ~BX_CPU_C(void);
-  void init (BX_MEM_C *addrspace);
-  void interrupt(Bit8u vector);
-
-  BX_SMF void pagingA20Changed(void);
-  BX_SMF void reset(unsigned source);
-  BX_SMF void set_INTR(bx_bool value);
-  BX_SMF void     atexit(void);
-
-  // now for some ancillary functions...
-  void cpu_loop(Bit32s max_instr_count);
-
-#ifdef BX_USE_VMX
-  ioreq_t*     __get_ioreq(void);
-  ioreq_t*     get_ioreq(void);
-  void                 dispatch_ioreq(ioreq_t *req);
-  void         handle_ioreq();
-  void         timer_handler();
-
-  int send_event;
-#endif
-};
-
-#endif  // #ifndef BX_CPU_H
diff --git a/tools/ioemu/include/extplugin.h b/tools/ioemu/include/extplugin.h
deleted file mode 100644 (file)
index f3e43f7..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: extplugin.h,v 1.4 2002/12/12 15:28:37 cbothamy Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-// extplugin.h
-//
-// This header file defines the types necessary to make a Bochs plugin,
-// but without mentioning all the details of Bochs internals (bochs.h).  
-// It is included by the configuration interfaces and possibly other 
-// things which are intentionally isolated from other parts of the program.
-//
-// The plugin_t struct comes from the plugin.h file from plex86.
-// Plex86 is Copyright (C) 1999-2000  The plex86 developers team
-//
-/////////////////////////////////////////////////////////////////////////
-
-#ifndef __EXTPLUGIN_H
-#define __EXTPLUGIN_H
-
-#if BX_PLUGINS
-#include "ltdl.h"
-#endif
-
-enum plugintype_t {
-  PLUGTYPE_NULL=100,
-  PLUGTYPE_CORE,
-  PLUGTYPE_OPTIONAL,
-  PLUGTYPE_USER
-};
-
-#define MAX_ARGC 10
-
-typedef struct _plugin_t
-{
-    plugintype_t type;
-    int  initialized;
-#if BX_PLUGINS
-    lt_dlhandle handle;
-#endif
-    int  argc;
-    char *name, *args, *argv[MAX_ARGC];
-    int  (*plugin_init)(struct _plugin_t *plugin, plugintype_t type, int argc, char *argv[]);
-    void (*plugin_fini)(void);
-
-    struct _plugin_t *next;
-} plugin_t;
-
-
-
-#endif /* __EXTPLUGIN_H */
-
diff --git a/tools/ioemu/include/instrument.h b/tools/ioemu/include/instrument.h
deleted file mode 100644 (file)
index 8d753ff..0000000
+++ /dev/null
@@ -1,256 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: instrument.h,v 1.14 2003/10/09 19:05:13 sshwarts Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2001  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-// possible types passed to BX_INSTR_TLB_CNTRL()
-#define BX_INSTR_MOV_CR3      10
-#define BX_INSTR_INVLPG       11
-#define BX_INSTR_TASKSWITCH   12
-
-// possible types passed to BX_INSTR_CACHE_CNTRL()
-#define BX_INSTR_INVD         20
-#define BX_INSTR_WBINVD       21
-
-#define BX_INSTR_IS_CALL  10
-#define BX_INSTR_IS_RET   11
-#define BX_INSTR_IS_IRET  12
-#define BX_INSTR_IS_JMP   13
-#define BX_INSTR_IS_INT   14
-
-#define BX_INSTR_PREFETCH_NTA 00
-#define BX_INSTR_PREFETCH_T0  01
-#define BX_INSTR_PREFETCH_T1  02
-#define BX_INSTR_PREFETCH_T2  03
-
-
-
-
-
-#if BX_INSTRUMENTATION
-
-class bxInstruction_c;
-
-// called from the CPU core
-
-void bx_instr_init(unsigned cpu);
-void bx_instr_shutdown(unsigned cpu);
-void bx_instr_reset(unsigned cpu);
-void bx_instr_new_instruction(unsigned cpu);
-
-void bx_instr_debug_promt();
-void bx_instr_start();
-void bx_instr_stop();
-void bx_instr_print();
-
-void bx_instr_cnear_branch_taken(unsigned cpu, bx_address new_eip);
-void bx_instr_cnear_branch_not_taken(unsigned cpu);
-void bx_instr_ucnear_branch(unsigned cpu, unsigned what, bx_address new_eip);
-void bx_instr_far_branch(unsigned cpu, unsigned what, Bit16u new_cs, bx_address new_eip);
-
-void bx_instr_opcode(unsigned cpu, Bit8u *opcode, unsigned len, bx_bool is32);
-void bx_instr_fetch_decode_completed(unsigned cpu, const bxInstruction_c *i);
-
-void bx_instr_prefix_as(unsigned cpu);
-void bx_instr_prefix_os(unsigned cpu);
-void bx_instr_prefix_rep(unsigned cpu);
-void bx_instr_prefix_repne(unsigned cpu);
-void bx_instr_prefix_lock(unsigned cpu);
-void bx_instr_prefix_cs(unsigned cpu);
-void bx_instr_prefix_ss(unsigned cpu);
-void bx_instr_prefix_ds(unsigned cpu);
-void bx_instr_prefix_es(unsigned cpu);
-void bx_instr_prefix_fs(unsigned cpu);
-void bx_instr_prefix_gs(unsigned cpu);
-void bx_instr_prefix_extend8b(unsigned cpu);
-
-void bx_instr_interrupt(unsigned cpu, unsigned vector);
-void bx_instr_exception(unsigned cpu, unsigned vector);
-void bx_instr_hwinterrupt(unsigned cpu, unsigned vector, Bit16u cs, bx_address eip);
-
-void bx_instr_tlb_cntrl(unsigned cpu, unsigned what, Bit32u newval);
-void bx_instr_cache_cntrl(unsigned cpu, unsigned what);
-void bx_instr_prefetch_hint(unsigned cpu, unsigned what, unsigned seg, bx_address offset);
-
-void bx_instr_before_execution(unsigned cpu);
-void bx_instr_after_execution(unsigned cpu);
-void bx_instr_repeat_iteration(unsigned cpu);
-
-void bx_instr_inp(Bit16u addr, unsigned len);
-void bx_instr_outp(Bit16u addr, unsigned len);
-void bx_instr_inp2(Bit16u addr, unsigned len, unsigned val);
-void bx_instr_outp2(Bit16u addr, unsigned len, unsigned val);
-
-void bx_instr_mem_code(unsigned cpu, bx_address linear, unsigned size);
-void bx_instr_mem_data(unsigned cpu, bx_address linear, unsigned size, unsigned rw);
-
-void bx_instr_lin_read(unsigned cpu, bx_address lin, bx_address phy, unsigned len);
-void bx_instr_lin_write(unsigned cpu, bx_address lin, bx_address phy, unsigned len);
-
-void bx_instr_phy_write(unsigned cpu, bx_address addr, unsigned len);
-void bx_instr_phy_read(unsigned cpu, bx_address addr, unsigned len);
-
-/* simulation init, shutdown, reset */
-#  define BX_INSTR_INIT(cpu_id)            bx_instr_init(cpu_id)
-#  define BX_INSTR_SHUTDOWN(cpu_id)        bx_instr_shutdown(cpu_id)
-#  define BX_INSTR_RESET(cpu_id)           bx_instr_reset(cpu_id)
-#  define BX_INSTR_NEW_INSTRUCTION(cpu_id) bx_instr_new_instruction(cpu_id)
-
-/* called from command line debugger */
-#  define BX_INSTR_DEBUG_PROMPT()          bx_instr_debug_promt()
-#  define BX_INSTR_START()                 bx_instr_start()
-#  define BX_INSTR_STOP()                  bx_instr_stop()
-#  define BX_INSTR_PRINT()                 bx_instr_print()
-
-/* branch resoultion */
-#  define BX_INSTR_CNEAR_BRANCH_TAKEN(cpu_id, new_eip)       bx_instr_cnear_branch_taken(cpu_id, new_eip)
-#  define BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(cpu_id)   bx_instr_cnear_branch_not_taken(cpu_id)
-#  define BX_INSTR_UCNEAR_BRANCH(cpu_id, what, new_eip)      bx_instr_ucnear_branch(cpu_id, what, new_eip)
-#  define BX_INSTR_FAR_BRANCH(cpu_id, what, new_cs, new_eip) bx_instr_far_branch(cpu_id, what, new_cs, new_eip)
-
-/* decoding completed */
-#  define BX_INSTR_OPCODE(cpu_id, opcode, len, is32) \
-                       bx_instr_opcode(cpu_id, opcode, len, is32)
-#  define BX_INSTR_FETCH_DECODE_COMPLETED(cpu_id, i) \
-                       bx_instr_fetch_decode_completed(cpu_id, i)
-     
-/* prefix decoded */
-#  define BX_INSTR_PREFIX_AS(cpu_id)       bx_instr_prefix_as(cpu_id)
-#  define BX_INSTR_PREFIX_OS(cpu_id)       bx_instr_prefix_os(cpu_id)
-#  define BX_INSTR_PREFIX_REP(cpu_id)      bx_instr_prefix_rep(cpu_id)
-#  define BX_INSTR_PREFIX_REPNE(cpu_id)    bx_instr_prefix_repne(cpu_id)
-#  define BX_INSTR_PREFIX_LOCK(cpu_id)     bx_instr_prefix_lock(cpu_id)
-#  define BX_INSTR_PREFIX_CS(cpu_id)       bx_instr_prefix_cs(cpu_id)
-#  define BX_INSTR_PREFIX_SS(cpu_id)       bx_instr_prefix_ss(cpu_id)
-#  define BX_INSTR_PREFIX_DS(cpu_id)       bx_instr_prefix_ds(cpu_id)
-#  define BX_INSTR_PREFIX_ES(cpu_id)       bx_instr_prefix_es(cpu_id)
-#  define BX_INSTR_PREFIX_FS(cpu_id)       bx_instr_prefix_fs(cpu_id)
-#  define BX_INSTR_PREFIX_GS(cpu_id)       bx_instr_prefix_gs(cpu_id)
-#  define BX_INSTR_PREFIX_EXTEND8B(cpu_id) bx_instr_prefix_extend8b(cpu_id)
-
-/* exceptional case and interrupt */
-#  define BX_INSTR_EXCEPTION(cpu_id, vector)            bx_instr_exception(cpu_id, vector)
-#  define BX_INSTR_INTERRUPT(cpu_id, vector)            bx_instr_interrupt(cpu_id, vector)
-#  define BX_INSTR_HWINTERRUPT(cpu_id, vector, cs, eip) bx_instr_hwinterrupt(cpu_id, vector, cs, eip)
-
-/* TLB/CACHE control instruction executed */
-#  define BX_INSTR_CACHE_CNTRL(cpu_id, what)            bx_instr_cache_cntrl(cpu_id, what)
-#  define BX_INSTR_TLB_CNTRL(cpu_id, what, newval)      bx_instr_tlb_cntrl(cpu_id, what, newval)
-#  define BX_INSTR_PREFETCH_HINT(cpu_id, what, seg, offset) \
-                       bx_instr_prefetch_hint(cpu_id, what, seg, offset)
-
-/* execution */
-#  define BX_INSTR_BEFORE_EXECUTION(cpu_id)             bx_instr_before_execution(cpu_id)
-#  define BX_INSTR_AFTER_EXECUTION(cpu_id)              bx_instr_after_execution(cpu_id)
-#  define BX_INSTR_REPEAT_ITERATION(cpu_id)             bx_instr_repeat_iteration(cpu_id)
-
-/* memory access */
-#  define BX_INSTR_LIN_READ(cpu_id, lin, phy, len)      bx_instr_lin_read(cpu_id, lin, phy, len)
-#  define BX_INSTR_LIN_WRITE(cpu_id, lin, phy, len)     bx_instr_lin_write(cpu_id, lin, phy, len)
-
-#  define BX_INSTR_MEM_CODE(cpu_id, linear, size)       bx_instr_mem_code(cpu_id, linear, size)
-#  define BX_INSTR_MEM_DATA(cpu_id, linear, size, rw)   bx_instr_mem_data(cpu_id, linear, size, rw)
-
-/* called from memory object */
-#  define BX_INSTR_PHY_WRITE(cpu_id, addr, len)         bx_instr_phy_write(cpu_id, addr, len)
-#  define BX_INSTR_PHY_READ(cpu_id, addr, len)          bx_instr_phy_read(cpu_id, addr, len)
-
-/* feedback from device units */
-#  define BX_INSTR_INP(addr, len)               bx_instr_inp(addr, len)
-#  define BX_INSTR_INP2(addr, len, val)         bx_instr_inp2(addr, len, val)
-#  define BX_INSTR_OUTP(addr, len)              bx_instr_outp(addr, len)
-#  define BX_INSTR_OUTP2(addr, len, val)        bx_instr_outp2(addr, len, val)
-
-#else   
-
-/* simulation init, shutdown, reset */
-#  define BX_INSTR_INIT(cpu_id)
-#  define BX_INSTR_SHUTDOWN(cpu_id)
-#  define BX_INSTR_RESET(cpu_id)
-#  define BX_INSTR_NEW_INSTRUCTION(cpu_id)
-
-/* called from command line debugger */
-#  define BX_INSTR_DEBUG_PROMPT()
-#  define BX_INSTR_START()
-#  define BX_INSTR_STOP()
-#  define BX_INSTR_PRINT()
-
-/* branch resoultion */
-#  define BX_INSTR_CNEAR_BRANCH_TAKEN(cpu_id, new_eip)
-#  define BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(cpu_id)
-#  define BX_INSTR_UCNEAR_BRANCH(cpu_id, what, new_eip)
-#  define BX_INSTR_FAR_BRANCH(cpu_id, what, new_cs, new_eip)
-
-/* decoding completed */
-#  define BX_INSTR_OPCODE(cpu_id, opcode, len, is32) 
-#  define BX_INSTR_FETCH_DECODE_COMPLETED(cpu_id, i)
-     
-/* prefix decoded */
-#  define BX_INSTR_PREFIX_AS(cpu_id)
-#  define BX_INSTR_PREFIX_OS(cpu_id)
-#  define BX_INSTR_PREFIX_REP(cpu_id)
-#  define BX_INSTR_PREFIX_REPNE(cpu_id)
-#  define BX_INSTR_PREFIX_LOCK(cpu_id)
-#  define BX_INSTR_PREFIX_CS(cpu_id)
-#  define BX_INSTR_PREFIX_SS(cpu_id)
-#  define BX_INSTR_PREFIX_DS(cpu_id)
-#  define BX_INSTR_PREFIX_ES(cpu_id)
-#  define BX_INSTR_PREFIX_FS(cpu_id)
-#  define BX_INSTR_PREFIX_GS(cpu_id)
-#  define BX_INSTR_PREFIX_EXTEND8B(cpu_id)
-
-/* exceptional case and interrupt */
-#  define BX_INSTR_EXCEPTION(cpu_id, vector)
-#  define BX_INSTR_INTERRUPT(cpu_id, vector)
-#  define BX_INSTR_HWINTERRUPT(cpu_id, vector, cs, eip)
-
-/* TLB/CACHE control instruction executed */
-#  define BX_INSTR_CACHE_CNTRL(cpu_id, what)
-#  define BX_INSTR_TLB_CNTRL(cpu_id, what, newval)
-#  define BX_INSTR_PREFETCH_HINT(cpu_id, what, seg, offset)
-
-/* execution */
-#  define BX_INSTR_BEFORE_EXECUTION(cpu_id)
-#  define BX_INSTR_AFTER_EXECUTION(cpu_id)
-#  define BX_INSTR_REPEAT_ITERATION(cpu_id)
-
-/* memory access */
-#  define BX_INSTR_LIN_READ(cpu_id, lin, phy, len)
-#  define BX_INSTR_LIN_WRITE(cpu_id, lin, phy, len)
-
-#  define BX_INSTR_MEM_CODE(cpu_id, linear, size)      
-#  define BX_INSTR_MEM_DATA(cpu_id, linear, size, rw)
-
-/* called from memory object */
-#  define BX_INSTR_PHY_WRITE(cpu_id, addr, len)
-#  define BX_INSTR_PHY_READ(cpu_id, addr, len)
-
-/* feedback from device units */
-#  define BX_INSTR_INP(addr, len)
-#  define BX_INSTR_INP2(addr, len, val)
-#  define BX_INSTR_OUTP(addr, len)
-#  define BX_INSTR_OUTP2(addr, len, val)
-
-#endif  
diff --git a/tools/ioemu/include/ltdl.h b/tools/ioemu/include/ltdl.h
deleted file mode 100644 (file)
index 3a02b31..0000000
+++ /dev/null
@@ -1,398 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: ltdl.h,v 1.2 2002/10/24 21:04:37 bdenney Exp $
-//
-// NOTE: The ltdl library comes from the Libtool package.  Bochs uses
-// ltdl and libtool to build and load plugins.  The libtool
-// documentation describes how to copy ltdl.c and ltdl.h into your
-// distribution, so it is clearly legal to do so.
-/////////////////////////////////////////////////////////////////////////
-
-/* ltdl.h -- generic dlopen functions
-   Copyright (C) 1998-2000 Free Software Foundation, Inc.
-   Originally by Thomas Tanner <tanner@ffii.org>
-   This file is part of GNU Libtool.
-
-This library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Lesser General Public
-License as published by the Free Software Foundation; either
-version 2 of the License, or (at your option) any later version.
-
-As a special exception to the GNU Lesser General Public License,
-if you distribute this file as part of a program or library that
-is built using GNU libtool, you may include it under the same
-distribution terms that you use for the rest of that program.
-
-This library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public
-License along with this library; if not, write to the Free
-Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-02111-1307  USA
-*/
-
-/* Only include this header file once. */
-#ifndef LTDL_H
-#define LTDL_H 1
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-#include <sys/types.h>         /* for size_t declaration */
-#ifdef __cplusplus
-};
-#endif
-
-\f
-/* --- MACROS FOR PORTABILITY --- */
-
-
-/* Saves on those hard to debug '\0' typos....  */
-#define LT_EOS_CHAR    '\0'
-
-/* LTDL_BEGIN_C_DECLS should be used at the beginning of your declarations,
-   so that C++ compilers don't mangle their names.  Use LTDL_END_C_DECLS at
-   the end of C declarations. */
-#ifdef __cplusplus
-# define LT_BEGIN_C_DECLS      extern "C" {
-# define LT_END_C_DECLS                }
-#else
-# define LT_BEGIN_C_DECLS      /* empty */
-# define LT_END_C_DECLS                /* empty */
-#endif
-
-LT_BEGIN_C_DECLS
-
-
-/* LT_PARAMS is a macro used to wrap function prototypes, so that compilers
-   that don't understand ANSI C prototypes still work, and ANSI C
-   compilers can issue warnings about type mismatches.  */
-#if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(WIN32) || defined(__cplusplus)
-# define LT_PARAMS(protos)     protos
-# define lt_ptr                void*
-#else
-# define LT_PARAMS(protos)     ()
-# define lt_ptr                char*
-#endif
-
-/* LT_STMT_START/END are used to create macros which expand to a
-   a single compound statement in a portable way.  */
-#if defined (__GNUC__) && !defined (__STRICT_ANSI__) && !defined (__cplusplus)
-#  define LT_STMT_START        (void)(
-#  define LT_STMT_END          )
-#else
-#  if (defined (sun) || defined (__sun__))
-#    define LT_STMT_START      if (1)
-#    define LT_STMT_END        else (void)0
-#  else
-#    define LT_STMT_START      do
-#    define LT_STMT_END        while (0)
-#  endif
-#endif
-
-/* LT_CONC creates a new concatenated symbol for the compiler
-   in a portable way.  */
-#if defined(__STDC__) || defined(__cplusplus)
-#  define LT_CONC(s,t) s##t
-#else
-#  define LT_CONC(s,t) s/**/t
-#endif
-
-/* LT_STRLEN can be used safely on NULL pointers.  */
-#define LT_STRLEN(s)   (((s) && (s)[0]) ? strlen (s) : 0)
-
-
-\f
-/* --- WINDOWS SUPPORT --- */
-
-
-/* Canonicalise Windows and Cygwin recognition macros.  */
-#ifdef __CYGWIN32__
-#  ifndef __CYGWIN__
-#    define __CYGWIN__ __CYGWIN32__
-#  endif
-#endif
-#if defined(_WIN32) || defined(WIN32)
-#  ifndef __WINDOWS__
-#    ifdef _WIN32
-#      define __WINDOWS__ _WIN32
-#    else
-#      ifdef WIN32
-#        define __WINDOWS__ WIN32
-#      endif
-#    endif
-#  endif
-#endif
-
-#ifdef __WINDOWS__
-#  ifndef __CYGWIN__
-/* LT_DIRSEP_CHAR is accepted *in addition* to '/' as a directory
-   separator when it is set. */
-#    define LT_DIRSEP_CHAR     '\\'
-#    define LT_PATHSEP_CHAR    ';'
-#  endif
-#endif
-#ifndef LT_PATHSEP_CHAR
-#  define LT_PATHSEP_CHAR      ':'
-#endif
-
-/* DLL building support on win32 hosts;  mostly to workaround their
-   ridiculous implementation of data symbol exporting. */
-#ifndef LT_SCOPE
-#  ifdef __WINDOWS__
-#    ifdef DLL_EXPORT          /* defined by libtool (if required) */
-#      define LT_SCOPE __declspec(dllexport)
-#    endif
-#    ifdef LIBLTDL_DLL_IMPORT  /* define if linking with this dll */
-#      define LT_SCOPE extern __declspec(dllimport)
-#    endif
-#  endif
-#  ifndef LT_SCOPE             /* static linking or !__WINDOWS__ */
-#    define LT_SCOPE   extern
-#  endif
-#endif
-
-
-
-\f
-/* --- DYNAMIC MODULE LOADING API --- */
-
-
-typedef        struct lt_dlhandle_struct *lt_dlhandle; /* A loaded module.  */
-
-/* Initialisation and finalisation functions for libltdl. */
-extern int         lt_dlinit           LT_PARAMS((void));
-extern int         lt_dlexit           LT_PARAMS((void));
-
-/* Module search path manipulation.  */
-extern int         lt_dladdsearchdir    LT_PARAMS((const char *search_dir));
-extern int         lt_dlinsertsearchdir LT_PARAMS((const char *before,
-                                                   const char *search_dir));
-extern int         lt_dlsetsearchpath   LT_PARAMS((const char *search_path));
-extern const char *lt_dlgetsearchpath   LT_PARAMS((void));
-extern int         lt_dlforeachfile     LT_PARAMS((
-                       const char *search_path,
-                       int (*func) (const char *filename, lt_ptr data),
-                       lt_ptr data));
-
-/* Portable libltdl versions of the system dlopen() API. */
-extern lt_dlhandle lt_dlopen           LT_PARAMS((const char *filename));
-extern lt_dlhandle lt_dlopenext        LT_PARAMS((const char *filename));
-extern lt_ptr      lt_dlsym            LT_PARAMS((lt_dlhandle handle,
-                                                    const char *name));
-extern const char *lt_dlerror          LT_PARAMS((void));
-extern int         lt_dlclose          LT_PARAMS((lt_dlhandle handle));
-
-/* Module residency management. */
-extern int         lt_dlmakeresident   LT_PARAMS((lt_dlhandle handle));
-extern int         lt_dlisresident     LT_PARAMS((lt_dlhandle handle));
-
-
-
-\f
-/* --- MUTEX LOCKING --- */
-
-
-typedef void   lt_dlmutex_lock         LT_PARAMS((void));
-typedef void   lt_dlmutex_unlock       LT_PARAMS((void));
-typedef void   lt_dlmutex_seterror     LT_PARAMS((const char *errmsg));
-typedef const char *lt_dlmutex_geterror        LT_PARAMS((void));
-
-extern int     lt_dlmutex_register     LT_PARAMS((lt_dlmutex_lock *lock,
-                                           lt_dlmutex_unlock *unlock,
-                                           lt_dlmutex_seterror *seterror,
-                                           lt_dlmutex_geterror *geterror));
-
-
-
-\f
-/* --- MEMORY HANDLING --- */
-
-
-/* By default, the realloc function pointer is set to our internal
-   realloc implementation which iself uses lt_dlmalloc and lt_dlfree.
-   libltdl relies on a featureful realloc, but if you are sure yours
-   has the right semantics then you can assign it directly.  Generally,
-   it is safe to assign just a malloc() and a free() function.  */
-LT_SCOPE  lt_ptr   (*lt_dlmalloc)      LT_PARAMS((size_t size));
-LT_SCOPE  lt_ptr   (*lt_dlrealloc)     LT_PARAMS((lt_ptr ptr, size_t size));
-LT_SCOPE  void    (*lt_dlfree)         LT_PARAMS((lt_ptr ptr));
-
-
-
-\f
-/* --- PRELOADED MODULE SUPPORT --- */
-
-
-/* A preopened symbol. Arrays of this type comprise the exported
-   symbols for a dlpreopened module. */
-typedef struct {
-  const char *name;
-  lt_ptr      address;
-} lt_dlsymlist;
-
-extern int     lt_dlpreload    LT_PARAMS((const lt_dlsymlist *preloaded));
-extern int     lt_dlpreload_default
-                               LT_PARAMS((const lt_dlsymlist *preloaded));
-
-#define LTDL_SET_PRELOADED_SYMBOLS()           LT_STMT_START{  \
-       extern const lt_dlsymlist lt_preloaded_symbols[];               \
-       lt_dlpreload_default(lt_preloaded_symbols);                     \
-                                               }LT_STMT_END
-
-
-
-\f
-/* --- MODULE INFORMATION --- */
-
-
-/* Read only information pertaining to a loaded module. */
-typedef        struct {
-  char *filename;              /* file name */
-  char *name;                  /* module name */
-  int  ref_count;              /* number of times lt_dlopened minus
-                                  number of times lt_dlclosed. */
-} lt_dlinfo;
-
-extern const lt_dlinfo *lt_dlgetinfo       LT_PARAMS((lt_dlhandle handle));
-extern lt_dlhandle     lt_dlhandle_next    LT_PARAMS((lt_dlhandle place));
-extern int             lt_dlforeach        LT_PARAMS((
-                               int (*func) (lt_dlhandle handle, lt_ptr data),
-                               lt_ptr data));
-
-/* Associating user data with loaded modules. */
-typedef unsigned lt_dlcaller_id;
-
-extern lt_dlcaller_id  lt_dlcaller_register  LT_PARAMS((void));
-extern lt_ptr          lt_dlcaller_set_data  LT_PARAMS((lt_dlcaller_id key,
-                                               lt_dlhandle handle,
-                                               lt_ptr data));
-extern lt_ptr          lt_dlcaller_get_data  LT_PARAMS((lt_dlcaller_id key,
-                                               lt_dlhandle handle));
-
-
-\f
-/* --- USER MODULE LOADER API --- */
-
-
-typedef        struct lt_dlloader      lt_dlloader;
-typedef lt_ptr                 lt_user_data;
-typedef lt_ptr                 lt_module;
-
-/* Function pointer types for creating user defined module loaders. */
-typedef lt_module   lt_module_open     LT_PARAMS((lt_user_data loader_data,
-                                           const char *filename));
-typedef int        lt_module_close     LT_PARAMS((lt_user_data loader_data,
-                                           lt_module handle));
-typedef lt_ptr     lt_find_sym         LT_PARAMS((lt_user_data loader_data,
-                                           lt_module handle,
-                                           const char *symbol));
-typedef int        lt_dlloader_exit    LT_PARAMS((lt_user_data loader_data));
-
-struct lt_user_dlloader {
-  const char          *sym_prefix;
-  lt_module_open       *module_open;
-  lt_module_close      *module_close;
-  lt_find_sym         *find_sym;
-  lt_dlloader_exit     *dlloader_exit;
-  lt_user_data         dlloader_data;
-};
-
-extern lt_dlloader    *lt_dlloader_next    LT_PARAMS((lt_dlloader *place));
-extern lt_dlloader    *lt_dlloader_find    LT_PARAMS((
-                                               const char *loader_name));
-extern const char     *lt_dlloader_name    LT_PARAMS((lt_dlloader *place));
-extern lt_user_data   *lt_dlloader_data    LT_PARAMS((lt_dlloader *place));
-extern int             lt_dlloader_add     LT_PARAMS((lt_dlloader *place,
-                               const struct lt_user_dlloader *dlloader,
-                               const char *loader_name));
-extern int             lt_dlloader_remove  LT_PARAMS((
-                                               const char *loader_name));
-
-
-\f
-/* --- ERROR MESSAGE HANDLING --- */
-
-/* Bryce rewrote the error table in a way that would be likely to work
-   on all compilers.  VC++ was not able to handle it the way it was
-   done originally. */
-
-/* ORIG COMMENT: Defining error strings alongside their symbolic names in a
-   macro in this way allows us to expand the macro in different contexts with
-   confidence that the enumeration of symbolic names will map correctly
-   onto the table of error strings.  */
-
-#define lt_dlerror_symbols_list                                                \
-  LT_ERROR_UNKNOWN,                                                    \
-  LT_ERROR_DLOPEN_NOT_SUPPORTED,                                       \
-  LT_ERROR_INVALID_LOADER,                                             \
-  LT_ERROR_INIT_LOADER,                                                        \
-  LT_ERROR_REMOVE_LOADER,                                              \
-  LT_ERROR_FILE_NOT_FOUND,                                             \
-  LT_ERROR_DEPLIB_NOT_FOUND,                                           \
-  LT_ERROR_NO_SYMBOLS,                                                 \
-  LT_ERROR_CANNOT_OPEN,                                                        \
-  LT_ERROR_CANNOT_CLOSE,                                               \
-  LT_ERROR_SYMBOL_NOT_FOUND,                                           \
-  LT_ERROR_NO_MEMORY,                                                  \
-  LT_ERROR_INVALID_HANDLE,                                             \
-  LT_ERROR_BUFFER_OVERFLOW,                                            \
-  LT_ERROR_INVALID_ERRORCODE,                                          \
-  LT_ERROR_SHUTDOWN,                                                   \
-  LT_ERROR_CLOSE_RESIDENT_MODULE,                                      \
-  LT_ERROR_INVALID_MUTEX_ARGS,                                         \
-  LT_ERROR_INVALID_POSITION,
-
-#define lt_dlerror_names_list                                          \
-    "unknown error",                                                   \
-    "dlopen support not available",                                    \
-    "invalid loader",                                                  \
-    "loader initialization failed",                                    \
-    "loader removal failed",                                           \
-    "file not found",                                                  \
-    "dependency library not found",                                    \
-    "no symbols defined",                                              \
-    "can't open the module",                                           \
-    "can't close the module",                                          \
-    "symbol not found",                                                        \
-    "not enough memory",                                               \
-    "invalid module handle",                                           \
-    "internal buffer overflow",                                                \
-    "invalid errorcode",                                               \
-    "library already shutdown",                                                \
-    "can't close resident module",                                     \
-    "invalid mutex handler registration",                              \
-    "invalid search path insert position",
-
-/* Enumerate the symbolic error names. */
-enum {
-       lt_dlerror_symbols_list
-       LT_ERROR_MAX
-};
-
-/* These functions are only useful from inside custom module loaders. */
-extern int     lt_dladderror   LT_PARAMS((const char *diagnostic));
-extern int     lt_dlseterror   LT_PARAMS((int errorcode));
-
-
-
-\f
-/* --- SOURCE COMPATIBILITY WITH OLD LIBLTDL --- */
-
-
-#ifdef LT_NON_POSIX_NAMESPACE
-#  define lt_ptr_t             lt_ptr
-#  define lt_module_t          lt_module
-#  define lt_module_open_t     lt_module_open
-#  define lt_module_close_t    lt_module_close
-#  define lt_find_sym_t                lt_find_sym
-#  define lt_dlloader_exit_t   lt_dlloader_exit
-#  define lt_dlloader_t                lt_dlloader
-#  define lt_dlloader_data_t   lt_user_data
-#endif
-
-LT_END_C_DECLS
-
-#endif /* !LTDL_H */
diff --git a/tools/ioemu/include/ltdlconf.h b/tools/ioemu/include/ltdlconf.h
deleted file mode 100644 (file)
index 5ffd0e7..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-/* ltdlconf.h.  Generated by configure.  */
-/////////////////////////////////////////////////////////////////////////
-// $Id: ltdlconf.h.in,v 1.2 2002/10/24 21:04:38 bdenney Exp $
-//
-// The configure script reads this file and produces ltdlconf.h, which
-// tells ltdl.c how to compile.  It was copied out of the libtool package
-// but appears to have been generated by autoheader.
-/////////////////////////////////////////////////////////////////////////
-
-/* config-h.in.  Generated automatically from configure.in by autoheader.  */
-
-/* Define to empty if the keyword does not work.  */
-/* #undef const */
-
-/* Define as __inline if that's what the C compiler calls it.  */
-/* #undef inline */
-
-/* Define if you have the ANSI C header files.  */
-#define STDC_HEADERS 1
-
-/* Define if you have the argz_append function.  */
-#define HAVE_ARGZ_APPEND 1
-
-/* Define if you have the argz_create_sep function.  */
-#define HAVE_ARGZ_CREATE_SEP 1
-
-/* Define if you have the argz_insert function.  */
-#define HAVE_ARGZ_INSERT 1
-
-/* Define if you have the argz_next function.  */
-#define HAVE_ARGZ_NEXT 1
-
-/* Define if you have the argz_stringify function.  */
-#define HAVE_ARGZ_STRINGIFY 1
-
-/* Define if you have the bcopy function.  */
-/* #undef HAVE_BCOPY */
-
-/* Define if you have the dlerror function.  */
-#define HAVE_DLERROR 1
-
-/* Define if you have the index function.  */
-/* #undef HAVE_INDEX */
-
-/* Define if you have the memcpy function.  */
-#define HAVE_MEMCPY 1
-
-/* Define if you have the memmove function.  */
-#define HAVE_MEMMOVE 1
-
-/* Define if you have the rindex function.  */
-/* #undef HAVE_RINDEX */
-
-/* Define if you have the strchr function.  */
-#define HAVE_STRCHR 1
-
-/* Define if you have the strcmp function.  */
-#define HAVE_STRCMP 1
-
-/* Define if you have the strrchr function.  */
-#define HAVE_STRRCHR 1
-
-/* Define if you have the <argz.h> header file.  */
-#define HAVE_ARGZ_H 1
-
-/* Define if you have the <assert.h> header file.  */
-#define HAVE_ASSERT_H 1
-
-/* Define if you have the <ctype.h> header file.  */
-#define HAVE_CTYPE_H 1
-
-/* Define if you have the <dirent.h> header file.  */
-#define HAVE_DIRENT_H 1
-
-/* Define if you have the <dl.h> header file.  */
-/* #undef HAVE_DL_H */
-
-/* Define if you have the <dld.h> header file.  */
-/* #undef HAVE_DLD_H */
-
-/* Define if you have the <dlfcn.h> header file.  */
-#define HAVE_DLFCN_H 1
-
-/* Define if you have the <errno.h> header file.  */
-#define HAVE_ERRNO_H 1
-
-/* Define if you have the <malloc.h> header file.  */
-#define HAVE_MALLOC_H 1
-
-/* Define if you have the <memory.h> header file.  */
-#define HAVE_MEMORY_H 1
-
-/* Define if you have the <ndir.h> header file.  */
-/* #undef HAVE_NDIR_H */
-
-/* Define if you have the <stdio.h> header file.  */
-#define HAVE_STDIO_H 1
-
-/* Define if you have the <stdlib.h> header file.  */
-#define HAVE_STDLIB_H 1
-
-/* Define if you have the <string.h> header file.  */
-#define HAVE_STRING_H 1
-
-/* Define if you have the <strings.h> header file.  */
-#define HAVE_STRINGS_H 1
-
-/* Define if you have the <sys/dir.h> header file.  */
-/* #undef HAVE_SYS_DIR_H */
-
-/* Define if you have the <sys/dl.h> header file.  */
-/* #undef HAVE_SYS_DL_H */
-
-/* Define if you have the <sys/ndir.h> header file.  */
-/* #undef HAVE_SYS_NDIR_H */
-
-/* Define if you have the <unistd.h> header file.  */
-#define HAVE_UNISTD_H 1
-
-/* Define to the extension used for shared libraries, say, .so.  */
-#define LTDL_SHLIB_EXT ".so"
-
-/* Define to the name of the environment variable that determines the dynamic library search path.  */
-#define LTDL_SHLIBPATH_VAR "LD_LIBRARY_PATH"
-
-/* Define to the system default library search path.  */
-#define LTDL_SYSSEARCHPATH "/lib:/usr/lib"
-
-/* Define to the sub-directory in which libtool stores uninstalled libraries.  */
-#define LTDL_OBJDIR ".libs/"
-
-/* Define if libtool can extract symbol lists from object files.  */
-#define HAVE_PRELOADED_SYMBOLS 1
-
-/* Define if you have the libdl library or equivalent.  */
-#define HAVE_LIBDL 1
-
-/* Define if you have the libdl library or equivalent. */
-#define HAVE_LIBDL 1
-
-/* Define if you have the libdl library or equivalent. */
-#define HAVE_LIBDL 1
-
-/* Define if you have the shl_load function. */
-/* #undef HAVE_SHL_LOAD */
-
-/* Define if you have the shl_load function. */
-/* #undef HAVE_SHL_LOAD */
-
-/* Define if you have the GNU dld library. */
-/* #undef HAVE_DLD */
-
-/* Define if dlsym() requires a leading underscode in symbol names.  */
-/* #undef NEED_USCORE */
-
-/* Define if the OS needs help to load dependent libraries for dlopen().  */
-/* #undef LTDL_DLOPEN_DEPLIBS */
-
-/* Define to a type to use for `error_t' if it is not otherwise available. */
-/* #undef error_t */
-
diff --git a/tools/ioemu/include/osdep.h b/tools/ioemu/include/osdep.h
deleted file mode 100644 (file)
index a47b88d..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: osdep.h,v 1.19 2003/08/20 06:26:27 japj Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2001  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-//
-// osdep.h
-//
-// requires Bit32u/Bit64u from config.h, size_t from stdio.h
-// 
-// Operating system dependent includes and defines for Bochs.  These 
-// declarations can be included by C or C++., but they require definition of
-// size_t beforehand.  This makes it difficult to place them into either
-// config.h or bochs.h.  If in config.h, size_t is not always available yet.
-// If in bochs.h, they can't be included by C programs so they lose.  
-//
-
-#ifndef BX_OSDEP_H
-#define BX_OSDEP_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif   /* __cplusplus */
-
-//////////////////////////////////////////////////////////////////////
-// Hacks for win32, but exclude MINGW32 because it doesn't need them.
-//////////////////////////////////////////////////////////////////////
-#ifdef WIN32
-
-// Definitions that are needed for all WIN32 compilers.
-#  define ssize_t long
-
-#ifndef __MINGW32__
-#define FMT_LL "%I64"
-
-// Definitions that are needed for WIN32 compilers EXCEPT FOR
-// cygwin compiling with -mno-cygwin.  e.g. VC++.
-
-// always return regular file.
-#  define S_ISREG(m)      (((m) & S_IFMT) == S_IFREG)
-#  define S_ISCHR(m)      (((m) & S_IFMT) == S_IFCHR)
-
-// win32 has snprintf though with different name.
-#define snprintf _snprintf
-#else    /* ifnndef __MINGW32__ */
-#define FMT_LL "%ll"
-#endif  /* ifnndef __MINGW32__ */
-#else    /* WIN32 */
-#define FMT_LL "%ll"
-#endif   /* WIN32 */
-
-// Missing defines for open
-#ifndef S_IRUSR
-#define S_IRUSR 0400
-#define S_IWUSR 0200
-#endif
-#ifndef S_IRGRP
-#define S_IRGRP 0040
-#define S_IWGRP 0020
-#endif
-#ifndef S_IROTH
-#define S_IROTH 0004
-#define S_IWOTH 0002
-#endif
-
-//////////////////////////////////////////////////////////////////////
-// Missing library functions.
-// These should work on any platform that needs them.
-// 
-// A missing library function is renamed to a bx_* function, so that when
-// debugging and linking there's no confusion over which version is used.
-// Because of renaming, the bx_* replacement functions can be tested on 
-// machines which have the real library function without duplicate symbols.
-//
-// If you're considering implementing a missing library function, note 
-// that it might be cleaner to conditionally disable the function call!
-//////////////////////////////////////////////////////////////////////
-
-#if !BX_HAVE_SNPRINTF
-#define snprintf bx_snprintf
-  extern int bx_snprintf (char *s, size_t maxlen, const char *format, ...);
-#endif
-
-#if BX_HAVE_STRTOULL
-  // great, just use the usual function
-#elif BX_HAVE_STRTOUQ
-  // they have strtouq and not strtoull
-  #define strtoull strtouq
-#else
-  #define strtoull bx_strtoull
-  extern Bit64u bx_strtoull (const char *nptr, char **endptr, int baseignore);
-#endif
-
-#if !BX_HAVE_STRDUP
-#define strdup bx_strdup
-  extern char *bx_strdup(const char *str);
-#endif
-
-#if !BX_HAVE_STRREV
-#define strrev bx_strrev
-  extern char *bx_strrev(char *str);
-#endif
-
-#if !BX_HAVE_SOCKLEN_T
-// needed on MacOS X 10.1
-typedef int socklen_t;
-#endif
-
-#if !BX_HAVE_MKSTEMP
-#define mkstemp bx_mkstemp
-  extern int bx_mkstemp(char *tpl);
-#endif
-
-//////////////////////////////////////////////////////////////////////
-// Missing library functions, implemented for MacOS only
-//////////////////////////////////////////////////////////////////////
-
-#if BX_WITH_MACOS
-// fd_read and fd_write are called by floppy.cc to access the Mac
-// floppy drive directly, since the MacOS doesn't have "special"
-// pathnames which map directly to IO devices
-
-int fd_read(char *buffer, Bit32u offset, Bit32u bytes);
-int fd_write(char *buffer, Bit32u offset, Bit32u bytes);
-int fd_stat(struct stat *buf);
-FILE *  fdopen(int fd, const char *type);
-
-typedef long ssize_t ;
-#endif
-
-//////////////////////////////////////////////////////////////////////
-// New functions to replace library functions
-//   with OS-independent versions
-//////////////////////////////////////////////////////////////////////
-
-#if BX_HAVE_REALTIME_USEC
-// 64-bit time in useconds.
-extern Bit64u bx_get_realtime64_usec (void);
-#endif
-
-#ifdef WIN32
-#undef BX_HAVE_MSLEEP
-#define BX_HAVE_MSLEEP 1
-#ifndef __MINGW32__
-#define msleep(msec)   _sleep(msec)
-#else
-#define msleep(msec)   Sleep(msec)
-#endif
-#endif
-
-#ifdef __cplusplus
-}
-#endif   /* __cplusplus */
-
-#endif /* ifdef BX_OSDEP_H */
diff --git a/tools/ioemu/include/pc_system.h b/tools/ioemu/include/pc_system.h
deleted file mode 100644 (file)
index c8ea664..0000000
+++ /dev/null
@@ -1,226 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: pc_system.h,v 1.25 2003/03/02 23:59:08 cbothamy Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-
-
-#define BX_MAX_TIMERS 64
-#define BX_NULL_TIMER_HANDLE 10000
-
-
-#if BX_SHOW_IPS
-extern unsigned long ips_count;
-#endif
-
-
-typedef void (*bx_timer_handler_t)(void *);
-
-
-BOCHSAPI extern class bx_pc_system_c bx_pc_system;
-
-#ifdef PROVIDE_M_IPS
-extern double m_ips;
-#endif
-
-#ifdef BX_USE_VMX
-extern unsigned int tsc_per_bx_tick;
-
-#define rdtscll(val) \
-     __asm__ __volatile__("rdtsc" : "=A" (val))
-#endif
-
-class BOCHSAPI bx_pc_system_c : private logfunctions {
-private:
-
-  // ===============================
-  // Timer oriented private features
-  // ===============================
-
-  struct {
-    bx_bool inUse;      // Timer slot is in-use (currently registered).
-    Bit64u  period;     // Timer periodocity in cpu ticks.
-    Bit64u  timeToFire; // Time to fire next (in absolute ticks).
-    bx_bool active;     // 0=inactive, 1=active.
-    bx_bool continuous; // 0=one-shot timer, 1=continuous periodicity.
-    bx_timer_handler_t funct;  // A callback function for when the
-                               //   timer fires.
-    void *this_ptr;            // The this-> pointer for C++ callbacks
-                               //   has to be stored as well.
-#define BxMaxTimerIDLen 32
-    char id[BxMaxTimerIDLen]; // String ID of timer.
-    } timer[BX_MAX_TIMERS];
-
-  unsigned   numTimers;  // Number of currently allocated timers.
-  Bit32u     currCountdown; // Current countdown ticks value (decrements to 0).
-  Bit32u     currCountdownPeriod; // Length of current countdown period.
-  Bit64u     ticksTotal; // Num ticks total since start of emulator execution.
-  Bit64u     lastTimeUsec; // Last sequentially read time in usec.
-  Bit64u     usecSinceLast; // Number of useconds claimed since then.
-
-  // A special null timer is always inserted in the timer[0] slot.  This
-  // make sure that at least one timer is always active, and that the
-  // duration is always less than a maximum 32-bit integer, so a 32-bit
-  // counter can be used for the current countdown.
-  static const Bit64u NullTimerInterval;
-  static void nullTimer(void* this_ptr);
-
-#if !defined(PROVIDE_M_IPS)
-  // This is the emulator speed, as measured in millions of
-  // x86 instructions per second that it can emulate on some hypothetically
-  // nomimal workload.
-  double     m_ips; // Millions of Instructions Per Second
-#endif
-
-#ifdef BX_USE_VMX
-  static Bit64s get_clock(void) {
-    struct timeval tv;
-    gettimeofday(&tv, NULL);
-    return tv.tv_sec * 1000000LL + tv.tv_usec;
-    }
-
-  static Bit64u cpu_calibrate_ticks(void) {
-    Bit64s usec, t1, t2;
-
-    usec = get_clock();
-    rdtscll(t1);
-
-    usleep(50 * 1000);
-    usec = get_clock() - usec;
-    rdtscll(t2);
-
-    return (((t2 - t1) * 1000000LL + (usec >> 1)) / usec);
-    }
-#endif
-  // This handler is called when the function which decrements the clock
-  // ticks finds that an event has occurred.
-  void   countdownEvent(void);
-
-public:
-
-  // ==============================
-  // Timer oriented public features
-  // ==============================
-
-  void   init_ips(Bit32u ips);
-  int    register_timer( void *this_ptr, bx_timer_handler_t, Bit32u useconds,
-                         bx_bool continuous, bx_bool active, const char *id);
-  unsigned unregisterTimer(int timerID);
-  void   start_timers(void);
-  void   activate_timer( unsigned timer_index, Bit32u useconds,
-                         bx_bool continuous );
-  void   deactivate_timer( unsigned timer_index );
-  static BX_CPP_INLINE void tick1(void) {
-#if BX_SHOW_IPS
-  {
-  extern unsigned long ips_count;
-  ips_count++;
-  }
-#endif
-    if (--bx_pc_system.currCountdown == 0) {
-      bx_pc_system.countdownEvent();
-      }
-    }
-  static BX_CPP_INLINE void tickn(Bit64u n) {
-#if BX_SHOW_IPS
-  {
-  extern unsigned long ips_count;
-  ips_count += n;
-  }
-#endif
-    while (n >= Bit64u(bx_pc_system.currCountdown)) {
-      n -= Bit64u(bx_pc_system.currCountdown);
-      bx_pc_system.currCountdown = 0;
-      bx_pc_system.countdownEvent();
-      // bx_pc_system.currCountdown is adjusted to new value by countdownevent().
-      };
-    // 'n' is not (or no longer) >= the countdown size.  We can just decrement
-    // the remaining requested ticks and continue.
-    bx_pc_system.currCountdown -= Bit32u(n);
-    }
-
-  int register_timer_ticks(void* this_ptr, bx_timer_handler_t, Bit64u ticks,
-                           bx_bool continuous, bx_bool active, const char *id);
-  void activate_timer_ticks(unsigned index, Bit64u instructions,
-                            bx_bool continuous);
-  Bit64u time_usec();
-  Bit64u time_usec_sequential();
-  static BX_CPP_INLINE Bit64u time_ticks() {
-    return bx_pc_system.ticksTotal +
-      Bit64u(bx_pc_system.currCountdownPeriod - bx_pc_system.currCountdown);
-    }
-  static BX_CPP_INLINE Bit64u getTicksTotal(void) {
-    return bx_pc_system.ticksTotal;
-    }
-
-  static BX_CPP_INLINE Bit32u  getNumCpuTicksLeftNextEvent(void) {
-    return bx_pc_system.currCountdown;
-    }
-#if BX_DEBUGGER
-  static void timebp_handler(void* this_ptr);
-#endif
-
-
-  // ===========================
-  // Non-timer oriented features
-  // ===========================
-
-  bx_bool HRQ;     // Hold Request
-  //bx_bool INTR;    // Interrupt
-
-
-    // Address line 20 control:
-    //   1 = enabled: extended memory is accessible
-    //   0 = disabled: A20 address line is forced low to simulate
-    //       an 8088 address map
-  bx_bool enable_a20;
-
-    // start out masking physical memory addresses to:
-    //   8086:      20 bits
-    //    286:      24 bits
-    //    386:      32 bits
-    // when A20 line is disabled, mask physical memory addresses to:
-    //    286:      20 bits
-    //    386:      20 bits
-    //
-  Bit32u  a20_mask;
-
-  void set_HRQ(bx_bool val);  // set the Hold ReQuest line
-  void set_INTR(bx_bool value); // set the INTR line to value
-
-  int IntEnabled( void );
-  int InterruptSignal( PCS_OP operation );
-  int ResetSignal( PCS_OP operation );
-  Bit8u  IAC(void);
-
-  bx_pc_system_c(void);
-
-  Bit32u  inp(Bit16u addr, unsigned io_len) BX_CPP_AttrRegparmN(2);
-  void    outp(Bit16u addr, Bit32u value, unsigned io_len) BX_CPP_AttrRegparmN(3);
-  void    set_enable_a20(Bit8u value) BX_CPP_AttrRegparmN(1);
-  bx_bool get_enable_a20(void);
-  void    exit(void);
-
-  };
diff --git a/tools/ioemu/include/plugin.h b/tools/ioemu/include/plugin.h
deleted file mode 100644 (file)
index dabd13f..0000000
+++ /dev/null
@@ -1,323 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: plugin.h,v 1.20 2003/08/04 16:03:08 akrisak Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-// This file provides macros and types needed for plugins.  It is based on
-// the plugin.h file from plex86, but with significant changes to make
-// it work in Bochs.  
-// Plex86 is Copyright (C) 1999-2000  The plex86 developers team
-//
-/////////////////////////////////////////////////////////////////////////
-
-#ifndef __PLUGIN_H
-#define __PLUGIN_H
-
-#include "extplugin.h"
-
-class bx_devices_c;
-BOCHSAPI extern logfunctions  *pluginlog;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define BX_PLUGIN_UNMAPPED  "unmapped"
-#define BX_PLUGIN_BIOSDEV   " biosdev"
-#define BX_PLUGIN_CMOS      "cmos"
-#define BX_PLUGIN_VGA       "vga"
-#define BX_PLUGIN_FLOPPY    "floppy"
-#define BX_PLUGIN_PARALLEL  "parallel"
-#define BX_PLUGIN_SERIAL    "serial"
-#define BX_PLUGIN_KEYBOARD  "keyboard"
-#define BX_PLUGIN_HARDDRV   "harddrv"
-#define BX_PLUGIN_DMA       "dma"
-#define BX_PLUGIN_PIC       "pic"
-#define BX_PLUGIN_PCI       "pci"
-#define BX_PLUGIN_PCI2ISA   "pci2isa"
-#define BX_PLUGIN_SB16      "sb16"
-#define BX_PLUGIN_NE2K      "ne2k"
-#define BX_PLUGIN_EXTFPUIRQ "extfpuirq"
-#define BX_PLUGIN_PCIVGA    "pcivga"
-#define BX_PLUGIN_PCIUSB    "pciusb"
-#define BX_PLUGIN_GAMEPORT  "gameport"
-
-
-#define BX_REGISTER_DEVICE_DEVMODEL(a,b,c,d) pluginRegisterDeviceDevmodel(a,b,c,d)
-
-#if BX_PLUGINS
-
-#define DEV_init_devices() {bx_devices.init(BX_MEM(0)); }
-#define DEV_reset_devices(type) {bx_devices.reset(type); }
-#define PLUG_load_plugin(name,type) {bx_load_plugin(#name,type);}
-
-#define DEV_register_ioread_handler(b,c,d,e,f)  pluginRegisterIOReadHandler(b,c,d,e,f)
-#define DEV_register_iowrite_handler(b,c,d,e,f) pluginRegisterIOWriteHandler(b,c,d,e,f)
-#define DEV_register_default_ioread_handler(b,c,d,e) pluginRegisterDefaultIOReadHandler(b,c,d,e)
-#define DEV_register_default_iowrite_handler(b,c,d,e) pluginRegisterDefaultIOWriteHandler(b,c,d,e)
-
-#define DEV_register_irq(b,c) pluginRegisterIRQ(b,c)
-#define DEV_unregister_irq(b,c) pluginUnregisterIRQ(b,c)
-
-#else
-
-#define DEV_init_devices() {bx_devices.init(BX_MEM(0)); }
-#define DEV_reset_devices(type) {bx_devices.reset(type); }
-// When plugins are off, PLUG_load_plugin will call the plugin_init function
-// directly.
-#define PLUG_load_plugin(name,type) {lib##name##_LTX_plugin_init(NULL,type,0,NULL);}
-#define DEV_register_ioread_handler(b,c,d,e,f) bx_devices.register_io_read_handler(b,c,d,e,f)
-#define DEV_register_iowrite_handler(b,c,d,e,f) bx_devices.register_io_write_handler(b,c,d,e,f)
-#define DEV_register_default_ioread_handler(b,c,d,e) bx_devices.register_default_io_read_handler(b,c,d,e)
-#define DEV_register_default_iowrite_handler(b,c,d,e) bx_devices.register_default_io_write_handler(b,c,d,e)
-#define DEV_register_irq(b,c) bx_devices.register_irq(b,c)
-#define DEV_unregister_irq(b,c) bx_devices.unregister_irq(b,c)
-
-#endif // #if BX_PLUGINS
-
-#define DEV_ioapic_present() (bx_devices.ioapic != NULL)
-
-// FIXME Do we really need pluginRegisterTimer ?
-#define DEV_register_timer(a,b,c,d,e,f) bx_pc_system.register_timer(a,b,c,d,e,f)
-
-///////// CMOS macros
-#define DEV_cmos_get_reg(a) (bx_devices.pluginCmosDevice->get_reg(a))
-#define DEV_cmos_set_reg(a,b) (bx_devices.pluginCmosDevice->set_reg(a,b))
-#define DEV_cmos_checksum() (bx_devices.pluginCmosDevice->checksum_cmos())
-#define DEV_cmos_get_timeval() (bx_devices.pluginCmosDevice->get_timeval())
-
-///////// keyboard macros
-#define DEV_mouse_motion(dx, dy, state) \
-    (bx_devices.pluginKeyboard->mouse_motion(dx, dy, state))
-#define DEV_kbd_gen_scancode(key) \
-    (bx_devices.pluginKeyboard->gen_scancode(key))
-#define DEV_kbd_paste_bytes(bytes, count) \
-    (bx_devices.pluginKeyboard->paste_bytes(bytes,count))
-#define DEV_kbd_paste_delay_changed() \
-    (bx_devices.pluginKeyboard->paste_delay_changed())
-#define DEV_mouse_enabled_changed(val) \
-    (bx_devices.pluginKeyboard->mouse_enabled_changed(val))
-
-///////// hard drive macros
-#define DEV_hd_read_handler(a, b, c) \
-    (bx_devices.pluginHardDrive->virt_read_handler(b, c))
-#define DEV_hd_write_handler(a, b, c, d) \
-    (bx_devices.pluginHardDrive->virt_write_handler(b, c, d))
-#define DEV_hd_get_first_cd_handle() \
-    (bx_devices.pluginHardDrive->get_first_cd_handle())
-#define DEV_hd_get_device_handle(a,b) \
-    (bx_devices.pluginHardDrive->get_device_handle(a,b))
-#define DEV_hd_get_cd_media_status(handle) \
-    (bx_devices.pluginHardDrive->get_cd_media_status(handle))
-#define DEV_hd_set_cd_media_status(handle, status) \
-    (bx_devices.pluginHardDrive->set_cd_media_status(handle, status))
-#define DEV_hd_close_harddrive()  bx_devices.pluginHardDrive->close_harddrive()
-#define DEV_hd_present() (bx_devices.pluginHardDrive != &bx_devices.stubHardDrive)
-
-#define DEV_bulk_io_quantum_requested() (bx_devices.bulkIOQuantumsRequested)
-#define DEV_bulk_io_quantum_transferred() (bx_devices.bulkIOQuantumsTransferred)
-#define DEV_bulk_io_host_addr() (bx_devices.bulkIOHostAddr)
-
-///////// FLOPPY macros
-#define DEV_floppy_get_media_status(drive) bx_devices.pluginFloppyDevice->get_media_status(drive)
-#define DEV_floppy_set_media_status(drive, status)  bx_devices.pluginFloppyDevice->set_media_status(drive, status)
-#define DEV_floppy_present() (bx_devices.pluginFloppyDevice != &bx_devices.stubFloppy)
-
-///////// DMA macros
-#define DEV_dma_register_8bit_channel(channel, dmaRead, dmaWrite, name) \
-  (bx_devices.pluginDmaDevice->registerDMA8Channel(channel, dmaRead, dmaWrite, name))
-#define DEV_dma_register_16bit_channel(channel, dmaRead, dmaWrite, name) \
-  (bx_devices.pluginDmaDevice->registerDMA16Channel(channel, dmaRead, dmaWrite, name))
-#define DEV_dma_unregister_channel(channel) \
-  (bx_devices.pluginDmaDevice->unregisterDMAChannel(channel))
-#define DEV_dma_set_drq(channel, val) \
-  (bx_devices.pluginDmaDevice->set_DRQ(channel, val))
-#define DEV_dma_get_tc() \
-  (bx_devices.pluginDmaDevice->get_TC())
-#define DEV_dma_raise_hlda() \
-  (bx_devices.pluginDmaDevice->raise_HLDA())
-
-///////// PIC macros
-#define DEV_pic_lower_irq(b)  (bx_devices.pluginPicDevice->lower_irq(b))
-#define DEV_pic_raise_irq(b)  (bx_devices.pluginPicDevice->raise_irq(b))
-#define DEV_pic_iac()         (bx_devices.pluginPicDevice->IAC())
-#define DEV_pic_show_pic_state() (bx_devices.pluginPicDevice->show_pic_state())
-
-///////// VGA macros
-#define DEV_vga_mem_read(addr) (bx_devices.pluginVgaDevice->mem_read(addr))
-#define DEV_vga_mem_write(addr, val) (bx_devices.pluginVgaDevice->mem_write(addr, val))
-#define DEV_vga_redraw_area(left, top, right, bottom) \
-  (bx_devices.pluginVgaDevice->redraw_area(left, top, right, bottom))
-#define DEV_vga_get_text_snapshot(rawsnap, height, width) \
-  (bx_devices.pluginVgaDevice->get_text_snapshot(rawsnap, height, width))
-#define DEV_vga_refresh() \
-  (bx_devices.pluginVgaDevice->trigger_timer(bx_devices.pluginVgaDevice))
-#define DEV_vga_set_update_interval(val) \
-  (bx_devices.pluginVgaDevice->set_update_interval(val))
-#define DEV_vga_get_actl_pal_idx(index) (bx_devices.pluginVgaDevice->get_actl_palette_idx(index))
-
-///////// PCI macros
-#define DEV_register_pci_handlers(b,c,d,e,f) \
-  (bx_devices.pluginPciBridge->register_pci_handlers(b,c,d,e,f))
-#define DEV_pci_rd_memtype(addr) bx_devices.pluginPciBridge->rd_memType(addr)
-#define DEV_pci_wr_memtype(addr) bx_devices.pluginPciBridge->wr_memType(addr)
-#define DEV_pci_print_i440fx_state() bx_devices.pluginPciBridge->print_i440fx_state()
-
-///////// NE2000 macro
-#define DEV_ne2k_print_info(file,page,reg,brief) \
-    bx_devices.pluginNE2kDevice->print_info(file,page,reg,brief)
-
-
-#if BX_HAVE_DLFCN_H
-#include <dlfcn.h>
-#endif
-
-typedef Bit32u (*ioReadHandler_t)(void *, Bit32u, unsigned);
-typedef void   (*ioWriteHandler_t)(void *, Bit32u, Bit32u, unsigned);
-
-extern plugin_t *plugins;
-
-typedef struct _device_t
-{
-    const char *name;
-    plugin_t *plugin;
-    void (*device_init_mem)(BX_MEM_C *);
-    void (*device_init_dev)();
-    void (*device_reset)(unsigned);
-    void (*device_load_state)();
-    void (*device_save_state)();
-
-    int use_devmodel_interface;  // BBD hack
-    class bx_devmodel_c *devmodel;  // BBD hack
-
-    struct _device_t *next;
-} device_t;
-
-
-extern device_t *devices;
-
-void plugin_startup (void);
-void plugin_load (char *name, char *args, plugintype_t);
-plugin_t *plugin_unload (plugin_t *plugin);
-void plugin_init_all (void);
-void plugin_fini_all (void);
-
-/* === Device Stuff === */
-typedef void (*deviceInitMem_t)(BX_MEM_C *);
-typedef void (*deviceInitDev_t)(void);
-typedef void (*deviceReset_t)(unsigned);
-typedef void (*deviceLoad_t)(void);
-typedef void (*deviceSave_t)(void);
-
-BOCHSAPI void pluginRegisterDeviceDevmodel(plugin_t *plugin, plugintype_t type, bx_devmodel_c *dev, char *name);
-BOCHSAPI bx_bool pluginDevicePresent(char *name);
-
-/* === IO port stuff === */
-BOCHSAPI extern int (*pluginRegisterIOReadHandler)(void *thisPtr, ioReadHandler_t callback,
-                                unsigned base, const char *name, Bit8u mask);
-BOCHSAPI extern int (*pluginRegisterIOWriteHandler)(void *thisPtr, ioWriteHandler_t callback,
-                                 unsigned base, const char *name, Bit8u mask);
-BOCHSAPI extern int (*pluginRegisterDefaultIOReadHandler)(void *thisPtr, ioReadHandler_t callback,
-                                const char *name, Bit8u mask);
-BOCHSAPI extern int (*pluginRegisterDefaultIOWriteHandler)(void *thisPtr, ioWriteHandler_t callback,
-                                 const char *name, Bit8u mask);
-
-/* === A20 enable line stuff === */
-BOCHSAPI extern unsigned (*pluginGetA20E)(void);
-BOCHSAPI extern void     (*pluginSetA20E)(unsigned val);
-
-/* === IRQ stuff === */
-BOCHSAPI extern void  (*pluginRegisterIRQ)(unsigned irq, const char *name);
-BOCHSAPI extern void  (*pluginUnregisterIRQ)(unsigned irq, const char *name);
-
-/* === Floppy stuff ===*/
-BOCHSAPI extern unsigned (* pluginFloppyGetMediaStatus)(unsigned drive);
-BOCHSAPI extern unsigned (* pluginFloppySetMediaStatus)(unsigned drive, unsigned status);
-
-/* === VGA stuff === */
-BOCHSAPI extern void (* pluginVGARedrawArea)(unsigned x0, unsigned y0,
-                 unsigned width, unsigned height);
-BOCHSAPI extern Bit8u (* pluginVGAMemRead)(Bit32u addr);
-BOCHSAPI extern void  (* pluginVGAMemWrite)(Bit32u addr, Bit8u value);
-BOCHSAPI extern void  (* pluginVGAGetTextSnapshot)(Bit8u **text_snapshot, 
-                         unsigned *txHeight, unsigned *txWidth);
-BOCHSAPI extern void  (* pluginVGARefresh)(void *);
-BOCHSAPI extern void  (* pluginVGASetUpdateInterval)(unsigned);
-BOCHSAPI extern Bit8u (* pluginVGAGetActlPaletteIdx)(Bit8u index);
-
-/* === Timer stuff === */
-BOCHSAPI extern int      (*pluginRegisterTimer)(void *this_ptr, void (*funct)(void *),
-                             Bit32u useconds, bx_bool continuous,
-                             bx_bool active, const char *name);
-
-BOCHSAPI extern void     (*pluginActivateTimer)(unsigned id, Bit32u usec, bx_bool continuous);
-BOCHSAPI extern void     (*pluginDeactivateTimer)(unsigned id);
-
-/* === HRQ stuff === */
-BOCHSAPI extern void     (*pluginSetHRQ)(unsigned val);
-BOCHSAPI extern void     (*pluginSetHRQHackCallback)( void (*callback)(void) );
-
-/* === Reset stuff === */
-BOCHSAPI extern void     (*pluginResetSignal)(unsigned sig);
-
-/* === PCI stuff === */
-BOCHSAPI extern bx_bool  (*pluginRegisterPCIDevice)(void *this_ptr,
-                             Bit32u (*bx_pci_read_handler)(void *, Bit8u, unsigned),
-                             void(*bx_pci_write_handler)(void *, Bit8u, Bit32u, unsigned),
-                             Bit8u devfunc, const char *name);
-BOCHSAPI extern Bit8u    (*pluginRd_memType)(Bit32u addr);
-BOCHSAPI extern Bit8u    (*pluginWr_memType)(Bit32u addr);
-
-void plugin_abort (void);
-
-int bx_load_plugin (const char *name, plugintype_t type);
-extern void bx_init_plugins (void);
-extern void bx_reset_plugins (unsigned);
-
-// every plugin must define these, within the extern"C" block, so that
-// a non-mangled function symbol is available in the shared library.
-void plugin_fini(void);
-int plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[]);
-
-// still in extern "C"
-#define DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(mod) \
-  int lib##mod##_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[]); \
-  void lib##mod##_LTX_plugin_fini(void);
-  
-DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(harddrv)
-DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(keyboard)
-DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(serial)
-DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(unmapped)
-DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(biosdev)
-DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(cmos)
-DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(dma)
-DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(pic)
-DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(vga)
-DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(floppy)
-DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(parallel)
-DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(pci)
-DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(pci2isa)
-DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(pcivga)
-DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(pciusb)
-DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(sb16)
-DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(ne2k)
-DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(extfpuirq)
-DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(gameport)
-DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(amigaos)
-DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(beos)
-DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(carbon)
-DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(macintosh)
-DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(nogui)
-DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(rfb)
-DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(sdl)
-DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(svga)
-DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(term)
-DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(win32)
-DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(wx)
-DECLARE_PLUGIN_INIT_FINI_FOR_MODULE(x)
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __PLUGIN_H */
diff --git a/tools/ioemu/include/state_file.h b/tools/ioemu/include/state_file.h
deleted file mode 100644 (file)
index 7cef477..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: state_file.h,v 1.5 2002/10/24 21:05:00 bdenney Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2001  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-// Classes for helping to make checkpoints of the emulator state.
-
-#ifndef _STATE_FILE_H
-#define _STATE_FILE_H
-#include <stdio.h>
-#include <stddef.h>
-
-
-class BOCHSAPI state_file {
-  void init(void);
-public:
-  FILE *file;
-  class logfunctions *log;
-
-  FILE *get_handle();
-  void write(Bit8u);
-  void write(Bit16u);
-  void write(Bit32u);
-  void write(Bit64u);
-  void write(const void*, size_t);
-  void read(Bit8u &);
-  void read(Bit16u &);
-  void read(Bit32u &);
-  void read(Bit64u &);
-  void read(void *, size_t);
-  void write_check(const char *);
-  void read_check (const char *);
-
-  state_file (const char *name, const char *options);
-  state_file (FILE *f);
-  ~state_file();
-};
-
-#endif  // #ifndef _STATE_FILE_H
diff --git a/tools/ioemu/iodev/Makefile b/tools/ioemu/iodev/Makefile
deleted file mode 100644 (file)
index e56e386..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-XEN_ROOT= ../../../
-include $(XEN_ROOT)/tools/Rules.mk
-TOPDIR= ..
-CXXFLAGS=-I. -I../include -I..
-
-ifeq ($(XEN_TARGET_ARCH), x86_32)
-CXXFLAGS+=-D_FILE_OFFSET_BITS=64
-endif
-
-OBJS=$(patsubst %.cc,%.o,$(wildcard *.cc))
-BXLIBS = ../gui/libgui.a ../memory/libmemory.a  
-LDLIBS= $(BXLIBS) $(X11_LDPATH) -lX11 -lXpm -lstdc++ -L../../../tools/libxc -L../../../tools/libxutil -lxc -lxutil -lpthread -lncurses 
-
-all: device-model
-
-device-model: $(OBJS) $(BXLIBS)
-       $(CC) $(LDFLAGS) $(OBJS) $(LOADLIBES) $(LDLIBS) -o $@
-
-include $(TOPDIR)/mk/helix.mk
-
-install:: all
-       install device-model $(DESTDIR)/usr/sbin
diff --git a/tools/ioemu/iodev/aspi-win32.h b/tools/ioemu/iodev/aspi-win32.h
deleted file mode 100644 (file)
index afa62d1..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-//
-// iodev/aspi-win32.h
-// $Id: aspi-win32.h,v 1.2 2001/06/25 12:52:37 bdenney Exp $
-//
-// This file was copied from cdrecord 1.9 under libscg/scg/aspi-win32.h.
-// The only modification is related to use of the PACKED keyword.  
-// 
-
-#ifndef __ASPI_WIN32_H_
-#define __ASPI_WIN32_H_
-
-#include <windows.h>
-
-#ifndef PACKED
-// It seems that VC++ has no PACKED keyword but Cygwin does.  We can just
-// define PACKED to be empty if it's not already defined by the system 
-// headers.
-#define PACKED /* empty */
-#endif
-
-/***************************************************************************
- ** SCSI MISCELLANEOUS EQUATES
- ***************************************************************************/
-#define SENSE_LEN                 14     /* Default sense buffer length    */
-#define SRB_DIR_SCSI              0x00   /* Direction determined by SCSI   */
-#define SRB_POSTING               0x01   /* Enable ASPI posting            */
-#define SRB_ENABLE_RESIDUAL_COUNT 0x04   /* Enable residual byte count     */
-                                         /* reporting                      */
-#define SRB_DIR_IN                0x08   /* Transfer from SCSI target to   */
-                                         /* host                           */
-#define SRB_DIR_OUT               0x10   /* Transfer from host to SCSI     */
-                                         /* target                         */
-#define SRB_EVENT_NOTIFY          0x40   /* Enable ASPI event notification */
-#define RESIDUAL_COUNT_SUPPORTED  0x02   /* Extended buffer flag           */
-#define MAX_SRB_TIMEOUT       1080001u   /* 30 hour maximum timeout in sec */
-#define DEFAULT_SRB_TIMEOUT   1080001u   /* use max.timeout by default     */
-
-/***************************************************************************
- ** ASPI command definitions
- ***************************************************************************/
-#define SC_HA_INQUIRY             0x00   /* Host adapter inquiry           */
-#define SC_GET_DEV_TYPE           0x01   /* Get device type                */
-#define SC_EXEC_SCSI_CMD          0x02   /* Execute SCSI command           */
-#define SC_ABORT_SRB              0x03   /* Abort an SRB                   */
-#define SC_RESET_DEV              0x04   /* SCSI bus device reset          */
-#define SC_SET_HA_PARMS           0x05   /* Set HA parameters              */
-#define SC_GET_DISK_INFO          0x06   /* Get Disk                       */
-#define SC_RESCAN_SCSI_BUS        0x07   /* Rebuild SCSI device map        */
-#define SC_GETSET_TIMEOUTS        0x08   /* Get/Set target timeouts        */
-
-
-/***************************************************************************
- ** SRB Status
- ***************************************************************************/
-#define SS_PENDING                0x00   /* SRB being processed            */
-#define SS_COMP                   0x01   /* SRB completed without error    */
-#define SS_ABORTED                0x02   /* SRB aborted                    */
-#define SS_ABORT_FAIL             0x03   /* Unable to abort SRB            */
-#define SS_ERR                    0x04   /* SRB completed with error       */
-#define SS_INVALID_CMD            0x80   /* Invalid ASPI command           */
-#define SS_INVALID_HA             0x81   /* Invalid host adapter number    */
-#define SS_NO_DEVICE              0x82   /* SCSI device not installed      */
-#define SS_INVALID_SRB            0xE0   /* Invalid parameter set in SRB   */
-#define SS_OLD_MANAGER            0xE1   /* ASPI manager doesn't support   */
-                                         /* windows                        */
-#define SS_BUFFER_ALIGN           0xE1   /* Buffer not aligned (replaces   */
-                                         /* SS_OLD_MANAGER in Win32)       */
-#define SS_ILLEGAL_MODE           0xE2   /* Unsupported Windows mode       */
-#define SS_NO_ASPI                0xE3   /* No ASPI managers               */
-#define SS_FAILED_INIT            0xE4   /* ASPI for windows failed init   */
-#define SS_ASPI_IS_BUSY           0xE5   /* No resources available to      */
-                                         /* execute command                */
-#define SS_BUFFER_TO_BIG          0xE6   /* Buffer size too big to handle  */
-#define SS_BUFFER_TOO_BIG         0xE6   /* Correct spelling of 'too'      */
-#define SS_MISMATCHED_COMPONENTS  0xE7   /* The DLLs/EXEs of ASPI don't    */
-                                         /* version check                  */
-#define SS_NO_ADAPTERS            0xE8   /* No host adapters to manager    */
-#define SS_INSUFFICIENT_RESOURCES 0xE9   /* Couldn't allocate resources    */
-                                         /* needed to init                 */
-#define SS_ASPI_IS_SHUTDOWN       0xEA   /* Call came to ASPI after        */
-                                         /* PROCESS_DETACH                 */
-#define SS_BAD_INSTALL            0xEB   /* The DLL or other components    */
-                                         /* are installed wrong            */
-
-/***************************************************************************
- ** Host Adapter Status
- ***************************************************************************/
-#define HASTAT_OK                 0x00   /* No error detected by HA        */
-#define HASTAT_SEL_TO             0x11   /* Selection Timeout              */
-#define HASTAT_DO_DU              0x12   /* Data overrun/data underrun     */
-#define HASTAT_BUS_FREE           0x13   /* Unexpected bus free            */
-#define HASTAT_PHASE_ERR          0x14   /* Target bus phase sequence      */
-#define HASTAT_TIMEOUT            0x09   /* Timed out while SRB was        */
-                                         /* waiting to be processed        */
-#define HASTAT_COMMAND_TIMEOUT    0x0B   /* Adapter timed out while        */
-                                         /* processing SRB                 */
-#define HASTAT_MESSAGE_REJECT     0x0D   /* While processing the SRB, the  */
-                                         /* adapter received a MESSAGE     */
-#define HASTAT_BUS_RESET          0x0E   /* A bus reset was detected       */
-#define HASTAT_PARITY_ERROR       0x0F   /* A parity error was detected    */
-#define HASTAT_REQUEST_SENSE_FAILED 0x10 /* The adapter failed in issuing  */
-
-/***************************************************************************
- ** SRB - HOST ADAPTER INQUIRIY - SC_HA_INQUIRY (0)
- ***************************************************************************/
-typedef struct {
-  BYTE     SRB_Cmd;           /* 00/000 ASPI command code == SC_HA_INQUIRY */
-  BYTE     SRB_Status;        /* 01/001 ASPI command status byte           */
-  BYTE     SRB_HaId;          /* 02/002 ASPI host adapter number           */
-  BYTE     SRB_Flags;         /* 03/003 ASPI request flags                 */
-  DWORD    SRB_Hdr_Rsvd;      /* 04/004 Reserved, must = 0                 */
-  BYTE     HA_Count;          /* 08/008 Number of host adapters present    */
-  BYTE     HA_SCSI_ID;        /* 09/009 SCSI ID of host adapter            */
-  BYTE     HA_ManagerId[16];  /* 0a/010 String describing the manager      */
-  BYTE     HA_Identifier[16]; /* 1a/026 String describing the host adapter */
-  BYTE     HA_Unique[16];     /* 2a/042 Host Adapter Unique parameters     */
-  WORD     HA_Rsvd1;          /* 3a/058 Reserved, must = 0                 */
-} PACKED SRB_HAInquiry, *PSRB_HAInquiry, FAR *LPSRB_HAInquiry;
-
-
-/***************************************************************************
- ** SRB - GET DEVICE TYPE - SC_GET_DEV_TYPE (1)
- ***************************************************************************/
-typedef struct
-{
-  BYTE     SRB_Cmd;           /* 00/000 ASPI cmd code == SC_GET_DEV_TYPE   */
-  BYTE     SRB_Status;        /* 01/001 ASPI command status byte           */
-  BYTE     SRB_HaId;          /* 02/002 ASPI host adapter number           */
-  BYTE     SRB_Flags;         /* 03/003 Reserved, must = 0                 */
-  DWORD    SRB_Hdr_Rsvd;      /* 04/004 Reserved, must = 0                 */
-  BYTE     SRB_Target;        /* 08/008 Target's SCSI ID                   */
-  BYTE     SRB_Lun;           /* 09/009 Target's LUN number                */
-  BYTE     SRB_DeviceType;    /* 0a/010 Target's peripheral device type    */
-  BYTE     SRB_Rsvd1;         /* 0b/011 Reserved, must = 0                 */
-} PACKED SRB_GDEVBlock, *PSRB_GDEVBlock, FAR *LPSRB_GDEVBlock;
-
-
-/***************************************************************************
- ** SRB - EXECUTE SCSI COMMAND - SC_EXEC_SCSI_CMD (2)
- ***************************************************************************/
-typedef struct
-{
-  BYTE     SRB_Cmd;           /* 00/000 ASPI cmd code == SC_EXEC_SCSI_CMD  */
-  BYTE     SRB_Status;        /* 01/001 ASPI command status byte           */
-  BYTE     SRB_HaId;          /* 02/002 ASPI host adapter number           */
-  BYTE     SRB_Flags;         /* 03/003 Reserved, must = 0                 */
-  DWORD    SRB_Hdr_Rsvd;      /* 04/004 Reserved, must = 0                 */
-  BYTE     SRB_Target;        /* 08/008 Target's SCSI ID                   */
-  BYTE     SRB_Lun;           /* 09/009 Target's LUN                       */
-  WORD     SRB_Rsvd1;         /* 0a/010 Reserved for alignment             */
-  DWORD    SRB_BufLen;        /* 0c/012 Data Allocation Length             */
-  BYTE FAR *SRB_BufPointer;   /* 10/016 Data Buffer Pointer                */
-  BYTE     SRB_SenseLen;      /* 14/020 Sense Allocation Length            */
-  BYTE     SRB_CDBLen;        /* 15/021 CDB Length                         */
-  BYTE     SRB_HaStat;        /* 16/022 Host Adapter Status                */
-  BYTE     SRB_TargStat;      /* 17/023 Target Status                      */
-  VOID FAR *SRB_PostProc;     /* 18/024 Post routine                       */
-  BYTE     SRB_Rsvd2[20];     /* 1c/028 Reserved, must = 0                 */
-  BYTE     CDBByte[16];       /* 30/048 SCSI CDB                           */
-  BYTE SenseArea[SENSE_LEN+2]; /* 40/064 Request Sense buffer              */
-} PACKED SRB_ExecSCSICmd, *PSRB_ExecSCSICmd, FAR *LPSRB_ExecSCSICmd;
-
-
-typedef struct
-{
-  BYTE     SRB_Cmd;           /* 00/000 ASPI cmd code == SC_ABORT_SRB      */
-  BYTE     SRB_Status;        /* 01/001 ASPI command status byte           */
-  BYTE     SRB_HaId;          /* 02/002 ASPI host adapter number           */
-  BYTE     SRB_Flags;         /* 03/003 Reserved, must = 0                 */
-  DWORD    SRB_Hdr_Rsvd;      /* 04/004 Reserved, must = 0                 */
-  void     *SRB_ToAbort;      /* 08/008 Pointer to SRB to abort            */
-} PACKED SRB_Abort, *PSRB_Abort, FAR *LPSRB_Abort;
-
-
-/***************************************************************************
- ** SRB - BUS DEVICE RESET - SC_RESET_DEV (4)
- ***************************************************************************/
-typedef struct
-{
-  BYTE     SRB_Cmd;           /* 00/000 ASPI cmd code == SC_RESET_DEV      */
-  BYTE     SRB_Status;        /* 01/001 ASPI command status byte           */
-  BYTE     SRB_HaId;          /* 02/002 ASPI host adapter number           */
-  DWORD    SRB_Flags;        /* 04/004 Reserved                           */
-  BYTE     SRB_Target;        /* 08/008 Target's SCSI ID                   */
-  BYTE     SRB_Lun;           /* 09/009 Target's LUN number                */
-  BYTE     SRB_Rsvd1[12];     /* 0A/010 Reserved for alignment             */
-  BYTE     SRB_HaStat;        /* 16/022 Host Adapter Status                */
-  BYTE     SRB_TargStat;      /* 17/023 Target Status                      */
-  VOID FAR *SRB_PostProc;     /* 18/024 Post routine                       */
-  BYTE     SRB_Rsvd2[36];     /* 1C/028 Reserved, must = 0                 */
-} SRB_BusDeviceReset, *PSRB_BusDeviceReset, FAR *LPSRB_BusDeviceReset;
-
-typedef struct tag_ASPI32BUFF
-{
-  PBYTE     AB_BufPointer;
-  DWORD     AB_BufLen;
-  DWORD     AB_ZeroFill;
-  DWORD     AB_Reserved;
-} PACKED ASPI32BUFF, *PASPI32BUFF, FAR *LPASPI32BUFF;
-
-typedef struct 
-{
-  BYTE      SRB_Cmd;
-  BYTE      SRB_Status;
-  BYTE      SRB_HaId;
-  BYTE      SRB_Flags;
-  DWORD     SRB_Hdr_Rsvd;
-} SRB, *PSRB, FAR *LPSRB;
-
-#endif
diff --git a/tools/ioemu/iodev/biosdev.cc b/tools/ioemu/iodev/biosdev.cc
deleted file mode 100644 (file)
index d4a6ef2..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: biosdev.cc,v 1.7 2003/12/08 19:36:23 danielg4 Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-// Here are the virtual ports use to display messages from the bioses :
-//
-//  0x0400 : rombios Panic port with message
-//  0x0401 : rombios Panic port with line number
-//  0x0402 : rombios Info port with message
-//  0x0403 : rombios Debug port with message
-//
-//  0x0500 : vgabios Info port with message
-//  0x0501 : vgabios Panic port with message
-//  0x0502 : vgabios Panic port with line number
-//  0x0503 : vgabios Debug port with message
-
-
-// Define BX_PLUGGABLE in files that can be compiled into plugins.  For
-// platforms that require a special tag on exported symbols, BX_PLUGGABLE 
-// is used to know when we are exporting symbols and when we are importing.
-#define BX_PLUGGABLE
-
-#include "bochs.h"
-
-bx_biosdev_c *theBiosDevice;
-
-  int
-libbiosdev_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
-{
-  theBiosDevice = new bx_biosdev_c ();
-  bx_devices.pluginBiosDevice = theBiosDevice;
-  BX_REGISTER_DEVICE_DEVMODEL(plugin, type, theBiosDevice, BX_PLUGIN_BIOSDEV);
-  return(0); // Success
-}
-
-  void
-libbiosdev_LTX_plugin_fini(void)
-{
-}
-
-logfunctions  *bioslog;
-logfunctions  *vgabioslog;
-
-bx_biosdev_c::bx_biosdev_c(void)
-{
-  bioslog = new logfunctions();
-  bioslog->put("BIOS");
-  bioslog->settype(BIOSLOG);
-  s.bios_message_i = 0;
-
-  vgabioslog = new logfunctions();
-  vgabioslog->put("VBIOS");
-  vgabioslog->settype(BIOSLOG);
-  s.vgabios_message_i = 0;
-}
-
-bx_biosdev_c::~bx_biosdev_c(void)
-{
-    if ( bioslog != NULL )
-    {
-        delete bioslog;
-        bioslog = NULL;
-    }
-
-    if ( vgabioslog != NULL )
-    {
-        delete vgabioslog;
-        vgabioslog = NULL;
-    }
-}
-
-  void
-bx_biosdev_c::init(void)
-{
-  DEV_register_iowrite_handler(this, write_handler, 0x0400, "Bios Panic Port 1", 3);
-  DEV_register_iowrite_handler(this, write_handler, 0x0401, "Bios Panic Port 2", 3);
-  DEV_register_iowrite_handler(this, write_handler, 0x0403, "Bios Debug Port", 1);
-  DEV_register_iowrite_handler(this, write_handler, 0x0402, "Bios Info Port", 1);
-
-  DEV_register_iowrite_handler(this, write_handler, 0x0501, "VGABios Panic Port 1", 3);
-  DEV_register_iowrite_handler(this, write_handler, 0x0502, "VGABios Panic Port 2", 3);
-  DEV_register_iowrite_handler(this, write_handler, 0x0503, "VGABios Debug Port", 1);
-  DEV_register_iowrite_handler(this, write_handler, 0x0500, "VGABios Info Port", 1);
-}
-
-  void
-bx_biosdev_c::reset(unsigned type)
-{
-}
-
-  // static IO port write callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-  void
-bx_biosdev_c::write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len)
-{
-#if !BX_USE_BIOS_SMF
-  bx_biosdev_c *class_ptr = (bx_biosdev_c *) this_ptr;
-
-  class_ptr->write(address, value, io_len);
-}
-
-  void
-bx_biosdev_c::write(Bit32u address, Bit32u value, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif  // !BX_USE_BIOS_SMF
-  UNUSED(io_len);
-
-
-  switch (address) {
-    // 0x400-0x401 are used as panic ports for the rombios
-    case 0x0401:
-      if (BX_BIOS_THIS s.bios_message_i > 0) {
-       // if there are bits of message in the buffer, print them as the
-       // panic message.  Otherwise fall into the next case.
-       if (BX_BIOS_THIS s.bios_message_i >= BX_BIOS_MESSAGE_SIZE)
-         BX_BIOS_THIS s.bios_message_i = BX_BIOS_MESSAGE_SIZE-1;
-        BX_BIOS_THIS s.bios_message[ BX_BIOS_THIS s.bios_message_i] = 0;
-       BX_BIOS_THIS s.bios_message_i = 0;
-        bioslog->panic("%s", BX_BIOS_THIS s.bios_message);
-       break;
-      }
-    case 0x0400:
-      bioslog->panic("BIOS panic at rombios.c, line %d", value);
-      break;
-
-    // 0x0402 is used as the info port for the rombios
-    // 0x0403 is used as the debug port for the rombios
-    case 0x0402:
-    case 0x0403:
-      BX_BIOS_THIS s.bios_message[BX_BIOS_THIS s.bios_message_i] =
-        (Bit8u) value;
-      BX_BIOS_THIS s.bios_message_i ++;
-      if ( BX_BIOS_THIS s.bios_message_i >= BX_BIOS_MESSAGE_SIZE ) {
-        BX_BIOS_THIS s.bios_message[ BX_BIOS_MESSAGE_SIZE - 1] = 0;
-        BX_BIOS_THIS s.bios_message_i = 0;
-       if (address==0x403) bioslog->ldebug("%s", BX_BIOS_THIS s.bios_message);
-       else bioslog->info("%s", BX_BIOS_THIS s.bios_message);
-       }
-      else if ((value & 0xff) == '\n') {
-        BX_BIOS_THIS s.bios_message[ BX_BIOS_THIS s.bios_message_i - 1 ] = 0;
-        BX_BIOS_THIS s.bios_message_i = 0;
-       if (address==0x403) bioslog->ldebug("%s", BX_BIOS_THIS s.bios_message);
-       else bioslog->info("%s", BX_BIOS_THIS s.bios_message);
-        }
-      break;
-
-    // 0x501-0x502 are used as panic ports for the vgabios
-    case 0x0502:
-      if (BX_BIOS_THIS s.vgabios_message_i > 0) {
-       // if there are bits of message in the buffer, print them as the
-       // panic message.  Otherwise fall into the next case.
-       if (BX_BIOS_THIS s.vgabios_message_i >= BX_BIOS_MESSAGE_SIZE)
-         BX_BIOS_THIS s.vgabios_message_i = BX_BIOS_MESSAGE_SIZE-1;
-        BX_BIOS_THIS s.vgabios_message[ BX_BIOS_THIS s.vgabios_message_i] = 0;
-       BX_BIOS_THIS s.vgabios_message_i = 0;
-        vgabioslog->panic("%s", BX_BIOS_THIS s.vgabios_message);
-       break;
-      }
-    case 0x0501:
-      vgabioslog->panic("BIOS panic at rombios.c, line %d", value);
-      break;
-
-    // 0x0500 is used as the message port for the vgabios
-    case 0x0500:
-    case 0x0503:
-      BX_BIOS_THIS s.vgabios_message[BX_BIOS_THIS s.vgabios_message_i] =
-        (Bit8u) value;
-      BX_BIOS_THIS s.vgabios_message_i ++;
-      if ( BX_BIOS_THIS s.vgabios_message_i >= BX_BIOS_MESSAGE_SIZE ) {
-        BX_BIOS_THIS s.vgabios_message[ BX_BIOS_MESSAGE_SIZE - 1] = 0;
-        BX_BIOS_THIS s.vgabios_message_i = 0;
-        if (address==0x503) vgabioslog->ldebug("%s", BX_BIOS_THIS s.vgabios_message);
-        else vgabioslog->info("%s", BX_BIOS_THIS s.vgabios_message);
-        }
-      else if ((value & 0xff) == '\n') {
-        BX_BIOS_THIS s.vgabios_message[ BX_BIOS_THIS s.vgabios_message_i - 1 ] = 0;
-        BX_BIOS_THIS s.vgabios_message_i = 0;
-        if (address==0x503) vgabioslog->ldebug("%s", BX_BIOS_THIS s.vgabios_message);
-        else vgabioslog->info("%s", BX_BIOS_THIS s.vgabios_message);
-        }
-      break;
-
-    default:
-           break;
-    }
-}
diff --git a/tools/ioemu/iodev/biosdev.h b/tools/ioemu/iodev/biosdev.h
deleted file mode 100644 (file)
index 7cd9873..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-
-// $Id: biosdev.h,v 1.3 2002/10/24 21:07:09 bdenney Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-#define BX_BIOS_MESSAGE_SIZE 80
-
-
-#if BX_USE_BIOS_SMF
-#  define BX_BIOS_SMF  static
-#  define BX_BIOS_THIS theBiosDevice->
-#else
-#  define BX_BIOS_SMF
-#  define BX_BIOS_THIS this->
-#endif
-
-
-class bx_biosdev_c : public bx_devmodel_c {
-public:
-  bx_biosdev_c(void);
-  ~bx_biosdev_c(void);
-
-  virtual void init(void);
-  virtual void reset (unsigned type);
-
-private:
-
-  static void   write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);
-#if !BX_USE_BIOS_SMF
-  void   write(Bit32u address, Bit32u value, unsigned io_len);
-#endif
-
-  struct {
-    Bit8u bios_message[BX_BIOS_MESSAGE_SIZE];
-    unsigned int bios_message_i;
-
-    Bit8u vgabios_message[BX_BIOS_MESSAGE_SIZE];
-    unsigned int vgabios_message_i;
-    } s;  // state information
-
-  };
diff --git a/tools/ioemu/iodev/cdrom.cc b/tools/ioemu/iodev/cdrom.cc
deleted file mode 100644 (file)
index 2b78e8d..0000000
+++ /dev/null
@@ -1,1338 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: cdrom.cc,v 1.66 2003/12/08 23:49:48 danielg4 Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-// These are the low-level CDROM functions which are called
-// from 'harddrv.cc'.  They effect the OS specific functionality
-// needed by the CDROM emulation in 'harddrv.cc'.  Mostly, just
-// ioctl() calls and such.  Should be fairly easy to add support
-// for your OS if it is not supported yet.
-
-
-// Define BX_PLUGGABLE in files that can be compiled into plugins.  For
-// platforms that require a special tag on exported symbols, BX_PLUGGABLE 
-// is used to know when we are exporting symbols and when we are importing.
-#define BX_PLUGGABLE
-
-#include "bochs.h"
-#if BX_SUPPORT_CDROM
-
-#define LOG_THIS /* no SMF tricks here, not needed */
-
-extern "C" {
-#include <errno.h>
-}
-
-#ifdef __linux__
-extern "C" {
-#include <sys/ioctl.h>
-#include <linux/cdrom.h>
-// I use the framesize in non OS specific code too
-#define BX_CD_FRAMESIZE CD_FRAMESIZE
-}
-
-#elif defined(__GNU__) || (defined(__CYGWIN32__) && !defined(WIN32))
-extern "C" {
-#include <sys/ioctl.h>
-#define BX_CD_FRAMESIZE 2048
-#define CD_FRAMESIZE 2048
-}
-
-#elif BX_WITH_MACOS
-#define BX_CD_FRAMESIZE 2048
-#define CD_FRAMESIZE 2048
-
-#elif defined(__sun)
-extern "C" {
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <sys/cdio.h>
-#define BX_CD_FRAMESIZE CDROM_BLK_2048
-}
-
-#elif defined(__DJGPP__)
-extern "C" {
-#include <sys/ioctl.h>
-#define BX_CD_FRAMESIZE 2048
-#define CD_FRAMESIZE 2048
-}
-
-#elif defined(__BEOS__)
-#include "cdrom_beos.h"
-#define BX_CD_FRAMESIZE 2048
-
-#elif (defined (__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__))
-// OpenBSD pre version 2.7 may require extern "C" { } structure around
-// all the includes, because the i386 sys/disklabel.h contains code which 
-// c++ considers invalid.
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/file.h>
-#include <sys/cdio.h>
-#include <sys/ioctl.h>
-#include <sys/disklabel.h>
-// ntohl(x) et al have been moved out of sys/param.h in FreeBSD 5
-#include <netinet/in.h>
-
-// XXX
-#define BX_CD_FRAMESIZE 2048
-#define CD_FRAMESIZE   2048
-
-#elif defined(__APPLE__)
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <dev/disk.h>
-#include <errno.h>
-#include <paths.h>
-#include <sys/param.h>
-
-#include <IOKit/IOKitLib.h>
-#include <IOKit/IOBSD.h>
-#include <IOKit/storage/IOCDMedia.h>
-#include <IOKit/storage/IOMedia.h>
-#include <IOKit/storage/IOCDTypes.h>
-#include <CoreFoundation/CoreFoundation.h>
-
-// These definitions were taken from mount_cd9660.c
-// There are some similar definitions in IOCDTypes.h
-// however there seems to be some dissagreement in 
-// the definition of CDTOC.length
-struct _CDMSF {
-       u_char   minute;
-       u_char   second;
-       u_char   frame;
-};
-
-#define MSF_TO_LBA(msf)                \
-       (((((msf).minute * 60UL) + (msf).second) * 75UL) + (msf).frame - 150)
-
-struct _CDTOC_Desc {
-       u_char        session;
-       u_char        ctrl_adr;  /* typed to be machine and compiler independent */
-       u_char        tno;
-       u_char        point;
-       struct _CDMSF  address;
-       u_char        zero;
-       struct _CDMSF  p;
-};
-
-struct _CDTOC {
-       u_short            length;  /* in native cpu endian */
-       u_char             first_session;
-       u_char             last_session;
-       struct _CDTOC_Desc  trackdesc[1];
-};
-
-static kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator, mach_port_t *masterPort );
-static kern_return_t GetDeviceFilePath( io_iterator_t mediaIterator, char *deviceFilePath, CFIndex maxPathSize );
-//int OpenDrive( const char *deviceFilePath );
-static struct _CDTOC * ReadTOC( const char * devpath );
-
-static char CDDevicePath[ MAXPATHLEN ];
-
-#define BX_CD_FRAMESIZE 2048
-#define CD_FRAMESIZE   2048
-
-#elif defined(WIN32)
-// windows.h included by bochs.h
-#include <winioctl.h>
-#include "aspi-win32.h"
-#include "scsidefs.h"
-
-DWORD (*GetASPI32SupportInfo)(void);
-DWORD (*SendASPI32Command)(LPSRB);
-BOOL  (*GetASPI32Buffer)(PASPI32BUFF);
-BOOL  (*FreeASPI32Buffer)(PASPI32BUFF);
-BOOL  (*TranslateASPI32Address)(PDWORD,PDWORD);
-DWORD (*GetASPI32DLLVersion)(void);
-
-
-static BOOL bUseASPI = FALSE;
-static BOOL bHaveDev;
-static UINT cdromCount = 0;
-static HINSTANCE hASPI = NULL;
-
-#define BX_CD_FRAMESIZE 2048
-#define CD_FRAMESIZE   2048
-
-#else // all others (Irix, Tru64)
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#define BX_CD_FRAMESIZE 2048
-#define CD_FRAMESIZE 2048 
-#endif
-
-#include <stdio.h>
-
-#ifdef __APPLE__
-static kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator,
-                                          mach_port_t *masterPort )
-{
-  kern_return_t     kernResult;
-  CFMutableDictionaryRef     classesToMatch;
-  kernResult = IOMasterPort( bootstrap_port, masterPort );
-  if ( kernResult != KERN_SUCCESS )
-    {
-      fprintf ( stderr, "IOMasterPort returned %d\n", kernResult );
-      return kernResult;
-    }
-  // CD media are instances of class kIOCDMediaClass.
-  classesToMatch = IOServiceMatching( kIOCDMediaClass );
-  if ( classesToMatch == NULL )
-    fprintf ( stderr, "IOServiceMatching returned a NULL dictionary.\n" );
-  else
-    {
-      // Each IOMedia object has a property with key kIOMediaEjectableKey
-      // which is true if the media is indeed ejectable. So add property
-      // to CFDictionary for matching.
-      CFDictionarySetValue( classesToMatch,
-                            CFSTR( kIOMediaEjectableKey ), kCFBooleanTrue );
-    }
-  kernResult = IOServiceGetMatchingServices( *masterPort,
-                                             classesToMatch, mediaIterator );
-  if ( (kernResult != KERN_SUCCESS) || (*mediaIterator == NULL) ) 
-    fprintf( stderr, "No ejectable CD media found.\n kernResult = %d\n", kernResult );
-
-  return kernResult;
-}
-
-
-static kern_return_t GetDeviceFilePath( io_iterator_t mediaIterator,
-                                       char *deviceFilePath, CFIndex maxPathSize )
-{
-  io_object_t nextMedia;
-  kern_return_t kernResult = KERN_FAILURE;
-  nextMedia = IOIteratorNext( mediaIterator );
-  if ( nextMedia == NULL )
-    {
-      *deviceFilePath = '\0';
-    }
-  else
-    {
-      CFTypeRef    deviceFilePathAsCFString;
-      deviceFilePathAsCFString = IORegistryEntryCreateCFProperty(
-                                                                 nextMedia, CFSTR( kIOBSDNameKey ),
-                                                                 kCFAllocatorDefault, 0 );
-      *deviceFilePath = '\0';
-      if ( deviceFilePathAsCFString )
-        {
-          size_t devPathLength = strlen( _PATH_DEV );
-          strcpy( deviceFilePath, _PATH_DEV );
-          if ( CFStringGetCString( (const __CFString *) deviceFilePathAsCFString,
-                                   deviceFilePath + devPathLength,
-                                   maxPathSize - devPathLength,
-                                   kCFStringEncodingASCII ) )
-            {
-              // fprintf( stderr, "BSD path: %s\n", deviceFilePath );
-              kernResult = KERN_SUCCESS;
-            }
-          CFRelease( deviceFilePathAsCFString );
-        }
-    }
-  IOObjectRelease( nextMedia );
-  return kernResult;
-}
-
-
-static int OpenDrive( const char *deviceFilePath )
-{
-
-  int fileDescriptor;
-
-  fileDescriptor = open( deviceFilePath, O_RDONLY );
-  if ( fileDescriptor == -1 )
-    fprintf( stderr, "Error %d opening device %s.\n", errno, deviceFilePath );
-  return fileDescriptor;
-
-}
-
-static struct _CDTOC * ReadTOC( const char * devpath ) {
-
-  struct _CDTOC * toc_p = NULL;
-  io_iterator_t iterator = 0;
-  io_registry_entry_t service = 0;
-  CFDictionaryRef properties = 0;
-  CFDataRef data = 0;
-  mach_port_t port = 0;
-  char * devname;
-  
-  if (( devname = strrchr( devpath, '/' )) != NULL ) {
-    ++devname;
-  }
-  else {
-    devname = (char *) devpath;
-  }
-
-  if ( IOMasterPort(bootstrap_port, &port ) != KERN_SUCCESS ) {
-    fprintf( stderr, "IOMasterPort failed\n" );
-    goto Exit;
-  }
-
-  if ( IOServiceGetMatchingServices( port, IOBSDNameMatching( port, 0, devname ),
-                                    &iterator ) != KERN_SUCCESS ) {
-    fprintf( stderr, "IOServiceGetMatchingServices failed\n" );
-    goto Exit;
-  }
-  
-  service = IOIteratorNext( iterator );
-
-  IOObjectRelease( iterator );
-
-  iterator = 0;
-
-  while ( service && !IOObjectConformsTo( service, "IOCDMedia" )) {
-    if ( IORegistryEntryGetParentIterator( service, kIOServicePlane,
-                                          &iterator ) != KERN_SUCCESS ) {
-      fprintf( stderr, "IORegistryEntryGetParentIterator failed\n" );
-      goto Exit;
-    }
-
-    IOObjectRelease( service );
-    service = IOIteratorNext( iterator );
-    IOObjectRelease( iterator );
-
-  }
-
-  if ( service == NULL ) {
-    fprintf( stderr, "CD media not found\n" );
-    goto Exit;
-  }
-
-  if ( IORegistryEntryCreateCFProperties( service, (__CFDictionary **) &properties,
-                                         kCFAllocatorDefault,
-                                         kNilOptions ) != KERN_SUCCESS ) {
-    fprintf( stderr, "IORegistryEntryGetParentIterator failed\n" );
-    goto Exit;
-  }
-
-  data = (CFDataRef) CFDictionaryGetValue( properties, CFSTR(kIOCDMediaTOCKey) );
-  if ( data == NULL ) {
-    fprintf( stderr, "CFDictionaryGetValue failed\n" );
-    goto Exit;
-  }
-  else {
-
-    CFRange range;
-    CFIndex buflen;
-
-    buflen = CFDataGetLength( data ) + 1;
-    range = CFRangeMake( 0, buflen );
-    toc_p = (struct _CDTOC *) malloc( buflen );
-    if ( toc_p == NULL ) {
-      fprintf( stderr, "Out of memory\n" );
-      goto Exit;
-    }
-    else {
-      CFDataGetBytes( data, range, (unsigned char *) toc_p );
-    }
-
-    /*
-    fprintf( stderr, "Table of contents\n length %d first %d last %d\n",
-           toc_p->length, toc_p->first_session, toc_p->last_session );
-    */
-
-    CFRelease( properties );
-
-  }
-  
-
- Exit:
-
-  if ( service ) {
-    IOObjectRelease( service );
-  }
-
-  return toc_p;
-
-}
-#endif
-
-#ifdef WIN32
-
-bool ReadCDSector(unsigned int hid, unsigned int tid, unsigned int lun, unsigned long frame, unsigned char *buf, int bufsize)
-{
-       HANDLE hEventSRB;
-       SRB_ExecSCSICmd srb;
-       DWORD dwStatus;
-
-       hEventSRB = CreateEvent(NULL, TRUE, FALSE, NULL);
-       
-       memset(&srb,0,sizeof(SRB_ExecSCSICmd));
-       srb.SRB_Cmd        = SC_EXEC_SCSI_CMD;
-       srb.SRB_HaId       = hid;
-       srb.SRB_Target     = tid;
-       srb.SRB_Lun        = lun;
-       srb.SRB_Flags      = SRB_DIR_IN | SRB_EVENT_NOTIFY;
-       srb.SRB_SenseLen   = SENSE_LEN;
-       srb.SRB_PostProc   = hEventSRB;
-       srb.SRB_BufPointer = buf;
-       srb.SRB_BufLen     = bufsize;
-       srb.SRB_CDBLen     = 10;
-       srb.CDBByte[0]     = SCSI_READ10;
-       srb.CDBByte[2]     = (unsigned char) (frame>>24);
-       srb.CDBByte[3]     = (unsigned char) (frame>>16);
-       srb.CDBByte[4]     = (unsigned char) (frame>>8);
-       srb.CDBByte[5]     = (unsigned char) (frame);
-       srb.CDBByte[7]     = 0;
-       srb.CDBByte[8]     = 1; /* read 1 frames */
-
-       ResetEvent(hEventSRB);
-       dwStatus = SendASPI32Command((SRB *)&srb);
-       if(dwStatus == SS_PENDING) {
-               WaitForSingleObject(hEventSRB, 100000);
-       }
-       CloseHandle(hEventSRB);
-       return (srb.SRB_TargStat == STATUS_GOOD);
-}
-
-int GetCDCapacity(unsigned int hid, unsigned int tid, unsigned int lun)
-{
-       HANDLE hEventSRB;
-       SRB_ExecSCSICmd srb;
-       DWORD dwStatus;
-       unsigned char buf[8];
-
-       hEventSRB = CreateEvent(NULL, TRUE, FALSE, NULL);
-       
-       memset(&buf, 0, sizeof(buf));
-       memset(&srb,0,sizeof(SRB_ExecSCSICmd));
-       srb.SRB_Cmd        = SC_EXEC_SCSI_CMD;
-       srb.SRB_HaId       = hid;
-       srb.SRB_Target     = tid;
-       srb.SRB_Lun        = lun;
-       srb.SRB_Flags      = SRB_DIR_IN | SRB_EVENT_NOTIFY;
-       srb.SRB_SenseLen   = SENSE_LEN;
-       srb.SRB_PostProc   = hEventSRB;
-       srb.SRB_BufPointer = (unsigned char *)buf;
-       srb.SRB_BufLen     = 8;
-       srb.SRB_CDBLen     = 10;
-       srb.CDBByte[0]     = SCSI_READCDCAP;
-       srb.CDBByte[2]     = 0;
-       srb.CDBByte[3]     = 0;
-       srb.CDBByte[4]     = 0;
-       srb.CDBByte[5]     = 0;
-       srb.CDBByte[8]     = 0;
-
-       ResetEvent(hEventSRB);
-       dwStatus = SendASPI32Command((SRB *)&srb);
-       if(dwStatus == SS_PENDING) {
-               WaitForSingleObject(hEventSRB, 100000);
-       }
-
-       CloseHandle(hEventSRB);
-       return ((buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + buf[3]) * ((buf[4] << 24) + (buf[5] << 16) + (buf[6] << 8) + buf[7]);
-}
-
-#endif
-
-cdrom_interface::cdrom_interface(char *dev)
-{
-  put("CD");
-  settype(CDLOG);
-  fd = -1; // File descriptor not yet allocated
-
-  if ( dev == NULL )
-    path = NULL;
-  else {
-    path = strdup(dev);
-  }
-  using_file=0;
-}
-
-void
-cdrom_interface::init(void) {
-  BX_DEBUG(("Init $Id: cdrom.cc,v 1.66 2003/12/08 23:49:48 danielg4 Exp $"));
-  BX_INFO(("file = '%s'",path));
-}
-
-cdrom_interface::~cdrom_interface(void)
-{
-#ifdef WIN32
-#else
-       if (fd >= 0)
-               close(fd);
-#endif
-       if (path)
-               free(path);
-       BX_DEBUG(("Exit"));
-}
-
-  bx_bool
-cdrom_interface::insert_cdrom(char *dev)
-{
-  unsigned char buffer[BX_CD_FRAMESIZE];
-  ssize_t ret;
-
-  // Load CD-ROM. Returns false if CD is not ready.
-  if (dev != NULL) path = strdup(dev);
-  BX_INFO (("load cdrom with path=%s", path));
-#ifdef WIN32
-    char drive[256];
-       OSVERSIONINFO osi;
-    if ( (path[1] == ':') && (strlen(path) == 2) )
-    {
-         osi.dwOSVersionInfoSize = sizeof(osi);
-         GetVersionEx(&osi);
-         if(osi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
-           // Use direct device access under windows NT/2k
-
-        // With all the backslashes it's hard to see, but to open D: drive 
-        // the name would be: \\.\d:
-        sprintf(drive, "\\\\.\\%s", path);
-        using_file = 0;
-        BX_INFO (("Using direct access for cdrom."));
-        // This trick only works for Win2k and WinNT, so warn the user of that.
-         } else {
-                 BX_INFO(("Using ASPI for cdrom. Drive letters are unused yet."));
-          bUseASPI = TRUE;
-         }
-    }
-    else
-    {
-      strcpy(drive,path);
-      using_file = 1;
-         bUseASPI = FALSE;
-      BX_INFO (("Opening image file as a cd"));
-    }
-       if(bUseASPI) {
-               DWORD d;
-               UINT cdr, cnt, max;
-               UINT i, j, k;
-               SRB_HAInquiry sh;
-               SRB_GDEVBlock sd;
-               if (!hASPI) {
-                 hASPI = LoadLibrary("WNASPI32.DLL");
-               }
-               if(hASPI) {
-            SendASPI32Command      = (DWORD(*)(LPSRB))GetProcAddress( hASPI, "SendASPI32Command" );
-                       GetASPI32DLLVersion    = (DWORD(*)(void))GetProcAddress( hASPI, "GetASPI32DLLVersion" );
-                       GetASPI32SupportInfo   = (DWORD(*)(void))GetProcAddress( hASPI, "GetASPI32SupportInfo" );
-//                     BX_INFO(("Using first CDROM.  Please upgrade your ASPI drivers to version 4.01 or later if you wish to specify a cdrom driver."));
-                       
-                       cdr = 0;
-                       bHaveDev = FALSE;
-                       d = GetASPI32SupportInfo();
-                       cnt = LOBYTE(LOWORD(d));
-                       for(i = 0; i < cnt; i++) {
-                               memset(&sh, 0, sizeof(sh));
-                               sh.SRB_Cmd  = SC_HA_INQUIRY;
-                               sh.SRB_HaId = i;
-                               SendASPI32Command((LPSRB)&sh);
-                               if(sh.SRB_Status != SS_COMP)
-                                       continue;
-
-                               max = (int)sh.HA_Unique[3];
-                               for(j = 0; j < max; j++) {
-                                       for(k = 0; k < 8; k++) {
-                                               memset(&sd, 0, sizeof(sd));
-                                               sd.SRB_Cmd    = SC_GET_DEV_TYPE;
-                                               sd.SRB_HaId   = i;
-                                               sd.SRB_Target = j;
-                                               sd.SRB_Lun    = k;
-                                               SendASPI32Command((LPSRB)&sd);
-                                               if(sd.SRB_Status == SS_COMP) {
-                                                       if(sd.SRB_DeviceType == DTYPE_CDROM) {
-                                                               cdr++;
-                                                               if(cdr > cdromCount) {
-                                                                       hid = i;
-                                                                       tid = j;
-                                                                       lun = k;
-                                                                       cdromCount++;
-                                                                       bHaveDev = TRUE;
-                                                               }
-                                                       }
-                                               }
-                                               if(bHaveDev) break;
-                                       }
-                                       if(bHaveDev) break;
-                               }
-
-                       }
-               } else {
-                       BX_PANIC(("Could not load ASPI drivers, so cdrom access will fail"));
-               }
-               fd=1;
-       } else {
-         BX_INFO(("Using direct access for CDROM"));
-      hFile=CreateFile((char *)&drive, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, NULL); 
-      if (hFile !=(void *)0xFFFFFFFF)
-        fd=1;
-       }
-#elif defined(__APPLE__)
-      if(strcmp(path, "drive") == 0)
-      {
-        mach_port_t masterPort = NULL;
-        io_iterator_t mediaIterator;
-        kern_return_t kernResult;
-        
-        BX_INFO(( "Insert CDROM" )); 
-        
-        kernResult = FindEjectableCDMedia( &mediaIterator, &masterPort );
-        if ( kernResult != KERN_SUCCESS ) {
-          BX_INFO (("Unable to find CDROM"));
-          return false;
-        }
-        
-        kernResult = GetDeviceFilePath( mediaIterator, CDDevicePath, sizeof( CDDevicePath ) );
-        if ( kernResult != KERN_SUCCESS ) {
-          BX_INFO (("Unable to get CDROM device file path" ));
-          return false;
-        }
-       
-        // Here a cdrom was found so see if we can read from it.
-        // At this point a failure will result in panic.
-        if ( strlen( CDDevicePath ) ) {
-          fd = open(CDDevicePath, O_RDONLY);
-        }
-      }
-      else
-      {
-        fd = open(path, O_RDONLY);
-      }
-#else
-      // all platforms except win32
-      fd = open(path, O_RDONLY);
-#endif
-    if (fd < 0) {
-       BX_ERROR(( "open cd failed for %s: %s", path, strerror(errno)));
-       return(false);
-    }
-
-  // I just see if I can read a sector to verify that a
-  // CD is in the drive and readable.
-#ifdef WIN32
-    if(bUseASPI) {
-      return ReadCDSector(hid, tid, lun, 0, buffer, BX_CD_FRAMESIZE);
-    } else {
-      if (!ReadFile(hFile, (void *) buffer, BX_CD_FRAMESIZE, (unsigned long *) &ret, NULL)) {
-         CloseHandle(hFile);
-         fd = -1;
-         BX_DEBUG(( "insert_cdrom: read returns error." ));
-         return(false);
-      }
-    }
-#else
-    // do fstat to determine if it's a file or a device, then set using_file.
-    struct stat stat_buf;
-    ret = fstat (fd, &stat_buf);
-    if (ret) {
-      BX_PANIC (("fstat cdrom file returned error: %s", strerror (errno)));
-    }
-    if (S_ISREG (stat_buf.st_mode)) {
-      using_file = 1;
-      BX_INFO (("Opening image file %s as a cd.", path));
-    } else {
-      using_file = 0;
-      BX_INFO (("Using direct access for cdrom."));
-    }
-
-    ret = read(fd, (char*) &buffer, BX_CD_FRAMESIZE);
-    if (ret < 0) {
-       close(fd);
-       fd = -1;
-       BX_DEBUG(( "insert_cdrom: read returns error: %s", strerror (errno) ));
-       return(false);
-        }
-#endif
-    return(true);
-}
-
-  int
-cdrom_interface::start_cdrom()
-{
-  // Spin up the cdrom drive.
-
-  if (fd >= 0) {
-#if defined(__NetBSD__)
-    if (ioctl (fd, CDIOCSTART) < 0)
-       BX_DEBUG(( "start_cdrom: start returns error: %s", strerror (errno) ));
-    return(true);
-#else
-    BX_INFO(("start_cdrom: your OS is not supported yet."));
-    return(false); // OS not supported yet, return false always.
-#endif
-    }
-  return(false);
-}
-
-  void
-cdrom_interface::eject_cdrom()
-{
-  // Logically eject the CD.  I suppose we could stick in
-  // some ioctl() calls to really eject the CD as well.
-
-  if (fd >= 0) {
-#if (defined(__OpenBSD__) || defined(__FreeBSD__))
-    (void) ioctl (fd, CDIOCALLOW);
-    if (ioctl (fd, CDIOCEJECT) < 0)
-         BX_DEBUG(( "eject_cdrom: eject returns error." ));
-#endif
-
-#ifdef WIN32
-if (using_file == 0)
-{
-       if(bUseASPI) {
-       } else {
-               DWORD lpBytesReturned;
-               DeviceIoControl(hFile, IOCTL_STORAGE_EJECT_MEDIA, NULL, 0, NULL, 0, &lpBytesReturned, NULL);
-       }
-}
-#else // WIN32
-
-#if __linux__
-  if (!using_file)
-    ioctl (fd, CDROMEJECT, NULL);
-#endif
-
-    close(fd);
-#endif // WIN32
-    fd = -1;
-    }
-}
-
-
-  bx_bool
-cdrom_interface::read_toc(uint8* buf, int* length, bx_bool msf, int start_track)
-{
-  // Read CD TOC. Returns false if start track is out of bounds.
-
-  if (fd < 0) {
-    BX_PANIC(("cdrom: read_toc: file not open."));
-    }
-
-#if defined(WIN32)
-  if (1) { // This is a hack and works okay if there's one rom track only
-#else
-  if (using_file) {
-#endif
-    // From atapi specs : start track can be 0-63, AA
-    if ((start_track > 1) && (start_track != 0xaa)) 
-      return false;
-
-    buf[2] = 1;
-    buf[3] = 1;
-
-    int len = 4;
-    if (start_track <= 1) {
-      buf[len++] = 0; // Reserved
-      buf[len++] = 0x14; // ADR, control
-      buf[len++] = 1; // Track number
-      buf[len++] = 0; // Reserved
-
-      // Start address
-      if (msf) {
-        buf[len++] = 0; // reserved
-        buf[len++] = 0; // minute
-        buf[len++] = 2; // second
-        buf[len++] = 0; // frame
-      } else {
-        buf[len++] = 0;
-        buf[len++] = 0;
-        buf[len++] = 0;
-        buf[len++] = 0; // logical sector 0
-      }
-    }
-
-    // Lead out track
-    buf[len++] = 0; // Reserved
-    buf[len++] = 0x16; // ADR, control
-    buf[len++] = 0xaa; // Track number
-    buf[len++] = 0; // Reserved
-
-    uint32 blocks = capacity();
-
-    // Start address
-    if (msf) {
-      buf[len++] = 0; // reserved
-      buf[len++] = (uint8)(((blocks + 150) / 75) / 60); // minute
-      buf[len++] = (uint8)(((blocks + 150) / 75) % 60); // second
-      buf[len++] = (uint8)((blocks + 150) % 75); // frame;
-    } else {
-      buf[len++] = (blocks >> 24) & 0xff;
-      buf[len++] = (blocks >> 16) & 0xff;
-      buf[len++] = (blocks >> 8) & 0xff;
-      buf[len++] = (blocks >> 0) & 0xff;
-    }
-
-    buf[0] = ((len-2) >> 8) & 0xff;
-    buf[1] = (len-2) & 0xff;
-
-    *length = len;
-
-    return true;
-  }
-  // all these implementations below are the platform-dependent code required
-  // to read the TOC from a physical cdrom.
-#ifdef WIN32
-  {
-/*     #define IOCTL_CDROM_BASE                 FILE_DEVICE_CD_ROM
-     #define IOCTL_CDROM_READ_TOC         CTL_CODE(IOCTL_CDROM_BASE, 0x0000, METHOD_BUFFERED, FILE_READ_ACCESS)
-     unsigned long iBytesReturned;
-     DeviceIoControl(hFile, IOCTL_CDROM_READ_TOC, NULL, 0, NULL, 0, &iBytesReturned, NULL);       */
-    BX_ERROR (("WARNING: read_toc is not implemented, just returning length=1"));
-    *length = 1;
-    return true;
-  }
-#elif __linux__ || defined(__sun)
-  {
-  struct cdrom_tochdr tochdr;
-  if (ioctl(fd, CDROMREADTOCHDR, &tochdr))
-    BX_PANIC(("cdrom: read_toc: READTOCHDR failed."));
-
-  if ((start_track > tochdr.cdth_trk1) && (start_track != 0xaa))
-    return false;
-
-  buf[2] = tochdr.cdth_trk0;
-  buf[3] = tochdr.cdth_trk1;
-
-  if (start_track < tochdr.cdth_trk0)
-    start_track = tochdr.cdth_trk0;
-
-  int len = 4;
-  for (int i = start_track; i <= tochdr.cdth_trk1; i++) {
-    struct cdrom_tocentry tocentry;
-    tocentry.cdte_format = (msf) ? CDROM_MSF : CDROM_LBA;
-    tocentry.cdte_track = i;
-    if (ioctl(fd, CDROMREADTOCENTRY, &tocentry))
-      BX_PANIC(("cdrom: read_toc: READTOCENTRY failed."));
-    buf[len++] = 0; // Reserved
-    buf[len++] = (tocentry.cdte_adr << 4) | tocentry.cdte_ctrl ; // ADR, control
-    buf[len++] = i; // Track number
-    buf[len++] = 0; // Reserved
-
-    // Start address
-    if (msf) {
-      buf[len++] = 0; // reserved
-      buf[len++] = tocentry.cdte_addr.msf.minute;
-      buf[len++] = tocentry.cdte_addr.msf.second;
-      buf[len++] = tocentry.cdte_addr.msf.frame;
-    } else {
-      buf[len++] = (((unsigned)tocentry.cdte_addr.lba) >> 24) & 0xff;
-      buf[len++] = (((unsigned)tocentry.cdte_addr.lba) >> 16) & 0xff;
-      buf[len++] = (((unsigned)tocentry.cdte_addr.lba) >> 8) & 0xff;
-      buf[len++] = (((unsigned)tocentry.cdte_addr.lba) >> 0) & 0xff;
-    }
-  }
-
-  // Lead out track
-  struct cdrom_tocentry tocentry;
-  tocentry.cdte_format = (msf) ? CDROM_MSF : CDROM_LBA;
-#ifdef CDROM_LEADOUT
-  tocentry.cdte_track = CDROM_LEADOUT;
-#else
-  tocentry.cdte_track = 0xaa;
-#endif
-  if (ioctl(fd, CDROMREADTOCENTRY, &tocentry))
-    BX_PANIC(("cdrom: read_toc: READTOCENTRY lead-out failed."));
-  buf[len++] = 0; // Reserved
-  buf[len++] = (tocentry.cdte_adr << 4) | tocentry.cdte_ctrl ; // ADR, control
-  buf[len++] = 0xaa; // Track number
-  buf[len++] = 0; // Reserved
-
-  // Start address
-  if (msf) {
-    buf[len++] = 0; // reserved
-    buf[len++] = tocentry.cdte_addr.msf.minute;
-    buf[len++] = tocentry.cdte_addr.msf.second;
-    buf[len++] = tocentry.cdte_addr.msf.frame;
-  } else {
-    buf[len++] = (((unsigned)tocentry.cdte_addr.lba) >> 24) & 0xff;
-    buf[len++] = (((unsigned)tocentry.cdte_addr.lba) >> 16) & 0xff;
-    buf[len++] = (((unsigned)tocentry.cdte_addr.lba) >> 8) & 0xff;
-    buf[len++] = (((unsigned)tocentry.cdte_addr.lba) >> 0) & 0xff;
-  }
-
-  buf[0] = ((len-2) >> 8) & 0xff;
-  buf[1] = (len-2) & 0xff;
-
-  *length = len;
-
-  return true;
-  }
-#elif (defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__))
-  {
-  struct ioc_toc_header h;
-  struct ioc_read_toc_entry t;
-
-  if (ioctl (fd, CDIOREADTOCHEADER, &h) < 0)
-    BX_PANIC(("cdrom: read_toc: READTOCHDR failed."));
-
-  if ((start_track > h.ending_track) && (start_track != 0xaa))
-    return false;
-
-  buf[2] = h.starting_track;
-  buf[3] = h.ending_track;
-
-  if (start_track < h.starting_track)
-    start_track = h.starting_track;
-
-  int len = 4;
-  for (int i = start_track; i <= h.ending_track; i++) {
-    struct cd_toc_entry tocentry;
-    t.address_format = (msf) ? CD_MSF_FORMAT : CD_LBA_FORMAT;
-    t.starting_track = i;
-    t.data_len = sizeof(tocentry);
-    t.data = &tocentry;
-
-    if (ioctl (fd, CDIOREADTOCENTRYS, &t) < 0)
-      BX_PANIC(("cdrom: read_toc: READTOCENTRY failed."));
-
-    buf[len++] = 0; // Reserved
-    buf[len++] = (tocentry.addr_type << 4) | tocentry.control ; // ADR, control
-    buf[len++] = i; // Track number
-    buf[len++] = 0; // Reserved
-
-    // Start address
-    if (msf) {
-      buf[len++] = 0; // reserved
-      buf[len++] = tocentry.addr.msf.minute;
-      buf[len++] = tocentry.addr.msf.second;
-      buf[len++] = tocentry.addr.msf.frame;
-    } else {
-      buf[len++] = (((unsigned)tocentry.addr.lba) >> 24) & 0xff;
-      buf[len++] = (((unsigned)tocentry.addr.lba) >> 16) & 0xff;
-      buf[len++] = (((unsigned)tocentry.addr.lba) >> 8) & 0xff;
-      buf[len++] = (((unsigned)tocentry.addr.lba) >> 0) & 0xff;
-    }
-  }
-
-  // Lead out track
-  struct cd_toc_entry tocentry;
-  t.address_format = (msf) ? CD_MSF_FORMAT : CD_LBA_FORMAT;
-  t.starting_track = 0xaa;
-  t.data_len = sizeof(tocentry);
-  t.data = &tocentry;
-
-  if (ioctl (fd, CDIOREADTOCENTRYS, &t) < 0)
-    BX_PANIC(("cdrom: read_toc: READTOCENTRY lead-out failed."));
-
-  buf[len++] = 0; // Reserved
-  buf[len++] = (tocentry.addr_type << 4) | tocentry.control ; // ADR, control
-  buf[len++] = 0xaa; // Track number
-  buf[len++] = 0; // Reserved
-
-  // Start address
-  if (msf) {
-    buf[len++] = 0; // reserved
-    buf[len++] = tocentry.addr.msf.minute;
-    buf[len++] = tocentry.addr.msf.second;
-    buf[len++] = tocentry.addr.msf.frame;
-  } else {
-    buf[len++] = (((unsigned)tocentry.addr.lba) >> 24) & 0xff;
-    buf[len++] = (((unsigned)tocentry.addr.lba) >> 16) & 0xff;
-    buf[len++] = (((unsigned)tocentry.addr.lba) >> 8) & 0xff;
-    buf[len++] = (((unsigned)tocentry.addr.lba) >> 0) & 0xff;
-  }
-
-  buf[0] = ((len-2) >> 8) & 0xff;
-  buf[1] = (len-2) & 0xff;
-
-  *length = len;
-
-  return true;
-  }
-#elif defined(__APPLE__)
-  // Read CD TOC. Returns false if start track is out of bounds.
-
-#if 1
-  {
-  struct _CDTOC * toc = ReadTOC( CDDevicePath );
-  
-  if ((start_track > toc->last_session) && (start_track != 0xaa))
-    return false;
-
-  buf[2] = toc->first_session;
-  buf[3] = toc->last_session;
-
-  if (start_track < toc->first_session)
-    start_track = toc->first_session;
-
-  int len = 4;
-  for (int i = start_track; i <= toc->last_session; i++) {
-    buf[len++] = 0; // Reserved
-    buf[len++] = toc->trackdesc[i].ctrl_adr ; // ADR, control
-    buf[len++] = i; // Track number
-    buf[len++] = 0; // Reserved
-
-    // Start address
-    if (msf) {
-      buf[len++] = 0; // reserved
-      buf[len++] = toc->trackdesc[i].address.minute;
-      buf[len++] = toc->trackdesc[i].address.second;
-      buf[len++] = toc->trackdesc[i].address.frame;
-    } else {
-      unsigned lba = (unsigned)(MSF_TO_LBA(toc->trackdesc[i].address));
-      buf[len++] = (lba >> 24) & 0xff;
-      buf[len++] = (lba >> 16) & 0xff;
-      buf[len++] = (lba >> 8) & 0xff;
-      buf[len++] = (lba >> 0) & 0xff;
-    }
-  }
-
-  // Lead out track
-  buf[len++] = 0; // Reserved
-  buf[len++] = 0x16; // ADR, control
-  buf[len++] = 0xaa; // Track number
-  buf[len++] = 0; // Reserved
-
-  uint32 blocks = capacity();
-
-  // Start address
-  if (msf) {
-    buf[len++] = 0; // reserved
-    buf[len++] = (uint8)(((blocks + 150) / 75) / 60); // minute
-    buf[len++] = (uint8)(((blocks + 150) / 75) % 60); // second
-    buf[len++] = (uint8)((blocks + 150) % 75); // frame;
-  } else {
-    buf[len++] = (blocks >> 24) & 0xff;
-    buf[len++] = (blocks >> 16) & 0xff;
-    buf[len++] = (blocks >> 8) & 0xff;
-    buf[len++] = (blocks >> 0) & 0xff;
-  }
-
-  buf[0] = ((len-2) >> 8) & 0xff;
-  buf[1] = (len-2) & 0xff;
-
-  *length = len;
-
-  return true;
-//  BX_INFO(( "Read TOC - Not Implemented" ));
-//  return false;
-  }
-#else
-  BX_INFO(( "Read TOC - Not Implemented" ));
-  return false;
-#endif
-#else
-  BX_INFO(("read_toc: your OS is not supported yet."));
-  return(false); // OS not supported yet, return false always.
-#endif
-}
-
-
-  uint32
-cdrom_interface::capacity()
-{
-  // Return CD-ROM capacity.  I believe you want to return
-  // the number of blocks of capacity the actual media has.
-
-#if !defined WIN32
-  // win32 has its own way of doing this
-  if (using_file) {
-    // return length of the image file
-    struct stat stat_buf;
-    int ret = fstat (fd, &stat_buf);
-    if (ret) {
-       BX_PANIC (("fstat on cdrom image returned err: %s", strerror(errno)));
-    }
-    BX_INFO (("cdrom size is %lld bytes", stat_buf.st_size));
-    if ((stat_buf.st_size % 2048) != 0)  {
-      BX_ERROR (("expected cdrom image to be a multiple of 2048 bytes"));
-    }
-    return stat_buf.st_size / 2048;
-  }
-#endif
-
-#ifdef __BEOS__
-       return GetNumDeviceBlocks(fd, BX_CD_FRAMESIZE);
-#elif defined(__sun)
-  {
-    struct stat buf = {0};
-
-    if (fd < 0) {
-      BX_PANIC(("cdrom: capacity: file not open."));
-    } 
-    
-    if( fstat(fd, &buf) != 0 )
-      BX_PANIC(("cdrom: capacity: stat() failed."));
-  
-    return(buf.st_size);
-  }
-#elif (defined(__NetBSD__) || defined(__OpenBSD__))
-  {
-  // We just read the disklabel, imagine that...
-  struct disklabel lp;
-
-  if (fd < 0)
-    BX_PANIC(("cdrom: capacity: file not open."));
-
-  if (ioctl(fd, DIOCGDINFO, &lp) < 0)
-    BX_PANIC(("cdrom: ioctl(DIOCGDINFO) failed"));
-
-  BX_DEBUG(( "capacity: %u", lp.d_secperunit ));
-  return(lp.d_secperunit);
-  }
-#elif defined(__linux__)
-  {
-  // Read the TOC to get the data size, since BLKGETSIZE doesn't work on
-  // non-ATAPI drives.  This is based on Keith Jones code below.
-  // <splite@purdue.edu> 21 June 2001
-
-  int i, dtrk_lba, num_sectors;
-  int dtrk = 0;
-  struct cdrom_tochdr td;
-  struct cdrom_tocentry te;
-
-  if (fd < 0)
-    BX_PANIC(("cdrom: capacity: file not open."));
-
-  if (ioctl(fd, CDROMREADTOCHDR, &td) < 0)
-    BX_PANIC(("cdrom: ioctl(CDROMREADTOCHDR) failed"));
-
-  num_sectors = -1;
-  dtrk_lba = -1;
-
-  for (i = td.cdth_trk0; i <= td.cdth_trk1; i++) {
-    te.cdte_track = i;
-    te.cdte_format = CDROM_LBA;
-    if (ioctl(fd, CDROMREADTOCENTRY, &te) < 0)
-      BX_PANIC(("cdrom: ioctl(CDROMREADTOCENTRY) failed"));
-
-    if (dtrk_lba != -1) {
-      num_sectors = te.cdte_addr.lba - dtrk_lba;
-      break;
-    }
-    if (te.cdte_ctrl & CDROM_DATA_TRACK) {
-      dtrk = i;
-      dtrk_lba = te.cdte_addr.lba;
-    }
-  }
-
-  if (num_sectors < 0) {
-    if (dtrk_lba != -1) {
-      te.cdte_track = CDROM_LEADOUT;
-      te.cdte_format = CDROM_LBA;
-      if (ioctl(fd, CDROMREADTOCENTRY, &te) < 0)
-        BX_PANIC(("cdrom: ioctl(CDROMREADTOCENTRY) failed"));
-      num_sectors = te.cdte_addr.lba - dtrk_lba;
-    } else
-      BX_PANIC(("cdrom: no data track found"));
-  }
-
-  BX_INFO(("cdrom: Data track %d, length %d", dtrk, num_sectors));
-
-  return(num_sectors);
-
-  }
-#elif defined(__FreeBSD__)
-  {
-  // Read the TOC to get the size of the data track.
-  // Keith Jones <freebsd.dev@blueyonder.co.uk>, 16 January 2000
-
-#define MAX_TRACKS 100
-
-  int i, num_tracks, num_sectors;
-  struct ioc_toc_header td;
-  struct ioc_read_toc_entry rte;
-  struct cd_toc_entry toc_buffer[MAX_TRACKS + 1];
-
-  if (fd < 0)
-    BX_PANIC(("cdrom: capacity: file not open."));
-
-  if (ioctl(fd, CDIOREADTOCHEADER, &td) < 0)
-    BX_PANIC(("cdrom: ioctl(CDIOREADTOCHEADER) failed"));
-
-  num_tracks = (td.ending_track - td.starting_track) + 1;
-  if (num_tracks > MAX_TRACKS)
-    BX_PANIC(("cdrom: TOC is too large"));
-
-  rte.address_format = CD_LBA_FORMAT;
-  rte.starting_track = td.starting_track;
-  rte.data_len = (num_tracks + 1) * sizeof(struct cd_toc_entry);
-  rte.data = toc_buffer;
-  if (ioctl(fd, CDIOREADTOCENTRYS, &rte) < 0)
-    BX_PANIC(("cdrom: ioctl(CDIOREADTOCENTRYS) failed"));
-
-  num_sectors = -1;
-  for (i = 0; i < num_tracks; i++) {
-    if (rte.data[i].control & 4) {     /* data track */
-      num_sectors = ntohl(rte.data[i + 1].addr.lba)
-          - ntohl(rte.data[i].addr.lba);
-      BX_INFO(( "cdrom: Data track %d, length %d",
-        rte.data[i].track, num_sectors));
-      break;
-      }
-    }
-
-  if (num_sectors < 0)
-    BX_PANIC(("cdrom: no data track found"));
-
-  return(num_sectors);
-
-  }
-#elif defined WIN32
-  {
-         if(bUseASPI) {
-                 return (GetCDCapacity(hid, tid, lun) / 2352);
-         } else if(using_file) {
-           ULARGE_INTEGER FileSize;
-           FileSize.LowPart = GetFileSize(hFile, &FileSize.HighPart);
-               return (FileSize.QuadPart / 2048);
-         } else {  /* direct device access */
-           DWORD SectorsPerCluster;
-           DWORD TotalNumOfClusters;
-           GetDiskFreeSpace( path, &SectorsPerCluster, NULL, NULL, &TotalNumOfClusters);
-               return (TotalNumOfClusters * SectorsPerCluster);
-         }
-  }
-#elif defined __APPLE__
-// Find the size of the first data track on the cd.  This has produced
-// the same results as the linux version on every cd I have tried, about
-// 5.  The differences here seem to be that the entries in the TOC when
-// retrieved from the IOKit interface appear in a reversed order when
-// compared with the linux READTOCENTRY ioctl.
-  {
-  // Return CD-ROM capacity.  I believe you want to return
-  // the number of bytes of capacity the actual media has.
-
-  BX_INFO(( "Capacity" ));
-
-  struct _CDTOC * toc = ReadTOC( CDDevicePath );
-
-  if ( toc == NULL ) {
-    BX_PANIC(( "capacity: Failed to read toc" ));
-  }
-
-  size_t toc_entries = ( toc->length - 2 ) / sizeof( struct _CDTOC_Desc );
-  
-  BX_DEBUG(( "reading %d toc entries\n", toc_entries ));
-
-  int start_sector = -1;
-  int data_track = -1;
-
-  // Iterate through the list backward. Pick the first data track and
-  // get the address of the immediately previous (or following depending
-  // on how you look at it).  The difference in the sector numbers
-  // is returned as the sized of the data track.
-  for ( int i=toc_entries - 1; i>=0; i-- ) {
-
-    BX_DEBUG(( "session %d ctl_adr %d tno %d point %d lba %d z %d p lba %d\n",
-             (int)toc->trackdesc[i].session,
-             (int)toc->trackdesc[i].ctrl_adr,
-             (int)toc->trackdesc[i].tno,
-             (int)toc->trackdesc[i].point,
-             MSF_TO_LBA( toc->trackdesc[i].address ),
-             (int)toc->trackdesc[i].zero,
-             MSF_TO_LBA(toc->trackdesc[i].p )));
-
-    if ( start_sector != -1 ) {
-
-      start_sector = MSF_TO_LBA(toc->trackdesc[i].p) - start_sector;
-      break;
-
-    }
-
-    if (( toc->trackdesc[i].ctrl_adr >> 4) != 1 ) continue;
-
-    if ( toc->trackdesc[i].ctrl_adr & 0x04 ) {
-
-      data_track = toc->trackdesc[i].point;
-
-      start_sector = MSF_TO_LBA(toc->trackdesc[i].p);
-
-    }
-      
-  }  
-
-  free( toc );
-
-  if ( start_sector == -1 ) {
-    start_sector = 0;
-  }
-
-  BX_INFO(("first data track %d data size is %d", data_track, start_sector));
-
-  return start_sector;
-  }
-#else
-  BX_ERROR(( "capacity: your OS is not supported yet." ));
-  return(0);
-#endif
-}
-
-  void BX_CPP_AttrRegparmN(2)
-cdrom_interface::read_block(uint8* buf, int lba)
-{
-  // Read a single block from the CD
-
-#ifdef WIN32
-  LARGE_INTEGER pos;
-#else
-  off_t pos;
-#endif
-  ssize_t n;
-
-#ifdef WIN32
-  if(bUseASPI) {
-         ReadCDSector(hid, tid, lun, lba, buf, BX_CD_FRAMESIZE);
-         n = BX_CD_FRAMESIZE;
-  } else {
-    pos.QuadPart = (LONGLONG)lba*BX_CD_FRAMESIZE;
-    pos.LowPart = SetFilePointer(hFile, pos.LowPart, &pos.HighPart, SEEK_SET);
-    if ((pos.LowPart == 0xffffffff) && (GetLastError() != NO_ERROR)) {
-      BX_PANIC(("cdrom: read_block: SetFilePointer returned error."));
-       }
-       ReadFile(hFile, (void *) buf, BX_CD_FRAMESIZE, (unsigned long *) &n, NULL);
-  }
-#elif defined(__APPLE__)
-#define CD_SEEK_DISTANCE kCDSectorSizeWhole
-  if(using_file)
-  {
-    pos = lseek(fd, lba*BX_CD_FRAMESIZE, SEEK_SET);
-    if (pos < 0) {
-      BX_PANIC(("cdrom: read_block: lseek returned error."));
-  }
-  n = read(fd, buf, BX_CD_FRAMESIZE);
-  }
-  else
-  {
-    // This seek will leave us 16 bytes from the start of the data
-    // hence the magic number. 
-    pos = lseek(fd, lba*CD_SEEK_DISTANCE + 16, SEEK_SET);
-    if (pos < 0) {
-      BX_PANIC(("cdrom: read_block: lseek returned error."));
-    }
-    n = read(fd, buf, CD_FRAMESIZE);
-  }
-#else
-  pos = lseek(fd, lba*BX_CD_FRAMESIZE, SEEK_SET);
-  if (pos < 0) {
-    BX_PANIC(("cdrom: read_block: lseek returned error."));
-  }
-  n = read(fd, (char*) buf, BX_CD_FRAMESIZE);
-#endif
-
-  if (n != BX_CD_FRAMESIZE) {
-    BX_PANIC(("cdrom: read_block: read returned %d",
-      (int) n));
-    }
-}
-
-#endif /* if BX_SUPPORT_CDROM */
diff --git a/tools/ioemu/iodev/cdrom.h b/tools/ioemu/iodev/cdrom.h
deleted file mode 100644 (file)
index 29fdfaf..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: cdrom.h,v 1.13 2003/08/19 00:37:03 cbothamy Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-// Header file for low-level OS specific CDROM emulation
-
-
-class cdrom_interface : public logfunctions {
-public:
-  cdrom_interface(char *dev);
-  ~cdrom_interface(void);
-  void init(void);
-
-  // Load CD-ROM. Returns false if CD is not ready.
-  bx_bool insert_cdrom(char *dev = NULL);
-
-  // Logically eject the CD.
-  void eject_cdrom();
-
-  // Read CD TOC. Returns false if start track is out of bounds.
-  bx_bool read_toc(uint8* buf, int* length, bx_bool msf, int start_track);
-
-  // Return CD-ROM capacity (in 2048 byte frames)
-  uint32 capacity();
-
-  // Read a single block from the CD
-  void read_block(uint8* buf, int lba) BX_CPP_AttrRegparmN(2);
-
-  // Start (spin up) the CD.
-  int start_cdrom();
-
-private:
-  int fd;
-  char *path;
-
-  int using_file;
-#ifdef WIN32
-  HANDLE hFile;
-  int hid;
-  int tid;
-  int lun;
-#endif
-  };
-
diff --git a/tools/ioemu/iodev/cdrom_beos.h b/tools/ioemu/iodev/cdrom_beos.h
deleted file mode 100644 (file)
index 8a22d5c..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef CDROM_BEOS_H
-#define CDROM_BEOS_H
-
-#include <stddef.h> //for off_t
-
-off_t GetNumDeviceBlocks(int fd, int block_size);
-int GetLogicalBlockSize(int fd);
-int GetDeviceBlockSize(int fd);
-
-#endif
diff --git a/tools/ioemu/iodev/cmos.cc b/tools/ioemu/iodev/cmos.cc
deleted file mode 100644 (file)
index fbf3144..0000000
+++ /dev/null
@@ -1,824 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: cmos.cc,v 1.44 2003/12/27 13:43:41 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-
-
-
-// Define BX_PLUGGABLE in files that can be compiled into plugins.  For
-// platforms that require a special tag on exported symbols, BX_PLUGGABLE 
-// is used to know when we are exporting symbols and when we are importing.
-#define BX_PLUGGABLE
-
-#include "bochs.h"
-
-#define LOG_THIS theCmosDevice->
-
-bx_cmos_c *theCmosDevice = NULL;
-
-// CMOS register definitions from Ralf Brown's interrupt list v6.1, in a file
-// called cmos.lst.  In cases where there are multiple uses for a given
-// register in the interrupt list, I only listed the purpose that Bochs
-// actually uses it for, but I wrote "alternatives" next to it.
-#define  REG_SEC                     0x00
-#define  REG_SEC_ALARM               0x01
-#define  REG_MIN                     0x02
-#define  REG_MIN_ALARM               0x03
-#define  REG_HOUR                    0x04
-#define  REG_HOUR_ALARM              0x05
-#define  REG_WEEK_DAY                0x06
-#define  REG_MONTH_DAY               0x07
-#define  REG_MONTH                   0x08
-#define  REG_YEAR                    0x09
-#define  REG_STAT_A                  0x0a
-#define  REG_STAT_B                  0x0b
-#define  REG_STAT_C                  0x0c
-#define  REG_STAT_D                  0x0d
-#define  REG_DIAGNOSTIC_STATUS       0x0e  /* alternatives */
-#define  REG_SHUTDOWN_STATUS         0x0f
-#define  REG_EQUIPMENT_BYTE          0x14
-#define  REG_CSUM_HIGH               0x2e
-#define  REG_CSUM_LOW                0x2f
-#define  REG_IBM_CENTURY_BYTE        0x32  /* alternatives */
-#define  REG_IBM_PS2_CENTURY_BYTE    0x37  /* alternatives */
-
-// Bochs CMOS map (to be completed)
-//
-// Idx  Len   Description
-// 0x15   2   Base memory in 1k
-// 0x17   2   Memory size above 1M in 1k
-// 0x30   2   Memory size above 1M in 1k
-// 0x34   2   Memory size above 16M in 64k
-//
-
-// check that BX_NUM_CMOS_REGS is 64 or 128
-#if (BX_NUM_CMOS_REGS == 64)
-#elif (BX_NUM_CMOS_REGS == 128)
-#else
-#error "Invalid BX_NUM_CMOS_REGS value in config.h"
-#endif
-
-
-  int
-libcmos_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
-{
-  theCmosDevice = new bx_cmos_c ();
-  bx_devices.pluginCmosDevice = theCmosDevice;
-  BX_REGISTER_DEVICE_DEVMODEL(plugin, type, theCmosDevice, BX_PLUGIN_CMOS);
-  return(0); // Success
-}
-
-  void
-libcmos_LTX_plugin_fini(void)
-{
-}
-
-bx_cmos_c::bx_cmos_c(void)
-{
-  put("CMOS");
-  settype(CMOSLOG);
-
-  unsigned i;
-  for (i=0; i<BX_NUM_CMOS_REGS; i++)
-    s.reg[i] = 0;
-  s.periodic_timer_index = BX_NULL_TIMER_HANDLE;
-  s.one_second_timer_index = BX_NULL_TIMER_HANDLE;
-  s.uip_timer_index = BX_NULL_TIMER_HANDLE;
-}
-
-bx_cmos_c::~bx_cmos_c(void)
-{
-  BX_DEBUG(("Exit."));
-}
-
-
-  void
-bx_cmos_c::init(void)
-{
-  BX_DEBUG(("Init $Id: cmos.cc,v 1.44 2003/12/27 13:43:41 vruppert Exp $"));
-  // CMOS RAM & RTC
-
-  DEV_register_ioread_handler(this, read_handler, 0x0070, "CMOS RAM", 1);
-  DEV_register_ioread_handler(this, read_handler, 0x0071, "CMOS RAM", 1);
-  DEV_register_iowrite_handler(this, write_handler, 0x0070, "CMOS RAM", 1);
-  DEV_register_iowrite_handler(this, write_handler, 0x0071, "CMOS RAM", 1);
-  DEV_register_irq(8, "CMOS RTC"); 
-  if (BX_CMOS_THIS s.periodic_timer_index == BX_NULL_TIMER_HANDLE) {
-    BX_CMOS_THIS s.periodic_timer_index =
-      DEV_register_timer(this, periodic_timer_handler,
-        1000000, 1,0, "cmos"); // continuous, not-active
-  }
-  if (BX_CMOS_THIS s.one_second_timer_index == BX_NULL_TIMER_HANDLE) {
-    BX_CMOS_THIS s.one_second_timer_index =
-      DEV_register_timer(this, one_second_timer_handler,
-        1000000, 1,0, "cmos"); // continuous, not-active
-  }
-  if (BX_CMOS_THIS s.uip_timer_index == BX_NULL_TIMER_HANDLE) {
-    BX_CMOS_THIS s.uip_timer_index =
-      DEV_register_timer(this, uip_timer_handler,
-        244, 0, 0, "cmos"); // one-shot, not-active
-  }
-
-#if BX_USE_SPECIFIED_TIME0 != 0
-  // ??? this will not be correct for using an image file.
-  // perhaps take values in CMOS and work backwards to find
-  // s.timeval from values read in.
-  BX_CMOS_THIS s.timeval = BX_USE_SPECIFIED_TIME0;
-
-#else // BX_USE_SPECIFIED_TIME0 != 0
-
-  // localtime
-  if (bx_options.clock.Otime0->get () == BX_CLOCK_TIME0_LOCAL) {
-       BX_INFO(("Using local time for initial clock"));
-       BX_CMOS_THIS s.timeval = time(NULL);
-  }
-  // utc
-  else if (bx_options.clock.Otime0->get () == BX_CLOCK_TIME0_UTC) {
-       bx_bool utc_ok = 0;
-
-       BX_INFO(("Using utc time for initial clock"));
-       
-       BX_CMOS_THIS s.timeval = time(NULL);
-
-#if BX_HAVE_GMTIME
-#if BX_HAVE_MKTIME
-       struct tm *utc_holder = gmtime(&BX_CMOS_THIS s.timeval);
-       utc_holder->tm_isdst = -1;
-       utc_ok = 1;
-       BX_CMOS_THIS s.timeval = mktime(utc_holder);
-#elif BX_HAVE_TIMELOCAL
-       struct tm *utc_holder = gmtime(&BX_CMOS_THIS s.timeval);
-       utc_holder->tm_isdst = 0;       // XXX Is this correct???
-       utc_ok = 1;
-       BX_CMOS_THIS s.timeval = timelocal(utc_holder);
-#endif //BX_HAVE_MKTIME
-#endif //BX_HAVE_GMTIME
-
-       if (!utc_ok) {
-           BX_ERROR(("UTC time is not supported on your platform. Using current time(NULL)"));
-       }
-  }
-  else {
-       BX_INFO(("Using specified time for initial clock"));
-       BX_CMOS_THIS s.timeval = bx_options.clock.Otime0->get ();
-  }
-#endif // BX_USE_SPECIFIED_TIME0 != 0
-
-  char *tmptime;
-  while( (tmptime =  strdup(ctime(&(BX_CMOS_THIS s.timeval)))) == NULL) {
-    BX_PANIC(("Out of memory."));
-  }
-  tmptime[strlen(tmptime)-1]='\0';
-
-  BX_INFO(("Setting initial clock to: %s (time0=%u)", tmptime, (Bit32u)BX_CMOS_THIS s.timeval));
-
-  update_clock();
-  BX_CMOS_THIS s.timeval_change = 0;
-
-  // load CMOS from image file if requested.
-  if (bx_options.cmos.OcmosImage->get ()) {
-    // CMOS image file requested
-    int fd, ret;
-    struct stat stat_buf;
-
-    fd = open(bx_options.cmos.Opath->getptr (), O_RDONLY
-#ifdef O_BINARY
-       | O_BINARY
-#endif
-        );
-    if (fd < 0) {
-      BX_PANIC(("trying to open cmos image file '%s'",
-     bx_options.cmos.Opath->getptr ()));
-      }
-    ret = fstat(fd, &stat_buf);
-    if (ret) {
-      BX_PANIC(("CMOS: could not fstat() image file."));
-      }
-    if (stat_buf.st_size != BX_NUM_CMOS_REGS) {
-      BX_PANIC(("CMOS: image file not same size as BX_NUM_CMOS_REGS."));
-      }
-
-    ret = ::read(fd, (bx_ptr_t) BX_CMOS_THIS s.reg, BX_NUM_CMOS_REGS);
-    if (ret != BX_NUM_CMOS_REGS) {
-      BX_PANIC(("CMOS: error reading cmos file."));
-      }
-    close(fd);
-    BX_INFO(("successfuly read from image file '%s'.",
-      bx_options.cmos.Opath->getptr ()));
-    }
-  else {
-    // CMOS values generated
-    BX_CMOS_THIS s.reg[REG_STAT_A] = 0x26;
-    BX_CMOS_THIS s.reg[REG_STAT_B] = 0x02;
-    BX_CMOS_THIS s.reg[REG_STAT_C] = 0x00;
-    BX_CMOS_THIS s.reg[REG_STAT_D] = 0x80;
-#if BX_SUPPORT_FPU == 1
-    BX_CMOS_THIS s.reg[REG_EQUIPMENT_BYTE] |= 0x02;
-#endif
-    }
-}
-
-  void
-bx_cmos_c::reset(unsigned type)
-{
-  BX_CMOS_THIS s.cmos_mem_address = 0;
-
-  // RESET affects the following registers:
-  //  CRA: no effects
-  //  CRB: bits 4,5,6 forced to 0
-  //  CRC: bits 4,5,6,7 forced to 0
-  //  CRD: no effects
-  BX_CMOS_THIS s.reg[REG_STAT_B] &= 0x8f;
-  BX_CMOS_THIS s.reg[REG_STAT_C] = 0;
-
-  // One second timer for updating clock & alarm functions
-  bx_pc_system.activate_timer(BX_CMOS_THIS s.one_second_timer_index,
-                         1000000, 1);
-
-  // handle periodic interrupt rate select
-  BX_CMOS_THIS CRA_change();
-}
-
-  void
-bx_cmos_c::CRA_change(void)
-{
-  unsigned nibble;
-
-  // Periodic Interrupt timer
-  nibble = BX_CMOS_THIS s.reg[REG_STAT_A] & 0x0f;
-  if (nibble == 0) {
-    // No Periodic Interrupt Rate when 0, deactivate timer
-    bx_pc_system.deactivate_timer(BX_CMOS_THIS s.periodic_timer_index);
-    BX_CMOS_THIS s.periodic_interval_usec = (Bit32u) -1; // max value
-    }
-  else {
-    // values 0001b and 0010b are the same as 1000b and 1001b
-    if (nibble <= 2)
-      nibble += 7;
-    BX_CMOS_THIS s.periodic_interval_usec = (unsigned) (1000000.0L /
-     (32768.0L / (1 << (nibble - 1))));
-
-    // if Periodic Interrupt Enable bit set, activate timer
-    if ( BX_CMOS_THIS s.reg[REG_STAT_B] & 0x40 )
-      bx_pc_system.activate_timer(BX_CMOS_THIS s.periodic_timer_index,
-     BX_CMOS_THIS s.periodic_interval_usec, 1);
-    else
-      bx_pc_system.deactivate_timer(BX_CMOS_THIS s.periodic_timer_index);
-    }
-}
-
-
-  // static IO port read callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-  Bit32u
-bx_cmos_c::read_handler(void *this_ptr, Bit32u address, unsigned io_len)
-{
-#if !BX_USE_CMOS_SMF
-  bx_cmos_c *class_ptr = (bx_cmos_c *) this_ptr;
-
-  return( class_ptr->read(address, io_len) );
-}
-
-  Bit32u
-bx_cmos_c::read(Bit32u address, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif
-  Bit8u ret8;
-
-  if (bx_dbg.cmos)
-    BX_INFO(("CMOS read of CMOS register 0x%02x",
-      (unsigned) BX_CMOS_THIS s.cmos_mem_address));
-
-
-  switch (address) {
-    case 0x0070:
-      BX_INFO(("read of index port 0x70. returning 0xff"));
-      // Volker says his boxes return 0xff
-      //ret8 = BX_CMOS_THIS s.cmos_mem_address;
-      return(0xff);
-      break;
-    case 0x0071:
-      if (BX_CMOS_THIS s.cmos_mem_address >= BX_NUM_CMOS_REGS) {
-     BX_PANIC(("unsupported cmos io read, register(0x%02x)!",
-       (unsigned) BX_CMOS_THIS s.cmos_mem_address));
-     }
-
-      ret8 = BX_CMOS_THIS s.reg[BX_CMOS_THIS s.cmos_mem_address];
-      // all bits of Register C are cleared after a read occurs.
-      if (BX_CMOS_THIS s.cmos_mem_address == REG_STAT_C) {
-        BX_CMOS_THIS s.reg[REG_STAT_C] = 0x00;
-        DEV_pic_lower_irq(8);
-        }
-      return(ret8);
-      break;
-
-    default:
-      BX_PANIC(("unsupported cmos read, address=0x%04x!",
-     (unsigned) address));
-      return(0);
-      break;
-    }
-}
-
-
-  // static IO port write callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-  void
-bx_cmos_c::write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len)
-{
-#if !BX_USE_CMOS_SMF
-  bx_cmos_c *class_ptr = (bx_cmos_c *) this_ptr;
-
-  class_ptr->write(address, value, io_len);
-}
-
-  void
-bx_cmos_c::write(Bit32u address, Bit32u value, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif  // !BX_USE_CMOS_SMF
-
-  if (bx_dbg.cmos)
-    BX_INFO(("CMOS write to address: 0x%04x = 0x%02x",
-      (unsigned) address, (unsigned) value));
-
-
-  switch (address) {
-    case 0x0070:
-#if (BX_NUM_CMOS_REGS == 64)
-      BX_CMOS_THIS s.cmos_mem_address = value & 0x3F;
-#else
-      BX_CMOS_THIS s.cmos_mem_address = value & 0x7F;
-#endif
-      break;
-
-    case 0x0071:
-      if (BX_CMOS_THIS s.cmos_mem_address >= BX_NUM_CMOS_REGS) {
-     BX_PANIC(("unsupported cmos io write, register(0x%02x) = 0x%02x !",
-       (unsigned) BX_CMOS_THIS s.cmos_mem_address, (unsigned) value));
-     return;
-     }
-      switch (BX_CMOS_THIS s.cmos_mem_address) {
-     case REG_SEC_ALARM:             // seconds alarm
-     case REG_MIN_ALARM:             // minutes alarm
-     case REG_HOUR_ALARM:            // hours alarm
-       BX_CMOS_THIS s.reg[BX_CMOS_THIS s.cmos_mem_address] = value;
-       BX_DEBUG(("alarm time changed to %02x:%02x:%02x", BX_CMOS_THIS s.reg[REG_HOUR_ALARM],
-                 BX_CMOS_THIS s.reg[REG_MIN_ALARM], BX_CMOS_THIS s.reg[REG_SEC_ALARM]));
-       return;
-       break;
-
-     case REG_SEC:                   // seconds
-     case REG_MIN:                   // minutes
-     case REG_HOUR:                  // hours
-     case REG_WEEK_DAY:              // day of the week
-     case REG_MONTH_DAY:             // day of the month
-     case REG_MONTH:                 // month
-     case REG_YEAR:                  // year
-     case REG_IBM_CENTURY_BYTE:      // century
-     case REG_IBM_PS2_CENTURY_BYTE:  // century (PS/2)
-       //BX_INFO(("write reg 0x%02x: value = 0x%02x",
-       //    (unsigned) BX_CMOS_THIS s.cmos_mem_address, (unsigned) value);
-       BX_CMOS_THIS s.reg[BX_CMOS_THIS s.cmos_mem_address] = value;
-       if (BX_CMOS_THIS s.cmos_mem_address == REG_IBM_PS2_CENTURY_BYTE) {
-         BX_CMOS_THIS s.reg[REG_IBM_CENTURY_BYTE] = value;
-       }
-       if (BX_CMOS_THIS s.reg[REG_STAT_B] & 0x80) {
-         BX_CMOS_THIS s.timeval_change = 1;
-       } else {
-         update_timeval();
-       }
-       return;
-       break;
-
-     case REG_STAT_A: // Control Register A
-       // bit 7: Update in Progress (read-only)
-       //   1 = signifies time registers will be updated within 244us
-       //   0 = time registers will not occur before 244us
-       //   note: this bit reads 0 when CRB bit 7 is 1
-       // bit 6..4: Divider Chain Control
-       //   000 oscillator disabled
-       //   001 oscillator disabled
-       //   010 Normal operation
-       //   011 TEST
-       //   100 TEST
-       //   101 TEST
-       //   110 Divider Chain RESET
-       //   111 Divider Chain RESET
-       // bit 3..0: Periodic Interrupt Rate Select
-       //   0000 None
-       //   0001 3.90625  ms
-       //   0010 7.8125   ms
-       //   0011 122.070  us
-       //   0100 244.141  us
-       //   0101 488.281  us
-       //   0110 976.562  us
-       //   0111 1.953125 ms
-       //   1000 3.90625  ms
-       //   1001 7.8125   ms
-       //   1010 15.625   ms
-       //   1011 31.25    ms
-       //   1100 62.5     ms
-       //   1101 125      ms
-       //   1110 250      ms
-       //   1111 500      ms
-
-       unsigned dcc;
-       dcc = (value >> 4) & 0x07;
-       if ((dcc & 0x06) == 0x06) {
-         BX_INFO(("CRA: divider chain RESET"));
-       } else if (dcc != 0x02) {
-         BX_PANIC(("CRA: divider chain control 0x%02x", dcc));
-       }
-       BX_CMOS_THIS s.reg[REG_STAT_A] &= 0x80;
-       BX_CMOS_THIS s.reg[REG_STAT_A] |= (value & 0x7f);
-       BX_CMOS_THIS CRA_change();
-       return;
-       break;
-
-     case REG_STAT_B: // Control Register B
-       // bit 0: Daylight Savings Enable
-       //   1 = enable daylight savings
-       //   0 = disable daylight savings
-       // bit 1: 24/12 houre mode
-       //   1 = 24 hour format
-       //   0 = 12 hour format
-       // bit 2: Data Mode
-       //   1 = binary format
-       //   0 = BCD format
-       // bit 3: "square wave enable"
-       //   Not supported and always read as 0
-       // bit 4: Update Ended Interrupt Enable
-       //   1 = enable generation of update ended interrupt
-       //   0 = disable
-       // bit 5: Alarm Interrupt Enable
-       //   1 = enable generation of alarm interrupt
-       //   0 = disable
-       // bit 6: Periodic Interrupt Enable
-       //   1 = enable generation of periodic interrupt
-       //   0 = disable
-       // bit 7: Set mode
-       //   1 = user copy of time is "frozen" allowing time registers
-       //       to be accessed without regard for an occurance of an update
-       //   0 = time updates occur normally
-
-       // can not handle binary or 12-hour mode yet.
-       if (value & 0x04)
-       BX_PANIC(("write status reg B, binary format enabled."));
-       if ( !(value & 0x02) )
-       BX_PANIC(("write status reg B, 12 hour mode enabled."));
-
-       value &= 0xf7; // bit3 always 0
-       // Note: setting bit 7 clears bit 4
-       if (value & 0x80)
-       value &= 0xef;
-
-       unsigned prev_CRB;
-       prev_CRB = BX_CMOS_THIS s.reg[REG_STAT_B];
-       BX_CMOS_THIS s.reg[REG_STAT_B] = value;
-       if ( (prev_CRB & 0x40) != (value & 0x40) ) {
-       // Periodic Interrupt Enabled changed
-       if (prev_CRB & 0x40) {
-         // transition from 1 to 0, deactivate timer
-         bx_pc_system.deactivate_timer(
-           BX_CMOS_THIS s.periodic_timer_index);
-         }
-       else {
-         // transition from 0 to 1
-         // if rate select is not 0, activate timer
-         if ( (BX_CMOS_THIS s.reg[REG_STAT_A] & 0x0f) != 0 ) {
-           bx_pc_system.activate_timer(
-             BX_CMOS_THIS s.periodic_timer_index,
-             BX_CMOS_THIS s.periodic_interval_usec, 1);
-           }
-         }
-       }
-       if ( (prev_CRB >= 0x80) && (value < 0x80) && BX_CMOS_THIS s.timeval_change) {
-         update_timeval();
-         BX_CMOS_THIS s.timeval_change = 0;
-       }
-       return;
-       break;
-
-     case REG_STAT_C: // Control Register C
-     case REG_STAT_D: // Control Register D
-       BX_ERROR(("write to control register 0x%02x (read-only)",
-              BX_CMOS_THIS s.cmos_mem_address));
-       break;
-
-     case REG_DIAGNOSTIC_STATUS:
-       BX_DEBUG(("write register 0x0e: 0x%02x", (unsigned) value));
-       break;
-
-     case REG_SHUTDOWN_STATUS:
-       switch (value) {
-       case 0x00: /* proceed with normal POST (soft reset) */
-         BX_DEBUG(("Reg 0Fh(00): shutdown action = normal POST"));
-         break;
-       case 0x01: /* shutdown after memory size check */
-         BX_DEBUG(("Reg 0Fh(01): request to change shutdown action"
-                        " to shutdown after memory size check"));
-       case 0x02: /* shutdown after successful memory test */
-         BX_DEBUG(("Reg 0Fh(02): request to change shutdown action"
-                        " to shutdown after successful memory test"));
-         break;
-       case 0x03: /* shutdown after failed memory test */
-         BX_DEBUG(("Reg 0Fh(03): request to change shutdown action"
-                        " to shutdown after successful memory test"));
-         break;
-       case 0x04: /* jump to disk bootstrap routine */
-         BX_DEBUG(("Reg 0Fh(04): request to change shutdown action "
-                        "to jump to disk bootstrap routine."));
-         break;
-       case 0x05: /* flush keyboard (issue EOI) and jump via 40h:0067h */
-         BX_DEBUG(("Reg 0Fh(05): request to change shutdown action "
-                        "to flush keyboard (issue EOI) and jump via 40h:0067h."));
-         break;
-       case 0x06:
-         BX_DEBUG(("Reg 0Fh(06): Shutdown after memory test !"));
-         break;
-       case 0x07: /* reset (after failed test in virtual mode) */
-         BX_DEBUG(("Reg 0Fh(07): request to change shutdown action "
-                        "to reset (after failed test in virtual mode)."));
-         break;
-       case 0x08: /* used by POST during protected-mode RAM test (return to POST) */
-         BX_DEBUG(("Reg 0Fh(08): request to change shutdown action "
-                        "to return to POST (used by POST during protected-mode RAM test)."));
-         break;
-       case 0x09: /* return to BIOS extended memory block move
-                  (interrupt 15h, func 87h was in progress) */
-         BX_DEBUG(("Reg 0Fh(09): request to change shutdown action "
-                        "to return to BIOS extended memory block move."));
-         break;
-       case 0x0a: /* jump to DWORD pointer at 40:67 */
-         BX_DEBUG(("Reg 0Fh(0a): request to change shutdown action"
-                        " to jump to DWORD at 40:67"));
-         break;
-       case 0x0b: /* iret to DWORD pointer at 40:67 */
-         BX_DEBUG(("Reg 0Fh(0b): request to change shutdown action"
-                        " to iret to DWORD at 40:67"));
-         break;
-       case 0x0c: /* retf to DWORD pointer at 40:67 */
-         BX_DEBUG(("Reg 0Fh(0c): request to change shutdown action"
-                        " to retf to DWORD at 40:67"));
-         break;
-       default:
-         BX_PANIC(("unsupported cmos io write to reg F, case 0x%02x!",
-           (unsigned) value));
-         break;
-       }
-       break;
-
-     default:
-       BX_DEBUG(("write reg 0x%02x: value = 0x%02x",
-       (unsigned) BX_CMOS_THIS s.cmos_mem_address, (unsigned) value));
-       break;
-     }
-
-      BX_CMOS_THIS s.reg[BX_CMOS_THIS s.cmos_mem_address] = value;
-      break;
-    }
-}
-
-
-  void
-bx_cmos_c::checksum_cmos(void)
-{
-  unsigned i;
-  Bit16u sum;
-
-  sum = 0;
-  for (i=0x10; i<=0x2d; i++) {
-    sum += BX_CMOS_THIS s.reg[i];
-    }
-  BX_CMOS_THIS s.reg[REG_CSUM_HIGH] = (sum >> 8) & 0xff; /* checksum high */
-  BX_CMOS_THIS s.reg[REG_CSUM_LOW] = (sum & 0xff);      /* checksum low */
-}
-
-  void
-bx_cmos_c::periodic_timer_handler(void *this_ptr)
-{
-  bx_cmos_c *class_ptr = (bx_cmos_c *) this_ptr;
-
-  class_ptr->periodic_timer();
-}
-
-  void
-bx_cmos_c::periodic_timer()
-{
-  // if periodic interrupts are enabled, trip IRQ 8, and
-  // update status register C
-  if (BX_CMOS_THIS s.reg[REG_STAT_B] & 0x40) {
-    BX_CMOS_THIS s.reg[REG_STAT_C] |= 0xc0; // Interrupt Request, Periodic Int
-    DEV_pic_raise_irq(8);
-    }
-}
-
-  void
-bx_cmos_c::one_second_timer_handler(void *this_ptr)
-{
-  bx_cmos_c *class_ptr = (bx_cmos_c *) this_ptr;
-
-  class_ptr->one_second_timer();
-}
-
-  void
-bx_cmos_c::one_second_timer()
-{
-  // divider chain reset - RTC stopped
-  if ((BX_CMOS_THIS s.reg[REG_STAT_A] & 0x60) == 0x60)
-    return;
-
-  // update internal time/date buffer
-  BX_CMOS_THIS s.timeval++;
-
-  // Dont update CMOS user copy of time/date if CRB bit7 is 1
-  // Nothing else do to
-  if (BX_CMOS_THIS s.reg[REG_STAT_B] & 0x80)
-    return;
-
-  BX_CMOS_THIS s.reg[REG_STAT_A] |= 0x80; // set UIP bit
-
-  // UIP timer for updating clock & alarm functions
-  bx_pc_system.activate_timer(BX_CMOS_THIS s.uip_timer_index,
-                         244, 0);
-}
-
-  void
-bx_cmos_c::uip_timer_handler(void *this_ptr)
-{
-  bx_cmos_c *class_ptr = (bx_cmos_c *) this_ptr;
-
-  class_ptr->uip_timer();
-}
-
-  void
-bx_cmos_c::uip_timer()
-{
-  update_clock();
-
-  // if update interrupts are enabled, trip IRQ 8, and
-  // update status register C
-  if (BX_CMOS_THIS s.reg[REG_STAT_B] & 0x10) {
-    BX_CMOS_THIS s.reg[REG_STAT_C] |= 0x90; // Interrupt Request, Update Ended
-    DEV_pic_raise_irq(8);
-    }
-
-  // compare CMOS user copy of time/date to alarm time/date here
-  if (BX_CMOS_THIS s.reg[REG_STAT_B] & 0x20) {
-    // Alarm interrupts enabled
-    bx_bool alarm_match = 1;
-    if ( (BX_CMOS_THIS s.reg[REG_SEC_ALARM] & 0xc0) != 0xc0 ) {
-      // seconds alarm not in dont care mode
-      if (BX_CMOS_THIS s.reg[REG_SEC] != BX_CMOS_THIS s.reg[REG_SEC_ALARM])
-     alarm_match = 0;
-      }
-    if ( (BX_CMOS_THIS s.reg[REG_MIN_ALARM] & 0xc0) != 0xc0 ) {
-      // minutes alarm not in dont care mode
-      if (BX_CMOS_THIS s.reg[REG_MIN] != BX_CMOS_THIS s.reg[REG_MIN_ALARM])
-     alarm_match = 0;
-      }
-    if ( (BX_CMOS_THIS s.reg[REG_HOUR_ALARM] & 0xc0) != 0xc0 ) {
-      // hours alarm not in dont care mode
-      if (BX_CMOS_THIS s.reg[REG_HOUR] != BX_CMOS_THIS s.reg[REG_HOUR_ALARM])
-     alarm_match = 0;
-      }
-    if (alarm_match) {
-      BX_CMOS_THIS s.reg[REG_STAT_C] |= 0xa0; // Interrupt Request, Alarm Int
-      DEV_pic_raise_irq(8);
-      }
-    }
-  BX_CMOS_THIS s.reg[REG_STAT_A] &= 0x7f; // clear UIP bit
-}
-
-
-  void
-bx_cmos_c::update_clock()
-{
-  struct tm *time_calendar;
-  unsigned year, month, day, century;
-  Bit8u val_bcd;
-
-  time_calendar = localtime(& BX_CMOS_THIS s.timeval);
-
-  // update seconds
-  val_bcd =
-     ((time_calendar->tm_sec  / 10) << 4) |
-     (time_calendar->tm_sec % 10);
-  BX_CMOS_THIS s.reg[REG_SEC] = val_bcd;
-
-  // update minutes
-  val_bcd =
-     ((time_calendar->tm_min  / 10) << 4) |
-     (time_calendar->tm_min % 10);
-  BX_CMOS_THIS s.reg[REG_MIN] = val_bcd;
-
-  // update hours
-  val_bcd =
-     ((time_calendar->tm_hour  / 10) << 4) |
-     (time_calendar->tm_hour % 10);
-  BX_CMOS_THIS s.reg[REG_HOUR] = val_bcd;
-
-  // update day of the week
-  day = time_calendar->tm_wday + 1; // 0..6 to 1..7
-  BX_CMOS_THIS s.reg[REG_WEEK_DAY] = ((day / 10) << 4) | (day % 10);
-
-  // update day of the month
-  day = time_calendar->tm_mday;
-  BX_CMOS_THIS s.reg[REG_MONTH_DAY] = ((day / 10) << 4) | (day % 10);
-
-  // update month
-  month   = time_calendar->tm_mon + 1;
-  BX_CMOS_THIS s.reg[REG_MONTH] = ((month / 10) << 4) | (month % 10);
-
-  // update year
-  year = time_calendar->tm_year % 100;
-  BX_CMOS_THIS s.reg[REG_YEAR] = ((year  / 10) << 4) | (year % 10);
-
-  // update century
-  century = (time_calendar->tm_year / 100) + 19;
-  BX_CMOS_THIS s.reg[REG_IBM_CENTURY_BYTE] = 
-    ((century  / 10) << 4) | (century % 10);
-
-  // Raul Hudea pointed out that some bioses also use reg 0x37 for the 
-  // century byte.  Tony Heller says this is critical in getting WinXP to run.
-  BX_CMOS_THIS s.reg[REG_IBM_PS2_CENTURY_BYTE] = 
-    BX_CMOS_THIS s.reg[REG_IBM_CENTURY_BYTE];
-}
-
-  void
-bx_cmos_c::update_timeval()
-{
-  struct tm time_calendar;
-  Bit8u val_bin;
-
-  // update seconds
-  val_bin =
-     ((BX_CMOS_THIS s.reg[REG_SEC] >> 4) * 10) +
-     (BX_CMOS_THIS s.reg[REG_SEC] & 0x0f);
-  time_calendar.tm_sec = val_bin;
-
-  // update minutes
-  val_bin =
-     ((BX_CMOS_THIS s.reg[REG_MIN] >> 4) * 10) +
-     (BX_CMOS_THIS s.reg[REG_MIN] & 0x0f);
-  time_calendar.tm_min = val_bin;
-
-  // update hours
-  val_bin =
-     ((BX_CMOS_THIS s.reg[REG_HOUR] >> 4) * 10) +
-     (BX_CMOS_THIS s.reg[REG_HOUR] & 0x0f);
-  time_calendar.tm_hour = val_bin;
-
-  // update day of the month
-  val_bin =
-     ((BX_CMOS_THIS s.reg[REG_MONTH_DAY] >> 4) * 10) +
-     (BX_CMOS_THIS s.reg[REG_MONTH_DAY] & 0x0f);
-  time_calendar.tm_mday = val_bin;
-
-  // update month
-  val_bin =
-     ((BX_CMOS_THIS s.reg[REG_MONTH] >> 4) * 10) +
-     (BX_CMOS_THIS s.reg[REG_MONTH] & 0x0f);
-  time_calendar.tm_mon = val_bin - 1;
-
-  // update year
-  val_bin =
-     ((BX_CMOS_THIS s.reg[REG_IBM_CENTURY_BYTE] >> 4) * 10) +
-     (BX_CMOS_THIS s.reg[REG_IBM_CENTURY_BYTE] & 0x0f);
-  val_bin = (val_bin - 19) * 100;
-  val_bin +=
-     (((BX_CMOS_THIS s.reg[REG_YEAR] >> 4) * 10) +
-     (BX_CMOS_THIS s.reg[REG_YEAR] & 0x0f));
-  time_calendar.tm_year = val_bin;
-
-  BX_CMOS_THIS s.timeval = mktime(& time_calendar);
-}
diff --git a/tools/ioemu/iodev/cmos.h b/tools/ioemu/iodev/cmos.h
deleted file mode 100644 (file)
index c53907d..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: cmos.h,v 1.9 2003/01/04 00:02:07 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-
-
-
-#if BX_USE_CMOS_SMF
-#  define BX_CMOS_SMF  static
-#  define BX_CMOS_THIS theCmosDevice->
-#else
-#  define BX_CMOS_SMF
-#  define BX_CMOS_THIS this->
-#endif
-
-
-class bx_cmos_c : public bx_cmos_stub_c {
-public:
-  bx_cmos_c(void);
-  ~bx_cmos_c(void);
-
-  virtual void init(void);
-  virtual void checksum_cmos(void);
-  virtual void reset(unsigned type);
-
-  virtual Bit32u get_reg(unsigned reg) {
-    return s.reg[reg];
-  }
-  virtual void set_reg(unsigned reg, Bit32u val) {
-    s.reg[reg] = val;
-  }
-  virtual time_t get_timeval() {
-    return s.timeval;
-  }
-
-  struct {
-    int     periodic_timer_index;
-    Bit32u  periodic_interval_usec;
-    int     one_second_timer_index;
-    int     uip_timer_index;
-    time_t  timeval;
-    Bit8u   cmos_mem_address;
-    bx_bool timeval_change;
-
-    Bit8u   reg[BX_NUM_CMOS_REGS];
-    } s;  // state information
-
-private:
-  static Bit32u read_handler(void *this_ptr, Bit32u address, unsigned io_len);
-  static void   write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);
-#if !BX_USE_CMOS_SMF
-  Bit32u read(Bit32u address, unsigned io_len);
-  void   write(Bit32u address, Bit32u value, unsigned len);
-#endif
-
-public:
-  static void periodic_timer_handler(void *);
-  static void one_second_timer_handler(void *);
-  static void uip_timer_handler(void *);
-  BX_CMOS_SMF void periodic_timer(void);
-  BX_CMOS_SMF void one_second_timer(void);
-  BX_CMOS_SMF void uip_timer(void);
-private:
-  BX_CMOS_SMF void update_clock(void);
-  BX_CMOS_SMF void update_timeval(void);
-  BX_CMOS_SMF void CRA_change(void);
-  };
diff --git a/tools/ioemu/iodev/cpu.cc b/tools/ioemu/iodev/cpu.cc
deleted file mode 100644 (file)
index 3e234d5..0000000
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- * Main cpu loop for handling I/O requests coming from a virtual machine
- * Copyright © 2004, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU Lesser General Public License,
- * version 2.1, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#include "bochs.h"
-#include <cpu/cpu.h>
-#ifdef BX_USE_VMX
-#include <sys/ioctl.h>
-/* According to POSIX 1003.1-2001 */
-#include <sys/select.h>
-
-/* According to earlier standards */
-#include <sys/time.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <values.h>
-#endif
-
-#define LOG_THIS BX_CPU_THIS_PTR
-
-#ifdef BX_USE_VMX
-
-//the evtchn fd for polling
-int evtchn_fd = -1;
-//the evtchn port for polling the notification, should be inputed as bochs's parameter
-u16 ioreq_port = 0;
-
-void *shared_page = NULL;
-
-//some functions to handle the io req packet
-
-//get the ioreq packets from share mem
-ioreq_t* bx_cpu_c::__get_ioreq(void)
-{
-       ioreq_t *req;
-       req = &((vcpu_iodata_t *) shared_page)->vp_ioreq;
-       if (req->state == STATE_IOREQ_READY) {
-               req->state = STATE_IOREQ_INPROCESS;
-       } else {
-               BX_INFO(("False I/O request ... in-service already: %lx, pvalid: %lx,port: %lx, data: %lx, count: %lx, size: %lx\n", req->state, req->pdata_valid, req->addr, req->u.data, req->count, req->size));
-               req = NULL;
-       }
-
-       return req;
-}
-
-//use poll to get the port notification
-//ioreq_vec--out,the 
-//retval--the number of ioreq packet
-ioreq_t* bx_cpu_c::get_ioreq(void)
-{
-       ioreq_t *req;
-       int rc;
-       u16 buf[2];
-       rc = read(evtchn_fd, buf, 2);
-       if (rc == 2 && buf[0] == ioreq_port){//got only one matched 16bit port index
-               // unmask the wanted port again
-               write(evtchn_fd, &ioreq_port, 2);
-
-               //get the io packet from shared memory
-               return __get_ioreq();
-       }
-
-       //read error or read nothing
-       return NULL;
-}
-
-//send the ioreq to device model
-void bx_cpu_c::dispatch_ioreq(ioreq_t *req)
-{
-       int ret, i;
-    int sign;
-
-    sign = (req->df) ? -1 : 1;
-
-       if ((!req->pdata_valid) && (req->dir == IOREQ_WRITE)) {
-               if (req->size != 4) {
-                       // Bochs expects higher bits to be 0
-                       req->u.data &= (1UL << (8 * req->size))-1;
-               }
-       }
-       if (req->port_mm == 0){//port io
-               if(req->dir == IOREQ_READ){//read
-                       //BX_INFO(("pio: <READ>addr:%llx, value:%llx, size: %llx, count: %llx\n", req->addr, req->u.data, req->size, req->count));
-
-                       if (!req->pdata_valid)
-                               req->u.data = BX_INP(req->addr, req->size);
-                       else {
-                               unsigned long tmp; 
-
-                               for (i = 0; i < req->count; i++) {
-                                       tmp = BX_INP(req->addr, req->size);
-                                       BX_MEM_WRITE_PHYSICAL((dma_addr_t) req->u.pdata + (sign * i * req->size), 
-                                                              req->size, &tmp);
-                               }
-                       }
-               } else if(req->dir == IOREQ_WRITE) {
-                       //BX_INFO(("pio: <WRITE>addr:%llx, value:%llx, size: %llx, count: %llx\n", req->addr, req->u.data, req->size, req->count));
-
-                       if (!req->pdata_valid) {
-                               BX_OUTP(req->addr, (dma_addr_t) req->u.data, req->size);
-                       } else {
-                               for (i = 0; i < req->count; i++) {
-                                       unsigned long tmp;
-
-                                       BX_MEM_READ_PHYSICAL((dma_addr_t) req->u.pdata + (sign * i * req->size), req->size, 
-                                                        &tmp);
-                                       BX_OUTP(req->addr, (dma_addr_t) tmp, req->size);
-                               }
-                       }
-                       
-               }
-       } else if (req->port_mm == 1){//memory map io
-               if (!req->pdata_valid) {
-                       if(req->dir == IOREQ_READ){//read
-                               //BX_INFO(("mmio[value]: <READ> addr:%llx, value:%llx, size: %llx, count: %llx\n", req->addr, req->u.data, req->size, req->count));
-                               for (i = 0; i < req->count; i++) {
-                                       BX_MEM_READ_PHYSICAL(req->addr + (sign * i * req->size), req->size, &req->u.data);
-                               }
-                       } else if(req->dir == IOREQ_WRITE) {//write
-                               //BX_INFO(("mmio[value]: <WRITE> addr:%llx, value:%llx, size: %llx, count: %llx\n", req->addr, req->u.data, req->size, req->count));
-                               for (i = 0; i < req->count; i++) {
-                                       BX_MEM_WRITE_PHYSICAL(req->addr + (sign * i * req->size), req->size, &req->u.data);
-                               }
-                       }
-               } else {
-                       //handle movs
-                       unsigned long tmp;
-                       if (req->dir == IOREQ_READ) {
-                               //BX_INFO(("mmio[pdata]: <READ>addr:%llx, pdata:%llx, size: %x, count: %x\n", req->addr, req->u.pdata, req->size, req->count));
-                               for (i = 0; i < req->count; i++) {
-                                       BX_MEM_READ_PHYSICAL(req->addr + (sign * i * req->size), req->size, &tmp);
-                                       BX_MEM_WRITE_PHYSICAL((dma_addr_t) req->u.pdata + (sign * i * req->size), req->size, &tmp);
-                               }
-                       } else if (req->dir == IOREQ_WRITE) {
-                               //BX_INFO(("mmio[pdata]: <WRITE>addr:%llx, pdata:%llx, size: %x, count: %x\n", req->addr, req->u.pdata, req->size, req->count));
-                               for (i = 0; i < req->count; i++) {
-                                       BX_MEM_READ_PHYSICAL((dma_addr_t)req->u.pdata + (sign * i * req->size), req->size, &tmp);
-                                       BX_MEM_WRITE_PHYSICAL(req->addr + (sign * i * req->size), req->size, &tmp);
-                               }
-                       }
-               }
-       }
-
-        /* No state change if state = STATE_IORESP_HOOK */
-        if (req->state == STATE_IOREQ_INPROCESS)
-                req->state = STATE_IORESP_READY;
-
-       send_event = 1;
-}
-
-void
-bx_cpu_c::handle_ioreq(void)
-{
-       ioreq_t *req = get_ioreq();
-       if (req)
-               dispatch_ioreq(req);
-}
-
-void
-bx_cpu_c::timer_handler(void)
-{
-       handle_ioreq();
-}
-
-#endif
-
-#define rdtscl(low) \
-     __asm__ __volatile__("rdtsc" : "=a" (low) : : "edx")
-
-void
-bx_cpu_c::cpu_loop(int max_instr_count)
-{
-       Bit8u vector;
-       fd_set rfds;
-       unsigned long stime_usec;
-       struct timeval tv;
-       int retval;
-
-       /* Watch stdin (fd 0) to see when it has input. */
-       FD_ZERO(&rfds);
-
-       while (1) {
-                static unsigned long long t1 = 0;
-               unsigned long long t2;
-
-               /* Wait up to one seconds. */
-               tv.tv_sec = 0;
-               tv.tv_usec = 100000;
-               FD_SET(evtchn_fd, &rfds);
-
-               send_event = 0;
-
-               if (t1 == 0) // the first time
-                       rdtscll(t1);
-
-               retval = select(evtchn_fd+1, &rfds, NULL, NULL, &tv);
-               if (retval == -1) {
-                       perror("select");
-                       return;
-               }
-
-               rdtscll(t2);
-
-#if __WORDSIZE == 32
-#define ULONGLONG_MAX   0xffffffffffffffffULL
-#else
-#define ULONGLONG_MAX   ULONG_MAX
-#endif
-
-               if (t2 <= t1)
-                       BX_TICKN((t2 + ULONGLONG_MAX - t1) / tsc_per_bx_tick);
-               else
-                       BX_TICKN((t2 - t1) / tsc_per_bx_tick);
-               t1 = t2;
-
-               timer_handler();
-               if (BX_CPU_INTR) {
-#if BX_SUPPORT_APIC
-                       if (BX_CPU_THIS_PTR local_apic.INTR)
-                               vector = BX_CPU_THIS_PTR local_apic.acknowledge_int ();
-                       else
-                               vector = DEV_pic_iac(); // may set INTR with next interrupt
-#else
-                       // if no local APIC, always acknowledge the PIC.
-                       vector = DEV_pic_iac(); // may set INTR with next interrupt
-#endif
-                       interrupt(vector);
-               }
-               /* we check DMA after interrupt check*/
-               while(BX_HRQ){
-                       DEV_dma_raise_hlda();
-               }
-
-               if (send_event) {
-                       int ret;
-                       ret = xc_evtchn_send(xc_handle, ioreq_port);
-                       if (ret == -1) {
-                               BX_ERROR(("evtchn_send failed on port: %d\n", ioreq_port));
-                       }
-               }
-       }
-}
-
-#ifdef __i386__
-static __inline__ void set_bit(long nr, volatile void *addr)
-{
-       __asm__ __volatile__( "lock ; "
-               "btsl %1,%0"
-               :"=m" ((*(volatile long *)addr))
-               :"Ir" (nr));
-
-       return;
-}
-#else 
-/* XXX: clean for IPF */
-static __inline__ void set_bit(long nr, volatile void *addr)
-{
-       __asm__ __volatile__( "lock ; "
-               "btsq %1,%0"
-               :"=m" ((*(volatile long *)addr))
-               :"Ir" (nr));
-
-       return;
-}
-#endif
-
-void
-bx_cpu_c::interrupt(Bit8u vector)
-{
-       unsigned long *intr, tscl;
-       int ret;
-
-       // Send a message on the event channel. Add the vector to the shared mem
-       // page.
-
-       rdtscl(tscl);
-       BX_DEBUG(("%lx: injecting vector: %x\n", tscl, vector));
-       intr = &(((vcpu_iodata_t *) shared_page)->vp_intr[0]);
-       set_bit(vector, intr);
-       
-       send_event = 1;
-}
-
-void
-bx_cpu_c::init(bx_mem_c*)
-{
-#ifdef BX_USE_VMX
-       if (evtchn_fd != -1)//the evtchn has been opened by another cpu object
-               return;
-
-       //use nonblock reading not polling, may change in future.
-       evtchn_fd = open("/dev/xen/evtchn", O_RDWR|O_NONBLOCK); 
-       if (evtchn_fd == -1) {
-               perror("open");
-               return;
-       }
-
-       BX_INFO(("listening to port: %d\n", ioreq_port));
-       /*unmask the wanted port -- bind*/
-       if (ioctl(evtchn_fd, ('E'<<8)|2, ioreq_port) == -1) {
-               perror("ioctl");
-               return;
-       }
-
-#if 0  
-       //register the reading evtchn function as timer
-       bx_pc_system.register_timer(this, timer_handler, 1000,//1000 us, may change
-                       1,//continuous timer
-                       1,//active
-                       "cpu reading evtchn handler");
-#endif
-
-#endif
-}
-
-void
-bx_cpu_c::reset(unsigned)
-{
-}
-
-void
-bx_cpu_c::atexit()
-{
-}
-
-void
-bx_cpu_c::set_INTR(unsigned value)
-{
-       BX_CPU_THIS_PTR INTR = value;
-}
-
-void
-bx_cpu_c::pagingA20Changed()
-{
-}
-
-bx_cpu_c::bx_cpu_c()
-{
-}
-
-bx_cpu_c::~bx_cpu_c()
-{
-}
diff --git a/tools/ioemu/iodev/crc32.cc b/tools/ioemu/iodev/crc32.cc
deleted file mode 100644 (file)
index a20abaa..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: crc32.cc,v 1.4 2001/10/03 13:10:38 bdenney Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-/* CRC-32 calculator
- * Adapted from http://www.createwindow.org/programming/crc32/
- */
-
-#include "crc32.h"
-
-CRC_Generator::CRC_Generator() {
-       init();
-}
-
-void CRC_Generator::init(void) {
-  Bit32u POLYNOMIAL = 0x04c11db7;
-  int i;
-
-  for(i = 0; i<0xFF; i++) {
-    int j;
-    crc32_table[i]=reflect(i,8) << 24;
-    for(j=0; j<8; j++)
-      crc32_table[i] = (crc32_table[i]<<1)^(crc32_table[i] & (1<<31) ? POLYNOMIAL : 0);
-    crc32_table[i] = reflect(crc32_table[i], 32);
-  }
-}
-
-Bit32u CRC_Generator::reflect(Bit32u ref, Bit8u ch) {
-  Bit32u value(0);
-  int i;
-
-  for(i=1; i<(ch+1); i++) {
-    if(ref & 1)
-      value |= 1 << (ch-i);
-    ref >>= 1;
-  }
-  return value;
-}
-
-Bit32u CRC_Generator::get_CRC(Bit8u * buf, Bit32u buflen) {
-  Bit32u ulCRC(0xFFFFFFFF);
-  Bit32u len(buflen);
-  Bit8u * buffer=(Bit8u *) buf;
-
-  while(len--)
-    ulCRC=(ulCRC>>8)^crc32_table[(ulCRC & 0xFF)^*buffer++];
-  return ulCRC ^ 0xFFFFFFFF;
-}
-
diff --git a/tools/ioemu/iodev/crc32.h b/tools/ioemu/iodev/crc32.h
deleted file mode 100644 (file)
index faedaf8..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: crc32.h,v 1.3 2001/10/03 13:10:38 bdenney Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-/* CRC-32 calculator
- * Adapted from http://www.createwindow.org/programming/crc32/
- */
-
-#ifndef _CRC_32_H_
-#define _CRC_32_H_
-
-#include "bochs.h"
-
-class CRC_Generator {
-private:
-  Bit32u crc32_table[256];
-  Bit32u reflect(Bit32u ref, Bit8u ch);
-public:
-  void init(void);
-  CRC_Generator();
-  Bit32u get_CRC(Bit8u * buf, Bit32u buflen);
-};
-
-#endif //_CRC_32_H_
-
diff --git a/tools/ioemu/iodev/devices.cc b/tools/ioemu/iodev/devices.cc
deleted file mode 100644 (file)
index 5dd7f5d..0000000
+++ /dev/null
@@ -1,685 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: devices.cc,v 1.58 2003/12/26 13:53:39 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-#include "bochs.h"
-#define LOG_THIS bx_devices.
-
-
-
-/* main memory size (in Kbytes)
- * subtract 1k for extended BIOS area
- * report only base memory, not extended mem
- */
-#define BASE_MEMORY_IN_K  640
-
-
-bx_devices_c bx_devices;
-
-
-
-
-// constructor for bx_devices_c
-bx_devices_c::bx_devices_c(void)
-{
-  put("DEV");
-  settype(DEVLOG);
-
-#if BX_PCI_SUPPORT
-  pluginPciBridge = &stubPci;
-  pluginPci2IsaBridge = NULL;
-#if BX_PCI_VGA_SUPPORT
-    pluginPciVgaAdapter = NULL;
-#endif
-#if BX_PCI_USB_SUPPORT
-    pluginPciUSBAdapter = NULL;
-#endif                               
-#endif
-  pit = NULL;
-  pluginKeyboard = &stubKeyboard;
-  pluginDmaDevice = &stubDma;
-  pluginFloppyDevice = &stubFloppy;
-  pluginBiosDevice = NULL;
-  pluginCmosDevice = &stubCmos;
-  pluginSerialDevice = NULL;
-  pluginParallelDevice = NULL;
-  pluginUnmapped = NULL;
-  pluginVgaDevice = &stubVga;
-  pluginPicDevice = &stubPic;
-  pluginHardDrive = &stubHardDrive;
-  pluginSB16Device = NULL;
-  pluginNE2kDevice =&stubNE2k;
-  pluginExtFpuIrq = NULL;
-  pluginGameport = NULL;
-  g2h = NULL;
-#if BX_IODEBUG_SUPPORT
-  iodebug = NULL;
-#endif
-}
-
-
-bx_devices_c::~bx_devices_c(void)
-{
-  // nothing needed for now
-  BX_DEBUG(("Exit."));
-  timer_handle = BX_NULL_TIMER_HANDLE;
-}
-
-
-  void
-bx_devices_c::init(BX_MEM_C *newmem)
-{
-  unsigned i;
-
-  BX_DEBUG(("Init $Id: devices.cc,v 1.58 2003/12/26 13:53:39 vruppert Exp $"));
-  mem = newmem;
-
-  /* no read / write handlers defined */
-  num_read_handles = 0;
-  num_write_handles = 0;
-
-  /* set unused elements to appropriate values */
-  for (i=0; i < BX_MAX_IO_DEVICES; i++) {
-    io_read_handler[i].funct  = NULL;
-    io_write_handler[i].funct = NULL;
-    }
-
-  /* set no-default handlers, will be overwritten by the real default handler */
-  io_read_handler[BX_DEFAULT_IO_DEVICE].handler_name  = "Default";
-  io_read_handler[BX_DEFAULT_IO_DEVICE].funct         = &default_read_handler;
-  io_read_handler[BX_DEFAULT_IO_DEVICE].this_ptr      = NULL;
-  io_read_handler[BX_DEFAULT_IO_DEVICE].mask          = 7;
-  io_write_handler[BX_DEFAULT_IO_DEVICE].handler_name = "Default";
-  io_write_handler[BX_DEFAULT_IO_DEVICE].funct        = &default_write_handler;
-  io_write_handler[BX_DEFAULT_IO_DEVICE].this_ptr     = NULL;
-  io_write_handler[BX_DEFAULT_IO_DEVICE].mask         = 7;
-
-  /* set handlers to the default one */
-  for (i=0; i < 0x10000; i++) {
-    read_handler_id[i] = BX_DEFAULT_IO_DEVICE; 
-    write_handler_id[i] = BX_DEFAULT_IO_DEVICE;
-    }
-
-  for (i=0; i < BX_MAX_IRQS; i++) {
-    irq_handler_name[i] = NULL;
-    }
-
-  // BBD: At present, the only difference between "core" and "optional"
-  // plugins is that initialization and reset of optional plugins is handled
-  // by the plugin device list ().  Init and reset of core plugins is done
-  // "by hand" in this file.  Basically, we're using core plugins when we
-  // want to control the init order.
-  //
-  // CB: UNMAPPED and BIOSDEV should maybe be optional
-  PLUG_load_plugin(unmapped, PLUGTYPE_CORE);
-  PLUG_load_plugin(biosdev, PLUGTYPE_CORE);
-  PLUG_load_plugin(cmos, PLUGTYPE_CORE);
-  PLUG_load_plugin(dma, PLUGTYPE_CORE);
-  PLUG_load_plugin(pic, PLUGTYPE_CORE);
-  PLUG_load_plugin(vga, PLUGTYPE_CORE);
-  PLUG_load_plugin(floppy, PLUGTYPE_CORE);
-  PLUG_load_plugin(harddrv, PLUGTYPE_OPTIONAL);
-  PLUG_load_plugin(keyboard, PLUGTYPE_OPTIONAL);
-  if (is_serial_enabled ())
-    PLUG_load_plugin(serial, PLUGTYPE_OPTIONAL);
-  if (is_parallel_enabled ()) 
-    PLUG_load_plugin(parallel, PLUGTYPE_OPTIONAL);
-  PLUG_load_plugin(extfpuirq, PLUGTYPE_OPTIONAL);
-#if BX_SUPPORT_GAME
-  PLUG_load_plugin(gameport, PLUGTYPE_OPTIONAL);
-#endif
-
-  // Start with registering the default (unmapped) handler
-  pluginUnmapped->init ();
-
-  // PCI logic (i440FX)
-  if (bx_options.Oi440FXSupport->get ()) {
-#if BX_PCI_SUPPORT
-    PLUG_load_plugin(pci, PLUGTYPE_OPTIONAL);
-    PLUG_load_plugin(pci2isa, PLUGTYPE_OPTIONAL);
-#if BX_PCI_VGA_SUPPORT
-    PLUG_load_plugin(pcivga, PLUGTYPE_OPTIONAL);
-#endif
-#if BX_PCI_USB_SUPPORT
-    PLUG_load_plugin(pciusb, PLUGTYPE_OPTIONAL);
-#endif
-#else
-    BX_ERROR(("Bochs is not compiled with PCI support"));
-#endif
-  }
-
-#if BX_SUPPORT_APIC
-    // I/O APIC 82093AA
-    ioapic = & bx_ioapic;
-    ioapic->init ();
-#endif
-
-  // BIOS log 
-  pluginBiosDevice->init ();
-
-  // CMOS RAM & RTC
-  pluginCmosDevice->init ();
-
-  /*--- 8237 DMA ---*/
-  pluginDmaDevice->init();
-
-  //--- FLOPPY ---
-  pluginFloppyDevice->init();
-
-  //--- SOUND ---
-  if (bx_options.sb16.Opresent->get ()) {
-#if BX_SUPPORT_SB16
-    PLUG_load_plugin(sb16, PLUGTYPE_OPTIONAL);
-#else
-    BX_ERROR(("Bochs is not compiled with SB16 support"));
-#endif
-  }
-
-  /*--- VGA adapter ---*/
-  pluginVgaDevice->init ();
-
-  /*--- 8259A PIC ---*/
-  pluginPicDevice->init();
-
-  /*--- 8254 PIT ---*/
-  pit = & bx_pit;
-  pit->init();
-
-  bx_virt_timer.init();
-
-  bx_slowdown_timer.init();
-
-#if BX_IODEBUG_SUPPORT
-  iodebug = &bx_iodebug;
-  iodebug->init();
-#endif
-
-  // NE2000 NIC
-  if (bx_options.ne2k.Opresent->get ()) {
-#if BX_NE2K_SUPPORT
-    PLUG_load_plugin(ne2k, PLUGTYPE_OPTIONAL);
-#else
-    BX_ERROR(("Bochs is not compiled with NE2K support"));
-#endif
-  }
-
-#if 0
-  // Guest to Host interface.  Used with special guest drivers
-  // which move data to/from the host environment.
-  g2h = &bx_g2h;
-  g2h->init();
-#endif
-
-  // system hardware
-  register_io_read_handler( this,
-                            &read_handler,
-                            0x0092,
-                            "Port 92h System Control", 1 );
-  register_io_write_handler(this,
-                            &write_handler,
-                            0x0092,
-                            "Port 92h System Control", 1 );
-
-  // misc. CMOS
-  Bit32u extended_memory_in_k = mem->get_memory_in_k() > 1024 ? (mem->get_memory_in_k() - 1024) : 0;
-  if (extended_memory_in_k > 0xffff) extended_memory_in_k = 0xffff;
-
-  DEV_cmos_set_reg(0x15, (Bit8u) BASE_MEMORY_IN_K);
-  DEV_cmos_set_reg(0x16, (Bit8u) (BASE_MEMORY_IN_K >> 8));
-  DEV_cmos_set_reg(0x17, (Bit8u) (extended_memory_in_k & 0xff) );
-  DEV_cmos_set_reg(0x18, (Bit8u) ((extended_memory_in_k >> 8) & 0xff) );
-  DEV_cmos_set_reg(0x30, (Bit8u) (extended_memory_in_k & 0xff) );
-  DEV_cmos_set_reg(0x31, (Bit8u) ((extended_memory_in_k >> 8) & 0xff) );
-
-  Bit32u extended_memory_in_64k = mem->get_memory_in_k() > 16384 ? (mem->get_memory_in_k() - 16384) / 64 : 0;
-  if (extended_memory_in_64k > 0xffff) extended_memory_in_64k = 0xffff;
-
-  DEV_cmos_set_reg(0x34, (Bit8u) (extended_memory_in_64k & 0xff) );
-  DEV_cmos_set_reg(0x35, (Bit8u) ((extended_memory_in_64k >> 8) & 0xff) );
-
-  if (timer_handle != BX_NULL_TIMER_HANDLE) {
-    timer_handle = bx_pc_system.register_timer( this, timer_handler,
-      (unsigned) BX_IODEV_HANDLER_PERIOD, 1, 1, "devices.cc");
-  }
-
-  // Clear fields for bulk IO acceleration transfers.
-  bulkIOHostAddr = 0;
-  bulkIOQuantumsRequested = 0;
-  bulkIOQuantumsTransferred = 0;
-
-  bx_init_plugins();
-
-  /* now perform checksum of CMOS memory */
-  DEV_cmos_checksum();
-}
-
-
-  void
-bx_devices_c::reset(unsigned type)
-{
-  pluginUnmapped->reset(type);
-#if BX_PCI_SUPPORT
-  if (bx_options.Oi440FXSupport->get ()) {
-    pluginPciBridge->reset(type);
-    pluginPci2IsaBridge->reset(type);
-#if BX_PCI_VGA_SUPPORT
-    pluginPciVgaAdapter->reset(type);
-#endif
-#if BX_PCI_USB_SUPPORT
-    pluginPciUSBAdapter->reset(type);
-#endif
-  }
-#endif
-#if BX_SUPPORT_IOAPIC
-  ioapic->reset (type);
-#endif
-  pluginBiosDevice->reset(type);
-  pluginCmosDevice->reset(type);
-  pluginDmaDevice->reset(type);
-  pluginFloppyDevice->reset(type);
-#if BX_SUPPORT_SB16
-  if (pluginSB16Device) pluginSB16Device->reset(type);
-#endif
-  pluginVgaDevice->reset(type);
-  pluginPicDevice->reset(type);
-  pit->reset(type);
-  bx_slowdown_timer.reset(type);
-#if BX_IODEBUG_SUPPORT
-  iodebug->reset(type);
-#endif
-#if BX_NE2K_SUPPORT
-  if (pluginNE2kDevice) pluginNE2kDevice->reset(type);
-#endif
-
-  bx_reset_plugins(type);
-}
-
-
-  Bit32u
-bx_devices_c::read_handler(void *this_ptr, Bit32u address, unsigned io_len)
-{
-#if !BX_USE_DEV_SMF
-  bx_devices_c *class_ptr = (bx_devices_c *) this_ptr;
-
-  return( class_ptr->port92_read(address, io_len) );
-}
-
-
-  Bit32u
-bx_devices_c::port92_read(Bit32u address, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif  // !BX_USE_DEV_SMF
-
-  BX_DEBUG(("port92h read partially supported!!!"));
-  BX_DEBUG(("  returning %02x", (unsigned) (BX_GET_ENABLE_A20() << 1)));
-  return(BX_GET_ENABLE_A20() << 1);
-}
-
-
-  void
-bx_devices_c::write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len)
-{
-#if !BX_USE_DEV_SMF
-  bx_devices_c *class_ptr = (bx_devices_c *) this_ptr;
-
-  class_ptr->port92_write(address, value, io_len);
-}
-
-  void
-bx_devices_c::port92_write(Bit32u address, Bit32u value, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif  // !BX_USE_DEV_SMF
-  bx_bool bx_cpu_reset;
-
-  BX_DEBUG(("port92h write of %02x partially supported!!!",
-    (unsigned) value));
-  BX_DEBUG(("A20: set_enable_a20() called"));
-  BX_SET_ENABLE_A20( (value & 0x02) >> 1 );
-  BX_DEBUG(("A20: now %u", (unsigned) BX_GET_ENABLE_A20()));
-  bx_cpu_reset  = (value & 0x01); /* high speed reset */
-  if (bx_cpu_reset) {
-    BX_PANIC(("PORT 92h write: CPU reset requested!"));
-    }
-}
-
-
-// This defines a no-default read handler, 
-// so Bochs does not segfault if unmapped is not loaded
-  Bit32u
-bx_devices_c::default_read_handler(void *this_ptr, Bit32u address, unsigned io_len)
-{
-  UNUSED(this_ptr);
-  BX_PANIC(("No default io-read handler found for 0x%04x/%d. Unmapped io-device not loaded ?", address, io_len));
-  return 0xffffffff;
-}
-
-// This defines a no-default write handler, 
-// so Bochs does not segfault if unmapped is not loaded
-  void
-bx_devices_c::default_write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len)
-{
-  UNUSED(this_ptr);
-  BX_PANIC(("No default io-write handler found for 0x%04x/%d. Unmapped io-device not loaded ?", address, io_len));
-}
-
-  void
-bx_devices_c::timer_handler(void *this_ptr)
-{
-  bx_devices_c *class_ptr = (bx_devices_c *) this_ptr;
-
-  class_ptr->timer();
-}
-
-  void
-bx_devices_c::timer()
-{
-#if (BX_USE_NEW_PIT==0)
-  if ( pit->periodic( BX_IODEV_HANDLER_PERIOD ) ) {
-    // This is a hack to make the IRQ0 work
-    DEV_pic_lower_irq(0);
-    DEV_pic_raise_irq(0);
-    }
-#endif
-
-
-  // separate calls to bx_gui->handle_events from the keyboard code.
-  {
-    static int multiple=0;
-    if ( ++multiple==10)
-    {
-      multiple=0;
-      SIM->periodic ();
-      if (!BX_CPU(0)->kill_bochs_request)
-       bx_gui->handle_events();
-    }
-  }
-
-// KPL Removed lapic periodic timer registration here.
-}
-
-
-  bx_bool
-bx_devices_c::register_irq(unsigned irq, const char *name)
-{
-  if (irq >= BX_MAX_IRQS) {
-    BX_PANIC(("IO device %s registered with IRQ=%d above %u",
-             name, irq, (unsigned) BX_MAX_IRQS-1));
-    return false;
-    }
-  if (irq_handler_name[irq]) {
-    BX_PANIC(("IRQ %u conflict, %s with %s", irq,
-      irq_handler_name[irq], name));
-    return false;
-    }
-  irq_handler_name[irq] = name;
-  return true;
-}
-
-  bx_bool
-bx_devices_c::unregister_irq(unsigned irq, const char *name)
-{
-  if (irq >= BX_MAX_IRQS) {
-    BX_PANIC(("IO device %s tried to unregister IRQ %d above %u",
-             name, irq, (unsigned) BX_MAX_IRQS-1));
-    return false;
-    }
-
-  if (!irq_handler_name[irq]) {
-    BX_INFO(("IO device %s tried to unregister IRQ %d, not registered",
-             name, irq));
-    return false;
-  }
-
-  if (strcmp(irq_handler_name[irq], name)) {
-    BX_INFO(("IRQ %u not registered to %s but to %s", irq,
-      name, irq_handler_name[irq]));
-    return false;
-    }
-  irq_handler_name[irq] = NULL;
-  return true;
-}
-
-  bx_bool
-bx_devices_c::register_io_read_handler( void *this_ptr, bx_read_handler_t f,
-                                        Bit32u addr, const char *name, Bit8u mask )
-{
-  unsigned handle;
-
-  addr &= 0x0000ffff;
-
-  /* first find existing handle for function or create new one */
-  for (handle=0; handle < num_read_handles; handle++) {
-    if ((io_read_handler[handle].funct == f) &&
-        (io_read_handler[handle].mask == mask)) break;
-    }
-
-  if (handle >= num_read_handles) {
-    /* no existing handle found, create new one */
-    if (num_read_handles >= BX_DEFAULT_IO_DEVICE) {
-      BX_INFO(("too many IO devices installed."));
-      BX_PANIC(("  try increasing BX_MAX_IO_DEVICES"));
-      }
-    num_read_handles++;
-    io_read_handler[handle].funct          = f;
-    io_read_handler[handle].this_ptr       = this_ptr;
-    io_read_handler[handle].handler_name   = name;
-    io_read_handler[handle].mask           = mask;
-    }
-
-  /* change table to reflect new handler id for that address */
-  if (read_handler_id[addr] < BX_DEFAULT_IO_DEVICE) {
-    // another handler is already registered for that address
-    BX_ERROR(("IO device address conflict(read) at IO address %Xh",
-      (unsigned) addr));
-    BX_ERROR(("  conflicting devices: %s & %s",
-      io_read_handler[handle].handler_name, io_read_handler[read_handler_id[addr]].handler_name));
-    return false; // address not available, return false.
-    }
-  read_handler_id[addr] = handle;
-  return true; // address mapped successfully
-}
-
-
-
-  bx_bool
-bx_devices_c::register_io_write_handler( void *this_ptr, bx_write_handler_t f,
-                                        Bit32u addr, const char *name, Bit8u mask )
-{
-  unsigned handle;
-
-  addr &= 0x0000ffff;
-
-  /* first find existing handle for function or create new one */
-  for (handle=0; handle < num_write_handles; handle++) {
-    if ((io_write_handler[handle].funct == f) &&
-        (io_write_handler[handle].mask == mask)) break;
-    }
-
-  if (handle >= num_write_handles) {
-    /* no existing handle found, create new one */
-    if (num_write_handles >= BX_DEFAULT_IO_DEVICE) {
-      BX_INFO(("too many IO devices installed."));
-      BX_PANIC(("  try increasing BX_MAX_IO_DEVICES"));
-      }
-    num_write_handles++;
-    io_write_handler[handle].funct          = f;
-    io_write_handler[handle].this_ptr       = this_ptr;
-    io_write_handler[handle].handler_name   = name;
-    io_write_handler[handle].mask           = mask;
-    }
-
-  /* change table to reflect new handler id for that address */
-  if (write_handler_id[addr] < BX_DEFAULT_IO_DEVICE) {
-    // another handler is already registered for that address
-    BX_ERROR(("IO device address conflict(write) at IO address %Xh",
-      (unsigned) addr));
-    BX_ERROR(("  conflicting devices: %s & %s",
-      io_write_handler[handle].handler_name, io_write_handler[write_handler_id[addr]].handler_name));
-    return false; //unable to map iodevice.
-    }
-  write_handler_id[addr] = handle;
-  return true; // done!
-}
-
-
-// Registration of default handlers (mainly be the unmapped device)
-// The trick here is to define a handler for the max index, so
-// unregisterd io address will get handled by the default function
-// This will be helpful when we want to unregister io handlers
-
-  bx_bool
-bx_devices_c::register_default_io_read_handler( void *this_ptr, bx_read_handler_t f,
-                                        const char *name, Bit8u mask )
-{
-  unsigned handle;
-
-  /* handle is fixed to the default I/O device */
-  handle = BX_DEFAULT_IO_DEVICE;
-
-  if (strcmp(io_read_handler[handle].handler_name, "Default")) {
-    BX_ERROR(("Default io read handler already registered '%s'",io_read_handler[handle].handler_name));
-    return false;
-    }
-
-  io_read_handler[handle].funct          = f;
-  io_read_handler[handle].this_ptr       = this_ptr;
-  io_read_handler[handle].handler_name   = name;
-  io_read_handler[handle].mask           = mask;
-
-  return true; 
-}
-
-
-
-  bx_bool
-bx_devices_c::register_default_io_write_handler( void *this_ptr, bx_write_handler_t f,
-                                        const char *name, Bit8u mask )
-{
-  unsigned handle;
-
-  /* handle is fixed to the MAX */
-  handle = BX_DEFAULT_IO_DEVICE;
-
-  if (strcmp(io_write_handler[handle].handler_name, "Default")) {
-    BX_ERROR(("Default io write handler already registered '%s'",io_write_handler[handle].handler_name));
-    return false;
-    }
-
-  io_write_handler[handle].funct          = f;
-  io_write_handler[handle].this_ptr       = this_ptr;
-  io_write_handler[handle].handler_name   = name;
-  io_write_handler[handle].mask           = mask;
-
-  return true; 
-}
-
-
-
-/*
- * Read a byte of data from the IO memory address space
- */
-
-  Bit32u BX_CPP_AttrRegparmN(2)
-bx_devices_c::inp(Bit16u addr, unsigned io_len)
-{
-  Bit8u handle;
-  Bit32u ret;
-
-  BX_INSTR_INP(addr, io_len);
-
-  handle = read_handler_id[addr];
-  if ((io_read_handler[handle].funct != NULL) &&
-      (io_read_handler[handle].mask & io_len)) {
-    ret = (* io_read_handler[handle].funct)(io_read_handler[handle].this_ptr,
-                             (Bit32u) addr, io_len);
-  } else {
-    switch (io_len) {
-      case 1: ret = 0xff; break;
-      case 2: ret = 0xffff; break;
-      default: ret = 0xffffffff; break;
-    }
-    BX_ERROR(("read from port 0x%04x with len %d returns 0x%x", addr, io_len, ret));
-  }
-  BX_INSTR_INP2(addr, io_len, ret);
-  BX_DBG_IO_REPORT(addr, io_len, BX_READ, ret);
-
-  return(ret);
-}
-
-
-/*
- * Write a byte of data to the IO memory address space.
- */
-
-  void BX_CPP_AttrRegparmN(3)
-bx_devices_c::outp(Bit16u addr, Bit32u value, unsigned io_len)
-{
-  Bit8u handle;
-
-  BX_INSTR_OUTP(addr, io_len);
-  BX_INSTR_OUTP2(addr, io_len, value);
-
-  BX_DBG_IO_REPORT(addr, io_len, BX_WRITE, value);
-  handle = write_handler_id[addr];
-  if ((io_write_handler[handle].funct != NULL) &&
-      (io_write_handler[handle].mask & io_len)) {
-    (* io_write_handler[handle].funct)(io_write_handler[handle].this_ptr,
-                       (Bit32u) addr, value, io_len);
-  } else {
-    BX_ERROR(("write to port 0x%04x with len %d ignored", addr, io_len));
-  }
-}
-
-bx_bool bx_devices_c::is_serial_enabled ()
-{
-  for (int i=0; i<BX_N_SERIAL_PORTS; i++) {
-    if (SIM->get_param_bool (BXP_COMx_ENABLED(i+1))->get())
-      return true;
-  }
-  return false;
-}
-
-bx_bool bx_devices_c::is_usb_enabled ()
-{
-  for (int i=0; i<BX_N_USB_HUBS; i++) {
-    if (SIM->get_param_bool (BXP_USBx_ENABLED(i+1))->get())
-       return true;
-  }
-  return false;
-}
-
-bx_bool bx_devices_c::is_parallel_enabled ()
-{
-  for (int i=0; i<BX_N_PARALLEL_PORTS; i++) {
-    if (SIM->get_param_bool (BXP_PARPORTx_ENABLED(i+1))->get())
-      return true;
-  }
-  return false;
-}
diff --git a/tools/ioemu/iodev/dma.cc b/tools/ioemu/iodev/dma.cc
deleted file mode 100644 (file)
index afe0238..0000000
+++ /dev/null
@@ -1,825 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: dma.cc,v 1.30 2003/07/31 15:29:34 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-
-// Define BX_PLUGGABLE in files that can be compiled into plugins.  For
-// platforms that require a special tag on exported symbols, BX_PLUGGABLE 
-// is used to know when we are exporting symbols and when we are importing.
-#define BX_PLUGGABLE
-
-#include "bochs.h"
-
-#define LOG_THIS theDmaDevice->
-
-#define DMA_MODE_DEMAND  0
-#define DMA_MODE_SINGLE  1
-#define DMA_MODE_BLOCK   2
-#define DMA_MODE_CASCADE 3
-
-bx_dma_c *theDmaDevice = NULL;
-
-  int
-libdma_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
-{
-  theDmaDevice = new bx_dma_c ();
-  bx_devices.pluginDmaDevice = theDmaDevice;
-  BX_REGISTER_DEVICE_DEVMODEL(plugin, type, theDmaDevice, BX_PLUGIN_DMA);
-  return(0); // Success
-}
-
-  void
-libdma_LTX_plugin_fini(void)
-{
-}
-
-bx_dma_c::bx_dma_c(void)
-{
-  put("DMA");
-  settype(DMALOG);
-}
-
-bx_dma_c::~bx_dma_c(void)
-{
-       BX_DEBUG(("Exit."));
-}
-
-  unsigned
-bx_dma_c::registerDMA8Channel(
-    unsigned channel,
-    void (* dmaRead)(Bit8u *data_byte),
-    void (* dmaWrite)(Bit8u *data_byte),
-    const char *name
-    )
-{
-  if (channel > 3) {
-    BX_PANIC(("registerDMA8Channel: invalid channel number(%u).", channel));
-    return 0; // Fail.
-    }
-  if (BX_DMA_THIS s[0].chan[channel].used) {
-    BX_PANIC(("registerDMA8Channel: channel(%u) already in use.", channel));
-    return 0; // Fail.
-    }
-  BX_INFO(("channel %u used by %s", channel, name));
-  BX_DMA_THIS h[channel].dmaRead8  = dmaRead;
-  BX_DMA_THIS h[channel].dmaWrite8 = dmaWrite;
-  BX_DMA_THIS s[0].chan[channel].used = 1;
-  return 1; // OK.
-}
-
-  unsigned
-bx_dma_c::registerDMA16Channel(
-    unsigned channel,
-    void (* dmaRead)(Bit16u *data_word),
-    void (* dmaWrite)(Bit16u *data_word),
-    const char *name
-    )
-{
-  if ((channel < 4) || (channel > 7)) {
-    BX_PANIC(("registerDMA16Channel: invalid channel number(%u).", channel));
-    return 0; // Fail.
-    }
-  if (BX_DMA_THIS s[1].chan[channel & 0x03].used) {
-    BX_PANIC(("registerDMA16Channel: channel(%u) already in use.", channel));
-    return 0; // Fail.
-    }
-  BX_INFO(("channel %u used by %s", channel, name));
-  channel &= 0x03;
-  BX_DMA_THIS h[channel].dmaRead16  = dmaRead;
-  BX_DMA_THIS h[channel].dmaWrite16 = dmaWrite;
-  BX_DMA_THIS s[1].chan[channel].used = 1;
-  return 1; // OK.
-}
-
-  unsigned
-bx_dma_c::unregisterDMAChannel(unsigned channel)
-{
-  bx_bool ma_sl = (channel > 3);
-  BX_DMA_THIS s[ma_sl].chan[channel & 0x03].used = 0;
-  BX_INFO(("channel %u no longer used", channel));
-  return 1;
-}
-
-  unsigned
-bx_dma_c::get_TC(void)
-{
-  return BX_DMA_THIS TC;
-}
-
-
-  void
-bx_dma_c::init(void)
-{
-  unsigned c, i, j;
-  BX_DEBUG(("Init $Id: dma.cc,v 1.30 2003/07/31 15:29:34 vruppert Exp $"));
-
-  /* 8237 DMA controller */
-
-  for (i=0; i < 2; i++) {
-    for (j=0; j < 4; j++) {
-      BX_DMA_THIS s[i].DRQ[j] = 0;
-      BX_DMA_THIS s[i].DACK[j] = 0;
-      }
-    }
-  BX_DMA_THIS HLDA = 0;
-  BX_DMA_THIS TC = 0;
-
-  // 0000..000F
-  for (i=0x0000; i<=0x000F; i++) {
-    DEV_register_ioread_handler(this, read_handler, i, "DMA controller", 1);
-    DEV_register_iowrite_handler(this, write_handler, i, "DMA controller", 3);
-    }
-
-  // 00081..008F
-  for (i=0x0081; i<=0x008F; i++) {
-    DEV_register_ioread_handler(this, read_handler, i, "DMA controller", 1);
-    DEV_register_iowrite_handler(this, write_handler, i, "DMA controller", 3);
-    }
-
-  // 000C0..00DE
-  for (i=0x00C0; i<=0x00DE; i+=2) {
-    DEV_register_ioread_handler(this, read_handler, i, "DMA controller", 1);
-    DEV_register_iowrite_handler(this, write_handler, i, "DMA controller", 3);
-    }
-
-
-  for (i=0; i<2; i++) {
-    for (c=0; c<4; c++) {
-      BX_DMA_THIS s[i].chan[c].mode.mode_type = 0;         // demand mode
-      BX_DMA_THIS s[i].chan[c].mode.address_decrement = 0; // address increment
-      BX_DMA_THIS s[i].chan[c].mode.autoinit_enable = 0;   // autoinit disable
-      BX_DMA_THIS s[i].chan[c].mode.transfer_type = 0;     // verify
-      BX_DMA_THIS s[i].chan[c].base_address = 0;
-      BX_DMA_THIS s[i].chan[c].current_address = 0;
-      BX_DMA_THIS s[i].chan[c].base_count = 0;
-      BX_DMA_THIS s[i].chan[c].current_count = 0;
-      BX_DMA_THIS s[i].chan[c].page_reg = 0;
-      BX_DMA_THIS s[i].chan[c].used = 0;
-      }
-    }
-  BX_DMA_THIS s[1].chan[0].used = 1; // cascade channel in use
-  BX_INFO(("channel 4 used by cascade"));
-  bios_init();
-}
-
-/* Remove it when guest fw ready*/
-  void
-bx_dma_c::bios_init(void){
-  BX_DMA_THIS s[1].mask[0] = 0; // unmask cascade channel  
-  BX_DMA_THIS s[1].chan[0].mode.mode_type = 3; // cascade mode for channel 4
-}
-
-  void
-bx_dma_c::reset(unsigned type)
-{
-  reset_controller(0);
-  reset_controller(1);
-  bios_init();
-}
-
-  void
-bx_dma_c::reset_controller(unsigned num)
-{
-  BX_DMA_THIS s[num].mask[0] = 1;
-  BX_DMA_THIS s[num].mask[1] = 1;
-  BX_DMA_THIS s[num].mask[2] = 1;
-  BX_DMA_THIS s[num].mask[3] = 1;
-  BX_DMA_THIS s[num].command_reg = 0;
-  BX_DMA_THIS s[num].status_reg = 0;
-  BX_DMA_THIS s[num].request_reg = 0;
-  BX_DMA_THIS s[num].temporary_reg = 0;
-  BX_DMA_THIS s[num].flip_flop = 0;
-}
-
-  // index to find channel from register number (only [0],[1],[2],[6] used)
-  Bit8u channelindex[7] = {2, 3, 1, 0, 0, 0, 0};
-
-
-  // static IO port read callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-  Bit32u
-bx_dma_c::read_handler(void *this_ptr, Bit32u address, unsigned io_len)
-{
-#if !BX_USE_DMA_SMF
-  bx_dma_c *class_ptr = (bx_dma_c *) this_ptr;
-
-  return( class_ptr->read(address, io_len) );
-}
-
-  /* 8237 DMA controller */
-  Bit32u BX_CPP_AttrRegparmN(2)
-bx_dma_c::read( Bit32u   address, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif  // !BX_USE_DMA_SMF
-
-  Bit8u retval;
-  Bit8u channel;
-  bx_bool ma_sl;
-
-  BX_DEBUG(("read addr=%04x", (unsigned) address));
-
-#if BX_DMA_FLOPPY_IO < 1
-  /* if we're not supporting DMA/floppy IO just return a bogus value */
-  return(0xff);
-#endif
-
-  switch (address) {
-    case 0x00: /* DMA-1 current address, channel 0 */
-    case 0x02: /* DMA-1 current address, channel 1 */
-    case 0x04: /* DMA-1 current address, channel 2 */
-    case 0x06: /* DMA-1 current address, channel 3 */
-    case 0xc0: /* DMA-2 current address, channel 0 */
-    case 0xc4: /* DMA-2 current address, channel 1 */
-    case 0xc8: /* DMA-2 current address, channel 2 */
-    case 0xcc: /* DMA-2 current address, channel 3 */
-      ma_sl = (address >= 0xc0);
-      channel = (address >> (1 + ma_sl)) & 0x03;
-      if (BX_DMA_THIS s[ma_sl].flip_flop==0) {
-        BX_DMA_THIS s[ma_sl].flip_flop = !BX_DMA_THIS s[ma_sl].flip_flop;
-        return(BX_DMA_THIS s[ma_sl].chan[channel].current_address & 0xff);
-        }
-      else {
-        BX_DMA_THIS s[ma_sl].flip_flop = !BX_DMA_THIS s[ma_sl].flip_flop;
-        return(BX_DMA_THIS s[ma_sl].chan[channel].current_address >> 8);
-        }
-
-    case 0x01: /* DMA-1 current count, channel 0 */
-    case 0x03: /* DMA-1 current count, channel 1 */
-    case 0x05: /* DMA-1 current count, channel 2 */
-    case 0x07: /* DMA-1 current count, channel 3 */
-    case 0xc2: /* DMA-2 current count, channel 0 */
-    case 0xc6: /* DMA-2 current count, channel 1 */
-    case 0xca: /* DMA-2 current count, channel 2 */
-    case 0xce: /* DMA-2 current count, channel 3 */
-      ma_sl = (address >= 0xc2);
-      channel = (address >> (1 + ma_sl)) & 0x03;
-      if (BX_DMA_THIS s[ma_sl].flip_flop==0) {
-        BX_DMA_THIS s[ma_sl].flip_flop = !BX_DMA_THIS s[ma_sl].flip_flop;
-        return(BX_DMA_THIS s[ma_sl].chan[channel].current_count & 0xff);
-        }
-      else {
-        BX_DMA_THIS s[ma_sl].flip_flop = !BX_DMA_THIS s[ma_sl].flip_flop;
-        return(BX_DMA_THIS s[ma_sl].chan[channel].current_count >> 8);
-        }
-
-    case 0x08: // DMA-1 Status Register
-    case 0xd0: // DMA-2 Status Register
-      // bit 7: 1 = channel 3 request
-      // bit 6: 1 = channel 2 request
-      // bit 5: 1 = channel 1 request
-      // bit 4: 1 = channel 0 request
-      // bit 3: 1 = channel 3 has reached terminal count
-      // bit 2: 1 = channel 2 has reached terminal count
-      // bit 1: 1 = channel 1 has reached terminal count
-      // bit 0: 1 = channel 0 has reached terminal count
-      // reading this register clears lower 4 bits (hold flags)
-      ma_sl = (address == 0xd0);
-      retval = BX_DMA_THIS s[ma_sl].status_reg;
-      BX_DMA_THIS s[ma_sl].status_reg &= 0xf0;
-      return(retval);
-      break;
-    case 0x0d: // DMA-1: temporary register
-    case 0xda: // DMA-2: temporary register
-      ma_sl = (address == 0xda);
-      BX_ERROR(("DMA-%d: read of temporary register", ma_sl+1));
-      // Note: write to 0x0D clears temporary register
-      return(0);
-      break;
-
-    case 0x0081: // DMA-1 page register, channel 2
-    case 0x0082: // DMA-1 page register, channel 3
-    case 0x0083: // DMA-1 page register, channel 1
-    case 0x0087: // DMA-1 page register, channel 0
-      channel = channelindex[address - 0x81];
-      return( BX_DMA_THIS s[0].chan[channel].page_reg );
-
-    case 0x0089: // DMA-2 page register, channel 2
-    case 0x008a: // DMA-2 page register, channel 3
-    case 0x008b: // DMA-2 page register, channel 1
-    case 0x008f: // DMA-2 page register, channel 0
-      channel = channelindex[address - 0x89];
-      return( BX_DMA_THIS s[1].chan[channel].page_reg );
-
-    case 0x0084:
-    case 0x0085:
-    case 0x0086:
-    case 0x0088:
-    case 0x008c:
-    case 0x008d:
-    case 0x008e:
-      BX_DEBUG(("read: extra page register 0x%04x unsupported", (unsigned) address));
-      return(0);
-
-    default:
-      BX_ERROR(("read: unsupported address=%04x", (unsigned) address));
-      return(0);
-    }
-}
-
-
-  // static IO port write callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-  void
-bx_dma_c::write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len)
-{
-#if !BX_USE_DMA_SMF
-  bx_dma_c *class_ptr = (bx_dma_c *) this_ptr;
-
-  class_ptr->write(address, value, io_len);
-}
-
-
-  /* 8237 DMA controller */
-  void BX_CPP_AttrRegparmN(3)
-bx_dma_c::write(Bit32u   address, Bit32u   value, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif  // !BX_USE_DMA_SMF
-  Bit8u set_mask_bit;
-  Bit8u channel;
-  bx_bool ma_sl;
-
-  if (io_len > 1) {
-    if ( (io_len == 2) && (address == 0x0b) ) {
-#if BX_USE_DMA_SMF
-      BX_DMA_THIS write_handler(NULL, address,   value & 0xff, 1);
-      BX_DMA_THIS write_handler(NULL, address+1, value >> 8,   1);
-#else
-      BX_DMA_THIS write(address,   value & 0xff, 1);
-      BX_DMA_THIS write(address+1, value >> 8,   1);
-#endif
-      return;
-      }
-
-    BX_ERROR(("io write to address %08x, len=%u",
-             (unsigned) address, (unsigned) io_len));
-    return;
-    }
-
-  BX_DEBUG(("write: address=%04x value=%02x",
-      (unsigned) address, (unsigned) value));
-
-#if BX_DMA_FLOPPY_IO < 1
-  /* if we're not supporting DMA/floppy IO just return */
-  return;
-#endif
-
-  switch (address) {
-    case 0x00:
-    case 0x02:
-    case 0x04:
-    case 0x06:
-    case 0xc0:
-    case 0xc4:
-    case 0xc8:
-    case 0xcc:
-      ma_sl = (address >= 0xc0);
-      channel = (address >> (1 + ma_sl)) & 0x03;
-      BX_DEBUG(("  DMA-%d base and current address, channel %d", ma_sl+1, channel));
-      if (BX_DMA_THIS s[ma_sl].flip_flop==0) { /* 1st byte */
-        BX_DMA_THIS s[ma_sl].chan[channel].base_address = value;
-        BX_DMA_THIS s[ma_sl].chan[channel].current_address = value;
-        }
-      else { /* 2nd byte */
-        BX_DMA_THIS s[ma_sl].chan[channel].base_address |= (value << 8);
-        BX_DMA_THIS s[ma_sl].chan[channel].current_address |= (value << 8);
-        BX_DEBUG(("    base = %04x",
-            (unsigned) BX_DMA_THIS s[ma_sl].chan[channel].base_address));
-        BX_DEBUG(("    curr = %04x",
-            (unsigned) BX_DMA_THIS s[ma_sl].chan[channel].current_address));
-        }
-      BX_DMA_THIS s[ma_sl].flip_flop = !BX_DMA_THIS s[ma_sl].flip_flop;
-      return;
-      break;
-
-    case 0x01:
-    case 0x03:
-    case 0x05:
-    case 0x07:
-    case 0xc2:
-    case 0xc6:
-    case 0xca:
-    case 0xce:
-      ma_sl = (address >= 0xc2);
-      channel = (address >> (1 + ma_sl)) & 0x03;
-      BX_DEBUG(("  DMA-%d base and current count, channel %d", ma_sl+1, channel));
-      if (BX_DMA_THIS s[ma_sl].flip_flop==0) { /* 1st byte */
-        BX_DMA_THIS s[ma_sl].chan[channel].base_count = value;
-        BX_DMA_THIS s[ma_sl].chan[channel].current_count = value;
-        }
-      else { /* 2nd byte */
-        BX_DMA_THIS s[ma_sl].chan[channel].base_count |= (value << 8);
-        BX_DMA_THIS s[ma_sl].chan[channel].current_count |= (value << 8);
-        BX_DEBUG(("    base = %04x",
-            (unsigned) BX_DMA_THIS s[ma_sl].chan[channel].base_count));
-        BX_DEBUG(("    curr = %04x",
-            (unsigned) BX_DMA_THIS s[ma_sl].chan[channel].current_count));
-        }
-      BX_DMA_THIS s[ma_sl].flip_flop = !BX_DMA_THIS s[ma_sl].flip_flop;
-      return;
-      break;
-
-    case 0x08: /* DMA-1: command register */
-    case 0xd0: /* DMA-2: command register */
-      ma_sl = (address == 0xd0);
-      if (value != 0x00)
-        BX_ERROR(("write to command register: value(%02xh) not 0x00",
-          (unsigned) value));
-      BX_DMA_THIS s[ma_sl].command_reg = value;
-      return;
-      break;
-
-    case 0x09: // DMA-1: request register
-    case 0xd2: // DMA-2: request register
-      ma_sl = (address == 0xd2);
-      channel = value & 0x03;
-      BX_ERROR(("DMA-%d: write to request register (%02x)", ma_sl+1, (unsigned) value));
-      // note: write to 0x0d clears this register
-      if (value & 0x04) {
-        // set request bit
-        BX_DMA_THIS s[ma_sl].status_reg |= (1 << (channel+4));
-        BX_DEBUG(("DMA-%d: set request bit for channel %u", ma_sl+1, (unsigned) channel));
-        }
-      else {
-        // clear request bit
-        BX_DMA_THIS s[ma_sl].status_reg &= ~(1 << (channel+4));
-        BX_DEBUG(("DMA-%d: cleared request bit for channel %u", ma_sl+1, (unsigned) channel));
-        }
-      control_HRQ(ma_sl);
-      return;
-      break;
-
-    case 0x0a:
-    case 0xd4:
-      ma_sl = (address == 0xd4);
-      set_mask_bit = value & 0x04;
-      channel = value & 0x03;
-      BX_DMA_THIS s[ma_sl].mask[channel] = (set_mask_bit > 0);
-      BX_DEBUG(("DMA-%d: set_mask_bit=%u, channel=%u, mask now=%02xh", ma_sl+1,
-          (unsigned) set_mask_bit, (unsigned) channel, (unsigned) BX_DMA_THIS s[ma_sl].mask[channel]));
-      control_HRQ(ma_sl);
-      return;
-      break;
-
-    case 0x0b: /* DMA-1 mode register */
-    case 0xd6: /* DMA-2 mode register */
-      ma_sl = (address == 0xd6);
-      channel = value & 0x03;
-      BX_DMA_THIS s[ma_sl].chan[channel].mode.mode_type = (value >> 6) & 0x03;
-      BX_DMA_THIS s[ma_sl].chan[channel].mode.address_decrement = (value >> 5) & 0x01;
-      BX_DMA_THIS s[ma_sl].chan[channel].mode.autoinit_enable = (value >> 4) & 0x01;
-      BX_DMA_THIS s[ma_sl].chan[channel].mode.transfer_type = (value >> 2) & 0x03;
-      BX_DEBUG(("DMA-%d: mode register[%u] = %02x", ma_sl+1,
-          (unsigned) channel, (unsigned) value));
-      return;
-      break;
-
-    case 0x0c: /* DMA-1 clear byte flip/flop */
-    case 0xd8: /* DMA-2 clear byte flip/flop */
-      ma_sl = (address == 0xd8);
-      BX_DEBUG(("DMA-%d: clear flip/flop", ma_sl+1));
-      BX_DMA_THIS s[ma_sl].flip_flop = 0;
-      return;
-      break;
-
-    case 0x0d: // DMA-1: master clear
-    case 0xda: // DMA-2: master clear
-      ma_sl = (address == 0xda);
-      BX_DEBUG(("DMA-%d: master clear", ma_sl+1));
-      // writing any value to this port resets DMA controller 1 / 2
-      // same action as a hardware reset
-      // mask register is set (chan 0..3 disabled)
-      // command, status, request, temporary, and byte flip-flop are all cleared
-      reset_controller(ma_sl);
-      return;
-      break;
-
-    case 0x0e: // DMA-1: clear mask register
-    case 0xdc: // DMA-2: clear mask register
-      ma_sl = (address == 0xdc);
-      BX_DEBUG(("DMA-%d: clear mask register", ma_sl+1));
-      BX_DMA_THIS s[ma_sl].mask[0] = 0;
-      BX_DMA_THIS s[ma_sl].mask[1] = 0;
-      BX_DMA_THIS s[ma_sl].mask[2] = 0;
-      BX_DMA_THIS s[ma_sl].mask[3] = 0;
-      control_HRQ(ma_sl);
-      return;
-      break;
-
-    case 0x0f: // DMA-1: write all mask bits
-    case 0xde: // DMA-2: write all mask bits
-      ma_sl = (address == 0xde);
-      BX_DEBUG(("DMA-%d: write all mask bits", ma_sl+1));
-      BX_DMA_THIS s[ma_sl].mask[0] = value & 0x01; value >>= 1;
-      BX_DMA_THIS s[ma_sl].mask[1] = value & 0x01; value >>= 1;
-      BX_DMA_THIS s[ma_sl].mask[2] = value & 0x01; value >>= 1;
-      BX_DMA_THIS s[ma_sl].mask[3] = value & 0x01;
-      control_HRQ(ma_sl);
-      return;
-      break;
-
-    case 0x81: /* DMA-1 page register, channel 2 */
-    case 0x82: /* DMA-1 page register, channel 3 */
-    case 0x83: /* DMA-1 page register, channel 1 */
-    case 0x87: /* DMA-1 page register, channel 0 */
-      /* address bits A16-A23 for DMA channel */
-      channel = channelindex[address - 0x81];
-      BX_DMA_THIS s[0].chan[channel].page_reg = value;
-      BX_DEBUG(("DMA-1: page register %d = %02x", channel, (unsigned) value));
-      return;
-      break;
-
-    case 0x89: /* DMA-2 page register, channel 2 */
-    case 0x8a: /* DMA-2 page register, channel 3 */
-    case 0x8b: /* DMA-2 page register, channel 1 */
-    case 0x8f: /* DMA-2 page register, channel 0 */
-      /* address bits A16-A23 for DMA channel */
-      channel = channelindex[address - 0x89];
-      BX_DMA_THIS s[1].chan[channel].page_reg = value;
-      BX_DEBUG(("DMA-2: page register %d = %02x", channel + 4, (unsigned) value));
-      return;
-      break;
-
-    case 0x0084:
-    case 0x0085:
-    case 0x0086:
-    case 0x0088:
-    case 0x008c:
-    case 0x008d:
-    case 0x008e:
-      BX_DEBUG(("write: extra page register 0x%04x unsupported", (unsigned) address));
-      return;
-      break;
-
-    default:
-      BX_ERROR(("write ignored: %04xh = %02xh",
-        (unsigned) address, (unsigned) value));
-    }
-}
-
-  void
-bx_dma_c::set_DRQ(unsigned channel, bx_bool val)
-{
-  Bit32u dma_base, dma_roof;
-  bx_bool ma_sl;
-
-  if (channel > 7) {
-    BX_PANIC(("set_DRQ() channel > 7"));
-    return;
-  }
-  ma_sl = (channel > 3);
-  BX_DMA_THIS s[ma_sl].DRQ[channel & 0x03] = val;
-  if (!BX_DMA_THIS s[ma_sl].chan[channel & 0x03].used) {
-    BX_PANIC(("set_DRQ(): channel %d not connected to device", channel));
-    return;
-  }
-  channel &= 0x03;
-  if (!val) {
-    //BX_DEBUG(("bx_dma_c::DRQ(): val == 0"));
-    // clear bit in status reg
-    BX_DMA_THIS s[ma_sl].status_reg &= ~(1 << (channel+4));
-
-    control_HRQ(ma_sl);
-    return;
-  }
-
-#if 0
-  BX_INFO(("mask[%d]: %02x", channel, (unsigned) BX_DMA_THIS s[0].mask[channel]));
-  BX_INFO(("flip_flop: %u", (unsigned) BX_DMA_THIS s[0].flip_flop));
-  BX_INFO(("status_reg: %02x", (unsigned) BX_DMA_THIS s[0].status_reg));
-  BX_INFO(("mode_type: %02x", (unsigned) BX_DMA_THIS s[0].chan[channel].mode.mode_type));
-  BX_INFO(("address_decrement: %02x", (unsigned) BX_DMA_THIS s[0].chan[channel].mode.address_decrement));
-  BX_INFO(("autoinit_enable: %02x", (unsigned) BX_DMA_THIS s[0].chan[channel].mode.autoinit_enable));
-  BX_INFO(("transfer_type: %02x", (unsigned) BX_DMA_THIS s[0].chan[channel].mode.transfer_type));
-  BX_INFO(("base_address: %04x", (unsigned) BX_DMA_THIS s[0].chan[channel].base_address));
-  BX_INFO(("current_address: %04x", (unsigned) BX_DMA_THIS s[0].chan[channel].current_address));
-  BX_INFO(("base_count: %04x", (unsigned) BX_DMA_THIS s[0].chan[channel].base_count));
-  BX_INFO(("current_count: %04x", (unsigned) BX_DMA_THIS s[0].chan[channel].current_count));
-  BX_INFO(("page_reg: %02x", (unsigned) BX_DMA_THIS s[0].chan[channel].page_reg));
-#endif
-
-  BX_DMA_THIS s[ma_sl].status_reg |= (1 << (channel+4));
-
-  if ( (BX_DMA_THIS s[ma_sl].chan[channel].mode.mode_type != DMA_MODE_SINGLE) &&
-       (BX_DMA_THIS s[ma_sl].chan[channel].mode.mode_type != DMA_MODE_DEMAND) &&
-       (BX_DMA_THIS s[ma_sl].chan[channel].mode.mode_type != DMA_MODE_CASCADE) )
-    BX_PANIC(("set_DRQ: mode_type(%02x) not handled",
-      (unsigned) BX_DMA_THIS s[ma_sl].chan[channel].mode.mode_type));
-
-  dma_base = (BX_DMA_THIS s[ma_sl].chan[channel].page_reg << 16) |
-             (BX_DMA_THIS s[ma_sl].chan[channel].base_address << ma_sl);
-  if (BX_DMA_THIS s[ma_sl].chan[channel].mode.address_decrement==0) {
-    dma_roof = dma_base + (BX_DMA_THIS s[ma_sl].chan[channel].base_count << ma_sl);
-  } else {
-    dma_roof = dma_base - (BX_DMA_THIS s[ma_sl].chan[channel].base_count << ma_sl);
-  }
-  if ( (dma_base & (0x7fff0000 << ma_sl)) != (dma_roof & (0x7fff0000 << ma_sl)) ) {
-    BX_INFO(("dma_base = %08x", (unsigned) dma_base));
-    BX_INFO(("dma_base_count = %08x", (unsigned) BX_DMA_THIS s[ma_sl].chan[channel].base_count));
-    BX_INFO(("dma_roof = %08x", (unsigned) dma_roof));
-    BX_PANIC(("request outside %dk boundary", 64 << ma_sl));
-  }
-
-  control_HRQ(ma_sl);
-}
-
-  void
-bx_dma_c::control_HRQ(bx_bool ma_sl)
-{
-  unsigned channel;
-
-  // deassert HRQ if no DRQ is pending
-  if ((BX_DMA_THIS s[ma_sl].status_reg & 0xf0) == 0) {
-    if (ma_sl) {
-      bx_pc_system.set_HRQ(0);
-    } else {
-      BX_DMA_THIS set_DRQ(4, 0);
-    }
-    return;
-  }
-  // find highest priority channel
-  for (channel=0; channel<4; channel++) {
-    if ( (BX_DMA_THIS s[ma_sl].status_reg & (1 << (channel+4))) &&
-         (BX_DMA_THIS s[ma_sl].mask[channel]==0) ) {
-      if (ma_sl) {
-        // assert Hold ReQuest line to CPU
-        bx_pc_system.set_HRQ(1);
-      } else {
-        // send DRQ to cascade channel of the master
-        BX_DMA_THIS set_DRQ(4, 1);
-      }
-      break;
-    }
-  }
-}
-
-  void
-bx_dma_c::raise_HLDA(void)
-{
-  unsigned channel;
-  Bit32u phy_addr;
-  bx_bool count_expired = 0;
-  bx_bool ma_sl = 0;
-
-  BX_DMA_THIS HLDA = 1;
-  // find highest priority channel
-  for (channel=0; channel<4; channel++) {
-    if ( (BX_DMA_THIS s[1].status_reg & (1 << (channel+4))) &&
-         (BX_DMA_THIS s[1].mask[channel]==0) ) {
-      ma_sl = 1;
-      break;
-      }
-    }
-  if (channel == 0) { // master cascade channel
-    BX_DMA_THIS s[1].DACK[0] = 1;
-    for (channel=0; channel<4; channel++) {
-      if ( (BX_DMA_THIS s[0].status_reg & (1 << (channel+4))) &&
-           (BX_DMA_THIS s[0].mask[channel]==0) ) {
-        ma_sl = 0;
-        break;
-        }
-      }
-    }
-  if (channel >= 4) {
-    // wait till they're unmasked
-    return;
-    }
-
-  //BX_DEBUG(("hlda: OK in response to DRQ(%u)", (unsigned) channel));
-  phy_addr = (BX_DMA_THIS s[ma_sl].chan[channel].page_reg << 16) |
-             (BX_DMA_THIS s[ma_sl].chan[channel].current_address << ma_sl);
-
-  BX_DMA_THIS s[ma_sl].DACK[channel] = 1;
-  // check for expiration of count, so we can signal TC and DACK(n)
-  // at the same time.
-  if (BX_DMA_THIS s[ma_sl].chan[channel].mode.address_decrement==0)
-    BX_DMA_THIS s[ma_sl].chan[channel].current_address++;
-  else
-    BX_DMA_THIS s[ma_sl].chan[channel].current_address--;
-  BX_DMA_THIS s[ma_sl].chan[channel].current_count--;
-  if (BX_DMA_THIS s[ma_sl].chan[channel].current_count == 0xffff) {
-    // count expired, done with transfer
-    // assert TC, deassert HRQ & DACK(n) lines
-    BX_DMA_THIS s[ma_sl].status_reg |= (1 << channel); // hold TC in status reg
-    BX_DMA_THIS TC = 1;
-    count_expired = 1;
-    if (BX_DMA_THIS s[ma_sl].chan[channel].mode.autoinit_enable == 0) {
-      // set mask bit if not in autoinit mode
-      BX_DMA_THIS s[ma_sl].mask[channel] = 1;
-      }
-    else {
-      // count expired, but in autoinit mode
-      // reload count and base address
-      BX_DMA_THIS s[ma_sl].chan[channel].current_address =
-        BX_DMA_THIS s[ma_sl].chan[channel].base_address;
-      BX_DMA_THIS s[ma_sl].chan[channel].current_count =
-        BX_DMA_THIS s[ma_sl].chan[channel].base_count;
-      }
-    }
-
-  Bit8u data_byte;
-  Bit16u data_word;
-
-  if (BX_DMA_THIS s[ma_sl].chan[channel].mode.transfer_type == 1) { // write
-    // DMA controlled xfer of byte from I/O to Memory
-
-    if (!ma_sl) {
-      if (BX_DMA_THIS h[channel].dmaWrite8)
-        BX_DMA_THIS h[channel].dmaWrite8(&data_byte);
-      else
-        BX_PANIC(("no dmaWrite handler for channel %u.", channel));
-
-      BX_MEM_WRITE_PHYSICAL(phy_addr, 1, &data_byte);
-
-      BX_DBG_DMA_REPORT(phy_addr, 1, BX_WRITE, data_byte);
-      }
-    else {
-      if (BX_DMA_THIS h[channel].dmaWrite16)
-        BX_DMA_THIS h[channel].dmaWrite16(&data_word);
-      else
-        BX_PANIC(("no dmaWrite handler for channel %u.", channel));
-
-      BX_MEM_WRITE_PHYSICAL(phy_addr, 2, &data_word);
-
-      BX_DBG_DMA_REPORT(phy_addr, 2, BX_WRITE, data_word);
-      }
-    }
-  else if (BX_DMA_THIS s[ma_sl].chan[channel].mode.transfer_type == 2) { // read
-    // DMA controlled xfer of byte from Memory to I/O
-
-    if (!ma_sl) {
-      BX_MEM_READ_PHYSICAL(phy_addr, 1, &data_byte);
-
-      if (BX_DMA_THIS h[channel].dmaRead8)
-        BX_DMA_THIS h[channel].dmaRead8(&data_byte);
-
-      BX_DBG_DMA_REPORT(phy_addr, 1, BX_READ, data_byte);
-      }
-    else {
-      BX_MEM_READ_PHYSICAL(phy_addr, 2, &data_word);
-
-      if (BX_DMA_THIS h[channel].dmaRead16)
-        BX_DMA_THIS h[channel].dmaRead16(&data_word);
-
-      BX_DBG_DMA_REPORT(phy_addr, 2, BX_READ, data_word);
-      }
-    }
-  else if (BX_DMA_THIS s[ma_sl].chan[channel].mode.transfer_type == 0) {
-    // verify
-
-    if (!ma_sl) {
-      if (BX_DMA_THIS h[channel].dmaWrite8)
-        BX_DMA_THIS h[channel].dmaWrite8(&data_byte);
-      else
-        BX_PANIC(("no dmaWrite handler for channel %u.", channel));
-      }
-    else {
-      if (BX_DMA_THIS h[channel].dmaWrite16)
-        BX_DMA_THIS h[channel].dmaWrite16(&data_word);
-      else
-        BX_PANIC(("no dmaWrite handler for channel %u.", channel));
-      }
-    }
-  else {
-    BX_PANIC(("hlda: transfer_type 3 is undefined"));
-    }
-
-  if (count_expired) {
-    BX_DMA_THIS TC = 0;            // clear TC, adapter card already notified
-    BX_DMA_THIS HLDA = 0;
-    bx_pc_system.set_HRQ(0);           // clear HRQ to CPU
-    BX_DMA_THIS s[ma_sl].DACK[channel] = 0; // clear DACK to adapter card
-    if (!ma_sl) {
-      BX_DMA_THIS set_DRQ(4, 0); // clear DRQ to cascade
-      BX_DMA_THIS s[1].DACK[0] = 0; // clear DACK to cascade
-      }
-    }
-}
diff --git a/tools/ioemu/iodev/dma.h b/tools/ioemu/iodev/dma.h
deleted file mode 100644 (file)
index 9f6c4eb..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: dma.h,v 1.15 2003/05/03 07:41:27 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-#ifndef _PCDMA_H
-#define _PCDMA_H
-
-
-#if BX_USE_DMA_SMF
-#  define BX_DMA_SMF  static
-#  define BX_DMA_THIS theDmaDevice->
-#else
-#  define BX_DMA_SMF
-#  define BX_DMA_THIS this->
-#endif
-
-
-
-class bx_dma_c : public bx_dma_stub_c {
-public:
-
-  bx_dma_c();
-  ~bx_dma_c(void);
-
-  virtual void     init(void);
-  virtual void     bios_init(void);
-  virtual void     reset(unsigned type);
-  virtual void     raise_HLDA(void);
-  virtual void     set_DRQ(unsigned channel, bx_bool val);
-  virtual unsigned get_TC(void);
-
-  virtual unsigned registerDMA8Channel(unsigned channel,
-    void (* dmaRead)(Bit8u *data_byte),
-    void (* dmaWrite)(Bit8u *data_byte),
-    const char *name);
-  virtual unsigned registerDMA16Channel(unsigned channel,
-    void (* dmaRead)(Bit16u *data_word),
-    void (* dmaWrite)(Bit16u *data_word),
-    const char *name);
-  virtual unsigned unregisterDMAChannel(unsigned channel);
-
-private:
-
-  static Bit32u read_handler(void *this_ptr, Bit32u address, unsigned io_len);
-  static void   write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);
-#if !BX_USE_DMA_SMF
-  Bit32u   read( Bit32u   address, unsigned io_len) BX_CPP_AttrRegparmN(2);
-  void     write(Bit32u   address, Bit32u   value, unsigned io_len) BX_CPP_AttrRegparmN(3);
-#endif
-  BX_DMA_SMF void control_HRQ(bx_bool ma_sl);
-  BX_DMA_SMF void reset_controller(unsigned num);
-
-  struct {
-    bx_bool DRQ[4];  // DMA Request
-    bx_bool DACK[4]; // DMA Acknowlege
-
-    bx_bool mask[4];
-    bx_bool flip_flop;
-    Bit8u   status_reg;
-    Bit8u   command_reg;
-    Bit8u   request_reg;
-    Bit8u   temporary_reg;
-    struct {
-      struct {
-        Bit8u mode_type;
-        Bit8u address_decrement;
-        Bit8u autoinit_enable;
-        Bit8u transfer_type;
-        } mode;
-      Bit16u  base_address;
-      Bit16u  current_address;
-      Bit16u  base_count;
-      Bit16u  current_count;
-      Bit8u   page_reg;
-      bx_bool used;
-      } chan[4]; /* DMA channels 0..3 */
-    } s[2];  // state information DMA-1 / DMA-2
-
-  bx_bool HLDA;    // Hold Acknowlege
-  bx_bool TC;      // Terminal Count
-
-  struct {
-    void (* dmaRead8)(Bit8u *data_byte);
-    void (* dmaWrite8)(Bit8u *data_byte);
-    void (* dmaRead16)(Bit16u *data_word);
-    void (* dmaWrite16)(Bit16u *data_word);
-    } h[4]; // DMA read and write handlers
-
-  };
-
-#endif  // #ifndef _PCDMA_H
diff --git a/tools/ioemu/iodev/eth.cc b/tools/ioemu/iodev/eth.cc
deleted file mode 100644 (file)
index d6ee9d2..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: eth.cc,v 1.16 2003/04/28 13:01:09 cbothamy Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2001  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-// eth.cc  - helper code to find and create pktmover classes
-
-// Peter Grehan (grehan@iprg.nokia.com) coded all of this
-// NE2000/ether stuff.
-
-// Define BX_PLUGGABLE in files that can be compiled into plugins.  For
-// platforms that require a special tag on exported symbols, BX_PLUGGABLE 
-// is used to know when we are exporting symbols and when we are importing.
-#define BX_PLUGGABLE
-#include "bochs.h"
-#if BX_NE2K_SUPPORT
-
-#define LOG_THIS /* not needed */
-
-eth_locator_c *eth_locator_c::all;
-
-//
-// Each pktmover module has a static locator class that registers
-// here 
-//
-eth_locator_c::eth_locator_c(const char *type)
-{
-  next = all;
-  all  = this;
-  this->type = type;
-}
-
-#ifdef ETH_NULL
-extern class bx_null_locator_c bx_null_match;
-#endif
-#ifdef ETH_FBSD
-extern class bx_fbsd_locator_c bx_fbsd_match;
-#endif
-#ifdef ETH_LINUX
-extern class bx_linux_locator_c bx_linux_match;
-#endif
-#ifdef ETH_WIN32
-extern class bx_win32_locator_c bx_win32_match;
-#endif
-#if HAVE_ETHERTAP
-extern class bx_tap_locator_c bx_tap_match;
-#endif
-#if HAVE_TUNTAP
-extern class bx_tuntap_locator_c bx_tuntap_match;
-#endif
-#ifdef ETH_TEST
-extern bx_test_match;
-#endif
-#ifdef ETH_ARPBACK
-extern class bx_arpback_locator_c bx_arpback_match;
-#endif
-
-//
-// Called by ethernet chip emulations to locate and create a pktmover
-// object
-//
-eth_pktmover_c *
-eth_locator_c::create(const char *type, const char *netif,
-                     const char *macaddr,
-                     eth_rx_handler_t rxh, void *rxarg)
-{
-#ifdef eth_static_constructors
-  for (eth_locator_c *p = all; p != NULL; p = p->next) {
-    if (strcmp(type, p->type) == 0)
-      return (p->allocate(netif, macaddr, rxh, rxarg));
-  }
-#else
-  eth_locator_c *ptr = 0;
-
-#ifdef ETH_ARPBACK
-  {
-    if (!strcmp(type, "arpback"))
-      ptr = (eth_locator_c *) &bx_arpback_match;
-  }
-#endif
-#ifdef ETH_NULL
-  {
-    if (!strcmp(type, "null"))
-      ptr = (eth_locator_c *) &bx_null_match; 
-  }
-#endif
-#ifdef ETH_FBSD
-  {
-    if (!strcmp(type, "fbsd"))    
-      ptr = (eth_locator_c *) &bx_fbsd_match;
-  }
-#endif
-#ifdef ETH_LINUX
-  {
-    if (!strcmp(type, "linux"))    
-      ptr = (eth_locator_c *) &bx_linux_match;
-  }
-#endif
-#if HAVE_TUNTAP
-  {
-    if (!strcmp(type, "tuntap"))    
-      ptr = (eth_locator_c *) &bx_tuntap_match;
-  }
-#endif
-#if HAVE_ETHERTAP
-  {
-    if (!strcmp(type, "tap"))    
-      ptr = (eth_locator_c *) &bx_tap_match;
-  }
-#endif
-#ifdef ETH_WIN32
-  {
-    if(!strcmp(type, "win32"))
-      ptr = (eth_locator_c *) &bx_win32_match;
-  }
-#endif
-#ifdef ETH_TEST
-  {
-    if (!strcmp(type, "test"))    
-      ptr = (eth_locator_c *) &bx_test_match;
-  }
-#endif
-  if (ptr)
-    return (ptr->allocate(netif, macaddr, rxh, rxarg));
-#endif
-
-  return (NULL);
-}
-
-#if (HAVE_ETHERTAP==1) || (HAVE_TUNTAP==1)
-
-extern "C" {
-#include <sys/wait.h>
-};
-
-#undef LOG_THIS
-#define LOG_THIS bx_devices.pluginNE2kDevice->
-
-// This is a utility script used for tuntap or ethertap
-int execute_script( char* scriptname, char* arg1 )
-{
-  int pid,status;
-
-  if (!(pid=fork())) {
-    char filename[BX_PATHNAME_LEN];
-    if ( scriptname[0]=='/' ) {
-      strcpy (filename, scriptname);
-    }
-    else {
-      getcwd (filename, BX_PATHNAME_LEN);
-      strcat (filename, "/");
-      strcat (filename, scriptname);
-    }
-
-    // execute the script
-    BX_INFO(("Executing script '%s %s'",filename,arg1));
-    execle(filename, scriptname, arg1, NULL, NULL);
-
-    // if we get here there has been a problem
-    exit(-1);
-  }
-
-  wait (&status);
-  if (!WIFEXITED(status)) {
-    return -1;
-  }
-  return WEXITSTATUS(status);
-}
-
-#endif // (HAVE_ETHERTAP==1) || (HAVE_TUNTAP==1)
-
-#endif /* if BX_NE2K_SUPPORT */
diff --git a/tools/ioemu/iodev/eth.h b/tools/ioemu/iodev/eth.h
deleted file mode 100644 (file)
index 8ac8c6f..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: eth.h,v 1.12 2003/04/26 14:48:45 cbothamy Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2001  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-// Peter Grehan (grehan@iprg.nokia.com) coded all of this
-// NE2000/ether stuff.
-
-//  eth.h  - see eth_null.cc for implementation details
-
-typedef void (*eth_rx_handler_t)(void *arg, const void *buf, unsigned len);
-
-int execute_script(char *name, char* arg1);
-
-//
-//  The eth_pktmover class is used by ethernet chip emulations
-// to interface to the outside world. An instance of this
-// would allow frames to be sent to and received from some
-// entity. An example would be the packet filter on a Unix
-// system, an NDIS driver in promisc mode on WinNT, or maybe
-// a simulated network that talks to another process.
-//
-class eth_pktmover_c {
-public:
-  virtual void sendpkt(void *buf, unsigned io_len) = 0;
-  virtual ~eth_pktmover_c (void) {}
-protected:
-  eth_rx_handler_t  rxh;   // receive callback
-  void *rxarg;
-};
-
-
-//
-//  The eth_locator class is used by pktmover classes to register
-// their name. Chip emulations use the static 'create' method
-// to locate and instantiate a pktmover class.
-//
-class eth_locator_c {
-public:
-  static eth_pktmover_c *create(const char *type, const char *netif,
-                               const char *macaddr,
-                               eth_rx_handler_t rxh, 
-                               void *rxarg);
-protected:
-  eth_locator_c(const char *type);
-  virtual eth_pktmover_c *allocate(const char *netif,
-                               const char *macaddr,
-                               eth_rx_handler_t rxh, 
-                               void *rxarg) = 0;
-private:
-  static eth_locator_c *all;
-  eth_locator_c *next;
-  const char *type;
-};
-
diff --git a/tools/ioemu/iodev/eth_arpback.cc b/tools/ioemu/iodev/eth_arpback.cc
deleted file mode 100644 (file)
index 0f30711..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: eth_arpback.cc,v 1.11 2002/11/20 19:06:22 bdenney Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2001  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-// eth_arpback.cc  - basic ethernet packetmover, only responds to ARP
-
-// Various networking docs:
-// http://www.graphcomp.com/info/rfc/
-// rfc0826: arp
-// rfc0903: rarp
-
-// Define BX_PLUGGABLE in files that can be compiled into plugins.  For
-// platforms that require a special tag on exported symbols, BX_PLUGGABLE 
-// is used to know when we are exporting symbols and when we are importing.
-#define BX_PLUGGABLE
-#include "bochs.h"
-
-#if BX_NE2K_SUPPORT && defined(ETH_ARPBACK)
-
-#include "crc32.h"
-#include "eth_packetmaker.h"
-#define LOG_THIS bx_devices.pluginNE2kDevice->
-
-
-//static const Bit8u external_mac[]={0xB0, 0xC4, 0x20, 0x20, 0x00, 0x00, 0x00};
-//static const Bit8u internal_mac[]={0xB0, 0xC4, 0x20, 0x00, 0x00, 0x00, 0x00};
-//static const Bit8u external_ip[]={ 192, 168, 0, 2, 0x00 };
-//static const Bit8u broadcast_mac[]={0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00};
-//static const Bit8u ethtype_arp[]={0x08, 0x06, 0x00};
-
-#define MAX_FRAME_SIZE 2048
-
-//
-//  Define the class. This is private to this module
-//
-class bx_arpback_pktmover_c : public eth_pktmover_c {
-public:
-  bx_arpback_pktmover_c(const char *netif, const char *macaddr,
-                    eth_rx_handler_t rxh,
-                    void *rxarg);
-  void sendpkt(void *buf, unsigned io_len);
-private:
-  int rx_timer_index;
-  static void rx_timer_handler(void *);
-  void rx_timer(void);
-  FILE *txlog, *txlog_txt;
-  //Bit8u arpbuf[MAX_FRAME_SIZE];
-  //Bit32u buflen;
-  //bx_bool bufvalid;
-  //CRC_Generator mycrc;
-  eth_ETHmaker packetmaker;
-};
-
-
-//
-//  Define the static class that registers the derived pktmover class,
-// and allocates one on request.
-//
-class bx_arpback_locator_c : public eth_locator_c {
-public:
-  bx_arpback_locator_c(void) : eth_locator_c("arpback") {}
-protected:
-  eth_pktmover_c *allocate(const char *netif, const char *macaddr,
-                          eth_rx_handler_t rxh,
-                          void *rxarg) {
-    return (new bx_arpback_pktmover_c(netif, macaddr, rxh, rxarg));
-  }
-} bx_arpback_match;
-
-
-//
-// Define the methods for the bx_arpback_pktmover derived class
-//
-
-// the constructor
-bx_arpback_pktmover_c::bx_arpback_pktmover_c(const char *netif, 
-                                      const char *macaddr,
-                                      eth_rx_handler_t rxh,
-                                      void *rxarg)
-{
-  this->rx_timer_index = 
-    bx_pc_system.register_timer(this, this->rx_timer_handler, 1000,
-                               1, 1, "eth_arpback"); // continuous, active
-  this->rxh   = rxh;
-  this->rxarg = rxarg;
-  //bufvalid=0;
-  packetmaker.init();
-#if BX_ETH_NULL_LOGGING
-  // Start the rx poll 
-  // eventually Bryce wants txlog to dump in pcap format so that
-  // tcpdump -r FILE can read it and interpret packets.
-  txlog = fopen ("ne2k-tx.log", "wb");
-  if (!txlog) BX_PANIC (("open ne2k-tx.log failed"));
-  txlog_txt = fopen ("ne2k-txdump.txt", "wb");
-  if (!txlog_txt) BX_PANIC (("open ne2k-txdump.txt failed"));
-  fprintf (txlog_txt, "arpback packetmover readable log file\n");
-  fprintf (txlog_txt, "net IF = %s\n", netif);
-  fprintf (txlog_txt, "MAC address = ");
-  for (int i=0; i<6; i++) 
-    fprintf (txlog_txt, "%02x%s", 0xff & macaddr[i], i<5?":" : "");
-  fprintf (txlog_txt, "\n--\n");
-  fflush (txlog_txt);
-#endif
-}
-
-void
-bx_arpback_pktmover_c::sendpkt(void *buf, unsigned io_len)
-{
-  if(io_len<MAX_FRAME_SIZE) {
-    eth_packet barney;
-    memcpy(barney.buf,buf,io_len);
-    barney.len=io_len;
-    if(packetmaker.ishandler(barney)) {
-      packetmaker.sendpacket(barney);
-    }
-    /*
-    if(( (!memcmp(buf, external_mac, 6)) || (!memcmp(buf, broadcast_mac, 6)) )
-       && (!memcmp(((Bit8u *)buf)+12, ethtype_arp, 2)) ) {
-      Bit32u tempcrc;
-      memcpy(arpbuf,buf,io_len); //move to temporary buffer
-      memcpy(arpbuf, arpbuf+6, 6); //set destination to sender
-      memcpy(arpbuf+6, external_mac, 6); //set sender to us
-      memcpy(arpbuf+32, arpbuf+22, 10); //move destination to sender
-      memcpy(arpbuf+22, external_mac, 6); //set sender to us
-      memcpy(arpbuf+28, external_ip, 4); //set sender to us
-      arpbuf[21]=2; //make this a reply and not a request
-      tempcrc=mycrc.get_CRC(arpbuf,io_len);
-      memcpy(arpbuf+io_len, &tempcrc, 4);
-      buflen=io_len;//+4
-      bufvalid=1;
-    }
-    */
-  }
-#if BX_ETH_NULL_LOGGING
-  BX_DEBUG (("sendpkt length %u", io_len));
-  // dump raw bytes to a file, eventually dump in pcap format so that
-  // tcpdump -r FILE can interpret them for us.
-  int n = fwrite (buf, io_len, 1, txlog);
-  if (n != 1) BX_ERROR (("fwrite to txlog failed", io_len));
-  // dump packet in hex into an ascii log file
-  fprintf (txlog_txt, "NE2K transmitting a packet, length %u\n", io_len);
-  Bit8u *charbuf = (Bit8u *)buf;
-  for (n=0; n<io_len; n++) {
-    if (((n % 16) == 0) && n>0)
-      fprintf (txlog_txt, "\n");
-    fprintf (txlog_txt, "%02x ", charbuf[n]);
-  }
-  fprintf (txlog_txt, "\n--\n");
-  // flush log so that we see the packets as they arrive w/o buffering
-  fflush (txlog);
-  fflush (txlog_txt);
-#endif
-}
-
-void bx_arpback_pktmover_c::rx_timer_handler (void * this_ptr)
-{
-#if BX_ETH_NULL_LOGGING
-  BX_DEBUG (("rx_timer_handler"));
-#endif
-  bx_arpback_pktmover_c *class_ptr = ((bx_arpback_pktmover_c *)this_ptr);
-
-  class_ptr->rx_timer();
-}
-
-void bx_arpback_pktmover_c::rx_timer (void)
-{
-  int nbytes = 0;
-  struct bpf_hdr *bhdr;
-  eth_packet rubble;
-  
-  if(packetmaker.getpacket(rubble)) {
-    //bufvalid=0;
-    void * buf=rubble.buf;
-    unsigned io_len=rubble.len;
-    Bit32u n;
-    fprintf (txlog_txt, "NE2K receiving a packet, length %u\n", io_len);
-    Bit8u *charbuf = (Bit8u *)buf;
-    for (n=0; n<io_len; n++) {
-      if (((n % 16) == 0) && n>0)
-       fprintf (txlog_txt, "\n");
-      fprintf (txlog_txt, "%02x ", charbuf[n]);
-    }
-    fprintf (txlog_txt, "\n--\n");
-    fflush (txlog_txt);
-
-    (*rxh)(rxarg, buf, io_len);
-  }
-}
-
-#endif /* if BX_NE2K_SUPPORT && defined(ETH_ARPBACK) */
-
diff --git a/tools/ioemu/iodev/eth_fbsd.cc b/tools/ioemu/iodev/eth_fbsd.cc
deleted file mode 100644 (file)
index 0c24b9b..0000000
+++ /dev/null
@@ -1,385 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: eth_fbsd.cc,v 1.26 2002/11/20 19:06:22 bdenney Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2001  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-// Peter Grehan (grehan@iprg.nokia.com) coded all of this
-// NE2000/ether stuff.
-
-// eth_fbsd.cc - A FreeBSD packet filter implementation of
-// an ethernet pktmover. There are some problems and limitations
-// with FreeBSD:
-//   - the source address of the frame is overwritten by
-//    the hosts's source address. This causes problems with
-//    learning bridges - since they cannot determine where
-//    BOCHS 'is', they broadcast the frame to all ports.
-//   - packets cannot be sent from BOCHS to the host
-//   - TCP performance seems to be abysmal; I think this is
-//     a timing problem somewhere.
-//   - I haven't handled the case where multiple frames arrive
-//     in a single BPF read. 
-//
-//   The /dev/bpf* devices need to be set up with the appropriate
-//  permissions for this to work.
-//
-//   The config line in .bochsrc should look something like:
-//
-//  ne2k: ioaddr=0x280, irq=9, mac=00:a:b:c:1:2, ethmod=fbsd, ethdev=fxp0
-//
-
-// Define BX_PLUGGABLE in files that can be compiled into plugins.  For
-// platforms that require a special tag on exported symbols, BX_PLUGGABLE 
-// is used to know when we are exporting symbols and when we are importing.
-#define BX_PLUGGABLE
-#include "bochs.h"
-#if BX_NE2K_SUPPORT && defined(ETH_FBSD)
-
-#define LOG_THIS bx_devices.pluginNE2kDevice->
-
-extern "C" {
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <net/if.h>
-#include <net/bpf.h>
-#include <errno.h>
-};
-
-#define BX_BPF_POLL  1000    // Poll for a frame every 250 usecs
-
-#define BX_BPF_BUFSIZ 2048   // enough for an ether frame + bpf hdr
-
-#define BX_BPF_INSNSIZ  8    // number of bpf insns
-
-// template filter for a unicast mac address and all 
-// multicast/broadcast frames
-static const struct bpf_insn macfilter[] = {
-    BPF_STMT(BPF_LD|BPF_W|BPF_ABS, 2),                  // A <- P[2:4]
-    BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 0xaaaaaaaa, 0, 2),  // if A != 0xaaaaaaa GOTO LABEL-1
-    BPF_STMT(BPF_LD|BPF_H|BPF_ABS, 0),                  // A <- P[0:2]
-    BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 0x0000aaaa, 2, 0),  // if A == 0xaaaa GOTO ACCEPT
-    // LABEL-1
-    BPF_STMT(BPF_LD|BPF_B|BPF_ABS, 0),                  // A <- P[0:1]
-    BPF_JUMP(BPF_JMP|BPF_JSET|BPF_K, 0x01, 0, 1),       // if !(A & 1) GOTO LABEL-REJECT
-    // LABEL-ACCEPT
-    BPF_STMT(BPF_RET, 1514),                            // Accept packet
-    // LABEL-REJECT
-    BPF_STMT(BPF_RET, 0),                               // Reject packet
-};
-
-// template filter for all frames
-static const struct bpf_insn promiscfilter[] = {
-  BPF_STMT(BPF_RET, 1514)
-};
-
-//
-//  Define the class. This is private to this module
-//
-class bx_fbsd_pktmover_c : public eth_pktmover_c {
-public:
-  bx_fbsd_pktmover_c(const char *netif, 
-                    const char *macaddr,
-                    eth_rx_handler_t rxh,
-                    void *rxarg);
-  void sendpkt(void *buf, unsigned io_len);
-
-private:
-  char *fbsd_macaddr[6];
-  int bpf_fd;
-  static void rx_timer_handler(void *);
-  void rx_timer(void);
-  int rx_timer_index;
-  struct bpf_insn filter[BX_BPF_INSNSIZ];
-  FILE *ne2klog, *ne2klog_txt;
-};
-
-
-//
-//  Define the static class that registers the derived pktmover class,
-// and allocates one on request.
-//
-class bx_fbsd_locator_c : public eth_locator_c {
-public:
-  bx_fbsd_locator_c(void) : eth_locator_c("fbsd") {}
-protected:
-  eth_pktmover_c *allocate(const char *netif, 
-                          const char *macaddr,
-                          eth_rx_handler_t rxh,
-                          void *rxarg) {
-    return (new bx_fbsd_pktmover_c(netif, macaddr, rxh, rxarg));
-  }
-} bx_fbsd_match;
-
-
-//
-// Define the methods for the bx_fbsd_pktmover derived class
-//
-
-// the constructor
-//
-// Open a bpf file descriptor, and attempt to bind to
-// the specified netif (Replicates libpcap open code)
-//
-bx_fbsd_pktmover_c::bx_fbsd_pktmover_c(const char *netif, 
-                                      const char *macaddr,
-                                      eth_rx_handler_t rxh,
-                                      void *rxarg)
-{
-  char device[sizeof "/dev/bpf000"];
-  int tmpfd;
-  int n = 0;
-  struct ifreq ifr;
-  struct bpf_version bv;
-  struct bpf_program bp;
-  u_int v;
-
-  memcpy(fbsd_macaddr, macaddr, 6);
-
-  do {
-    (void)sprintf(device, "/dev/bpf%d", n++);
-    this->bpf_fd = open(device, O_RDWR);
-       BX_DEBUG(("tried %s, returned %d (%s)",device,this->bpf_fd,strerror(errno)));
-       if(errno == EACCES)
-               break;
-  } while (this->bpf_fd == -1);
-  
-  if (this->bpf_fd == -1) {
-    BX_PANIC(("eth_freebsd: could not open packet filter: %s", strerror(errno)));
-    return;
-  }
-
-  if (ioctl(this->bpf_fd, BIOCVERSION, (caddr_t)&bv) < 0) {
-    BX_PANIC(("eth_freebsd: could not retrieve bpf version"));
-    close(this->bpf_fd);
-    this->bpf_fd = -1;
-    return;
-  }
-  if (bv.bv_major != BPF_MAJOR_VERSION || bv.bv_minor < BPF_MINOR_VERSION) {
-    BX_PANIC(("eth_freebsd: bpf version mismatch between compilation and runtime"));
-    close(this->bpf_fd);
-    this->bpf_fd = -1;
-    return;
-  }
-
-  // Set buffer size
-  v = BX_BPF_BUFSIZ;
-  if (ioctl(this->bpf_fd, BIOCSBLEN, (caddr_t)&v) < 0) {
-    BX_PANIC(("eth_freebsd: could not set buffer size: %s", strerror(errno)));
-    close(this->bpf_fd);
-    this->bpf_fd = -1;
-    return;
-  }
-
-  (void)strncpy(ifr.ifr_name, netif, sizeof(ifr.ifr_name));
-  if (ioctl(this->bpf_fd, BIOCSETIF, (caddr_t)&ifr) < 0) {
-    BX_PANIC(("eth_freebsd: could not enable interface '%s': %s", netif, strerror(errno)));
-    close(this->bpf_fd);
-    this->bpf_fd == -1;
-  }
-  
-  // Verify that the device is an ethernet.
-  if (ioctl(this->bpf_fd, BIOCGDLT, (caddr_t)&v) < 0) {
-    BX_PANIC(("eth_freebsd: could not retrieve datalink type: %s", strerror(errno)));
-    close(this->bpf_fd);
-    this->bpf_fd = -1;
-    return;
-  }
-  if (v != DLT_EN10MB) {
-    BX_PANIC(("eth_freebsd: incorrect datalink type %d, expected 10mb ethernet", v));
-    close(this->bpf_fd);
-    this->bpf_fd = -1;
-    return;
-  }
-
-  // Put the device into promisc mode. This could be optimised
-  // to filter on a MAC address, broadcast, and all-multi,
-  // but this will do for now.
-  //
-  if (ioctl(this->bpf_fd, BIOCPROMISC, NULL) < 0) {
-    BX_PANIC(("eth_freebsd: could not enable promisc mode: %s", strerror(errno)));
-    close(this->bpf_fd);
-    this->bpf_fd = -1;
-    return;
-  }
-
-  // Set up non-blocking i/o
-  v = 1;
-  if (ioctl(this->bpf_fd, FIONBIO, &v) < 0) {
-    BX_PANIC(("eth_freebsd: could not enable non-blocking i/o: %s", strerror(errno)));
-    close(this->bpf_fd);
-    this->bpf_fd = -1;
-    return;
-  }
-
-  // Install a filter
-#ifdef notdef
-  memcpy(&this->filter, promiscfilter, sizeof(promiscfilter));
-  bp.bf_len   = 1;
-#else
-  memcpy(&this->filter, macfilter, sizeof(macfilter));
-  this->filter[1].k =
-      (macaddr[2] & 0xff) << 24 |
-    (macaddr[3] & 0xff) << 16 |
-    (macaddr[4] & 0xff) << 8  |
-    (macaddr[5] & 0xff);
-  this->filter[3].k =
-      (macaddr[0] & 0xff) << 8 |
-    (macaddr[1] & 0xff);
-  bp.bf_len   = 8;
-#endif
-  bp.bf_insns = &this->filter[0];
-  if (ioctl(this->bpf_fd, BIOCSETF, &bp) < 0) {
-    BX_PANIC(("eth_freebsd: could not set filter: %s", strerror(errno)));
-    close(this->bpf_fd);
-    this->bpf_fd = -1;
-    return;
-  }
-
-  // Start the rx poll 
-  this->rx_timer_index = 
-    bx_pc_system.register_timer(this, this->rx_timer_handler, BX_BPF_POLL,
-                               1, 1, "eth_fbsd"); // continuous, active
-
-  this->rxh   = rxh;
-  this->rxarg = rxarg;
-
-#if BX_ETH_FBSD_LOGGING
-  // eventually Bryce wants ne2klog to dump in pcap format so that
-  // tcpdump -r FILE can read it and interpret packets.
-  ne2klog = fopen ("ne2k.raw", "wb");
-  if (!ne2klog) BX_PANIC (("open ne2k-tx.log failed"));
-  ne2klog_txt = fopen ("ne2k.txt", "wb");
-  if (!ne2klog_txt) BX_PANIC (("open ne2k-txdump.txt failed"));
-  fprintf (ne2klog_txt, "null packetmover readable log file\n");
-  fprintf (ne2klog_txt, "net IF = %s\n", netif);
-  fprintf (ne2klog_txt, "MAC address = ");
-  for (int i=0; i<6; i++)
-    fprintf (ne2klog_txt, "%02x%s", 0xff & macaddr[i], i<5?":" : "");
-  fprintf (ne2klog_txt, "\n--\n");
-  fflush (ne2klog_txt);
-#endif
-}
-
-// the output routine - called with pre-formatted ethernet frame.
-void
-bx_fbsd_pktmover_c::sendpkt(void *buf, unsigned io_len)
-{
-#if BX_ETH_FBSD_LOGGING
-  BX_DEBUG (("sendpkt length %u", io_len));
-  // dump raw bytes to a file, eventually dump in pcap format so that
-  // tcpdump -r FILE can interpret them for us.
-  int n = fwrite (buf, io_len, 1, ne2klog);
-  if (n != 1) BX_ERROR (("fwrite to ne2klog failed", io_len));
-  // dump packet in hex into an ascii log file
-  fprintf (ne2klog_txt, "NE2K TX packet, length %u\n", io_len);
-  Bit8u *charbuf = (Bit8u *)buf;
-  for (n=0; n<io_len; n++) {
-    if (((n % 16) == 0) && n>0)
-      fprintf (ne2klog_txt, "\n");
-    fprintf (ne2klog_txt, "%02x ", charbuf[n]);
-  }
-  fprintf (ne2klog_txt, "\n--\n");
-  // flush log so that we see the packets as they arrive w/o buffering
-  fflush (ne2klog);
-  fflush (ne2klog_txt);
-#endif
-  int status;
-
-  if (this->bpf_fd != -1)
-    status = write(this->bpf_fd, buf, io_len);
-}
-
-// The receive poll process
-void
-bx_fbsd_pktmover_c::rx_timer_handler(void *this_ptr)
-{
-  bx_fbsd_pktmover_c *class_ptr = (bx_fbsd_pktmover_c *) this_ptr;
-
-  class_ptr->rx_timer();
-}
-
-
-void
-bx_fbsd_pktmover_c::rx_timer(void)
-{
-  int nbytes = 0;
-    unsigned char rxbuf[BX_BPF_BUFSIZ]; 
-  struct bpf_hdr *bhdr;
-    struct bpf_stat bstat;
-    static struct bpf_stat previous_bstat;
-    int counter = 10;
-#define phdr ((unsigned char*)bhdr)
-
-    bhdr = (struct bpf_hdr *) rxbuf;
-  nbytes = read(this->bpf_fd, rxbuf, sizeof(rxbuf));
-
-    while (phdr < (rxbuf + nbytes)) {
-       if (ioctl(this->bpf_fd, BIOCGSTATS, &bstat) < 0) {
-           BX_PANIC(("eth_freebsd: could not stat filter: %s", strerror(errno)));
-       }
-       if (bstat.bs_drop > previous_bstat.bs_drop) {
-           BX_INFO (("eth_freebsd: %d packets dropped by the kernel.",
-                     bstat.bs_drop - previous_bstat.bs_drop));
-       }
-       previous_bstat = bstat;
-       if (bhdr->bh_caplen < 20 || bhdr->bh_caplen > 1514) {
-           BX_ERROR(("eth_freebsd: received too weird packet length: %d", bhdr->bh_caplen));
-       }
-
-    // filter out packets sourced from this node
-       if (memcmp(bhdr + bhdr->bh_hdrlen + 6, this->fbsd_macaddr, 6)) {
-           (*rxh)(rxarg, phdr + bhdr->bh_hdrlen, bhdr->bh_caplen);
-    }
-       
-#if BX_ETH_FBSD_LOGGING
-  /// hey wait there is no receive data with a NULL ethernet, is there....
-    BX_DEBUG (("receive packet length %u", nbytes));
-    // dump raw bytes to a file, eventually dump in pcap format so that
-    // tcpdump -r FILE can interpret them for us.
-       if (1 != fwrite (bhdr, bhdr->bh_caplen, 1, ne2klog)) {
-           BX_PANIC (("fwrite to ne2klog failed: %s", strerror(errno)));
-       }
-    // dump packet in hex into an ascii log file
-       fprintf (this->ne2klog_txt, "NE2K RX packet, length %u\n", bhdr->bh_caplen);
-    Bit8u *charrxbuf = (Bit8u *)rxbuf;
-       int n;
-       for (n=0; n<bhdr->bh_caplen; n++) {
-      if (((n % 16) == 0) && n>0)
-       fprintf (this->ne2klog_txt, "\n");
-           fprintf (this->ne2klog_txt, "%02x ", phdr[n]);
-    }
-    fprintf (this->ne2klog_txt, "\n--\n");
-    // flush log so that we see the packets as they arrive w/o buffering
-    fflush (this->ne2klog);
-    fflush (this->ne2klog_txt);
-#endif
-
-       // Advance bhdr and phdr pointers to next packet
-       bhdr = (struct bpf_hdr*) ((char*) bhdr + BPF_WORDALIGN(bhdr->bh_hdrlen + bhdr->bh_caplen));
-  }  
-}
-
-#endif /* if BX_NE2K_SUPPORT && defined(ETH_FBSD) */
-
diff --git a/tools/ioemu/iodev/eth_linux.cc b/tools/ioemu/iodev/eth_linux.cc
deleted file mode 100644 (file)
index e7076b9..0000000
+++ /dev/null
@@ -1,286 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: eth_linux.cc,v 1.14 2003/02/16 19:35:57 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2001  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-// Peter Grehan (grehan@iprg.nokia.com) coded all of this
-// NE2000/ether stuff.
-
-// eth_linux.cc - A Linux socket filter adaptation of the FreeBSD BPF driver
-// <splite@purdue.edu> 21 June 2001
-//
-// Problems and limitations:
-//   - packets cannot be sent from BOCHS to the host
-//   - Linux kernel sometimes gets network watchdog timeouts under emulation
-//   - author doesn't know C++
-//
-//   The config line in .bochsrc should look something like:
-//
-//  ne2k: ioaddr=0x280, irq=10, mac=00:a:b:c:1:2, ethmod=linux, ethdev=eth0
-//
-
-// Define BX_PLUGGABLE in files that can be compiled into plugins.  For
-// platforms that require a special tag on exported symbols, BX_PLUGGABLE 
-// is used to know when we are exporting symbols and when we are importing.
-#define BX_PLUGGABLE
-#include "bochs.h"
-#if BX_NE2K_SUPPORT && defined (ETH_LINUX)
-#define LOG_THIS bx_devices.pluginNE2kDevice->
-
-extern "C" {
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <netpacket/packet.h>
-#include <netinet/in.h>
-#include <net/ethernet.h>
-#include <net/if.h>
-#include <linux/types.h>
-#include <linux/filter.h>
-};
-
-#define BX_PACKET_POLL  1000    // Poll for a frame every 1000 usecs
-
-#define BX_PACKET_BUFSIZ 2048  // Enough for an ether frame
-
-// template filter for a unicast mac address and all
-// multicast/broadcast frames
-static const struct sock_filter macfilter[] = {
-  BPF_STMT(BPF_LD|BPF_W|BPF_ABS, 2),
-  BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 0xaaaaaaaa, 0, 2),
-  BPF_STMT(BPF_LD|BPF_H|BPF_ABS, 0),
-  BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 0x0000aaaa, 2, 0),
-  BPF_STMT(BPF_LD|BPF_B|BPF_ABS, 0),
-  BPF_JUMP(BPF_JMP|BPF_JSET|BPF_K, 0x01, 0, 1),
-  BPF_STMT(BPF_RET, 1514),
-  BPF_STMT(BPF_RET, 0),
-};
-#define BX_LSF_ICNT 8    // number of lsf instructions in macfilter
-
-#if 0
-// template filter for all frames
-static const struct sock_filter promiscfilter[] = {
-  BPF_STMT(BPF_RET, 1514)
-};
-#endif
-
-//
-//  Define the class. This is private to this module
-//
-class bx_linux_pktmover_c : public eth_pktmover_c {
-public:
-  bx_linux_pktmover_c(const char *netif, 
-                    const char *macaddr,
-                    eth_rx_handler_t rxh,
-                    void *rxarg);
-  void sendpkt(void *buf, unsigned io_len);
-
-private:
-  unsigned char *linux_macaddr[6];
-  int fd;
-  int ifindex;
-  static void rx_timer_handler(void *);
-  void rx_timer(void);
-  int rx_timer_index;
-  struct sock_filter filter[BX_LSF_ICNT];
-};
-
-
-//
-//  Define the static class that registers the derived pktmover class,
-// and allocates one on request.
-//
-class bx_linux_locator_c : public eth_locator_c {
-public:
-  bx_linux_locator_c(void) : eth_locator_c("linux") {}
-protected:
-  eth_pktmover_c *allocate(const char *netif, 
-                          const char *macaddr,
-                          eth_rx_handler_t rxh,
-                          void *rxarg) {
-    return (new bx_linux_pktmover_c(netif, macaddr, rxh, rxarg));
-  }
-} bx_linux_match;
-
-
-//
-// Define the methods for the bx_linux_pktmover derived class
-//
-
-// the constructor
-//
-bx_linux_pktmover_c::bx_linux_pktmover_c(const char *netif, 
-                                      const char *macaddr,
-                                      eth_rx_handler_t rxh,
-                                      void *rxarg)
-{
-  struct sockaddr_ll sll;
-  struct packet_mreq mr;
-  struct ifreq ifr;
-  struct sock_fprog fp;
-
-  memcpy(linux_macaddr, macaddr, 6);
-
-  // Open packet socket
-  //
-  if ((this->fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) == -1) {
-    if (errno == EACCES)
-      BX_PANIC(("eth_linux: must be root or have CAP_NET_RAW capability to open socket"));
-    else
-      BX_PANIC(("eth_linux: could not open socket: %s", strerror(errno)));
-    this->fd = -1;
-    return;
-  }
-  
-  // Translate interface name to index
-  //
-  memset(&ifr, 0, sizeof(ifr));
-  strcpy(ifr.ifr_name, netif);
-  if (ioctl(this->fd, SIOCGIFINDEX, &ifr) == -1) {
-    BX_PANIC(("eth_linux: could not get index for interface '%s'\n", netif));
-    close(fd);
-    this->fd = -1;
-    return;
-  }
-  this->ifindex = ifr.ifr_ifindex;
-
-
-  // Bind to given interface
-  //
-  memset(&sll, 0, sizeof(sll));
-  sll.sll_family = AF_PACKET;
-  sll.sll_ifindex = this->ifindex;
-  if (bind(fd, (struct sockaddr *)&sll, (socklen_t)sizeof(sll)) == -1) {
-    BX_PANIC(("eth_linux: could not bind to interface '%s': %s\n", netif, strerror(errno)));
-    close(fd);
-    this->fd = -1;
-    return;
-  }
-
-  // Put the device into promisc mode.
-  //
-  memset(&mr, 0, sizeof(mr));
-  mr.mr_ifindex = this->ifindex;
-  mr.mr_type = PACKET_MR_PROMISC;
-  if (setsockopt(this->fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, (void *)&mr, (socklen_t)sizeof(mr)) == -1) {
-    BX_PANIC(("eth_linux: could not enable promisc mode: %s\n", strerror(errno)));
-    close(this->fd);
-    this->fd = -1;
-    return;
-  }
-
-  // Set up non-blocking i/o
-  if (fcntl(this->fd, F_SETFL, O_NONBLOCK) == -1) {
-    BX_PANIC(("eth_linux: could not set non-blocking i/o on socket"));
-    close(this->fd);
-    this->fd = -1;
-    return;
-  }
-
-  // Install a filter
-#ifdef notdef
-  memcpy(&this->filter, promiscfilter, sizeof(promiscfilter));
-  fp.len   = 1;
-#endif
-  memcpy(&this->filter, macfilter, sizeof(macfilter));
-  this->filter[1].k = (macaddr[2] & 0xff) << 24 | (macaddr[3] & 0xff) << 16 |
-    (macaddr[4] & 0xff) << 8  | (macaddr[5] & 0xff);
-  this->filter[3].k = (macaddr[0] & 0xff) << 8 | (macaddr[1] & 0xff);
-  fp.len = BX_LSF_ICNT;
-  fp.filter = this->filter;
-  BX_INFO(("eth_linux: fp.len=%d fp.filter=%lx", fp.len, (unsigned long) fp.filter));
-  if (setsockopt(this->fd, SOL_SOCKET, SO_ATTACH_FILTER, &fp, sizeof(fp)) < 0) {
-    BX_PANIC(("eth_linux: could not set socket filter: %s", strerror(errno)));
-    close(this->fd);
-    this->fd = -1;
-    return;
-  }
-
-  // Start the rx poll 
-  this->rx_timer_index = 
-    bx_pc_system.register_timer(this, this->rx_timer_handler, BX_PACKET_POLL,
-                               1, 1, "eth_linux"); // continuous, active
-
-  this->rxh   = rxh;
-  this->rxarg = rxarg;
-  BX_INFO(("eth_linux: enabled NE2K emulation on interface %s", netif));
-}
-
-// the output routine - called with pre-formatted ethernet frame.
-void
-bx_linux_pktmover_c::sendpkt(void *buf, unsigned io_len)
-{
-  int status;
-
-  if (this->fd != -1) {
-    status = write(this->fd, buf, io_len);
-    if (status == -1)
-      BX_INFO(("eth_linux: write failed: %s", strerror(errno)));
-  }
-}
-
-// The receive poll process
-void
-bx_linux_pktmover_c::rx_timer_handler(void *this_ptr)
-{
-  bx_linux_pktmover_c *class_ptr = (bx_linux_pktmover_c *) this_ptr;
-
-  class_ptr->rx_timer();
-}
-
-void
-bx_linux_pktmover_c::rx_timer(void)
-{
-  int nbytes = 0;
-  Bit8u rxbuf[BX_PACKET_BUFSIZ]; 
-  struct sockaddr_ll sll;
-  socklen_t fromlen;
-//static unsigned char bcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
-
-  if (this->fd == -1)
-    return;
-
-  fromlen = sizeof(sll);
-  nbytes = recvfrom(this->fd, rxbuf, sizeof(rxbuf), 0, (struct sockaddr *)&sll, &fromlen);
-
-  if (nbytes == -1) {
-    if (errno != EAGAIN)
-      BX_INFO(("eth_linux: error receiving packet: %s\n", strerror(errno)));
-    return;
-  }
-
-  // this should be done with LSF someday
-  // filter out packets sourced by us
-  if (memcmp(sll.sll_addr, this->linux_macaddr, 6) == 0)
-    return;
-  // let through broadcast, multicast, and our mac address
-//  if ((memcmp(rxbuf, bcast_addr, 6) == 0) || (memcmp(rxbuf, this->linux_macaddr, 6) == 0) || rxbuf[0] & 0x01) {
-    BX_DEBUG(("eth_linux: got packet: %d bytes, dst=%x:%x:%x:%x:%x:%x, src=%x:%x:%x:%x:%x:%x\n", nbytes, rxbuf[0], rxbuf[1], rxbuf[2], rxbuf[3], rxbuf[4], rxbuf[5], rxbuf[6], rxbuf[7], rxbuf[8], rxbuf[9], rxbuf[10], rxbuf[11]));
-    (*rxh)(rxarg, rxbuf, nbytes);
-//  }
-}
-#endif /* if BX_NE2K_SUPPORT && defined ETH_LINUX */
diff --git a/tools/ioemu/iodev/eth_null.cc b/tools/ioemu/iodev/eth_null.cc
deleted file mode 100644 (file)
index 1116279..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: eth_null.cc,v 1.13 2002/11/20 19:06:23 bdenney Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2001  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-// eth_null.cc  - skeleton code for an ethernet pktmover
-
-// Various networking docs:
-// http://www.graphcomp.com/info/rfc/
-// rfc0826: arp
-// rfc0903: rarp
-
-// Define BX_PLUGGABLE in files that can be compiled into plugins.  For
-// platforms that require a special tag on exported symbols, BX_PLUGGABLE 
-// is used to know when we are exporting symbols and when we are importing.
-#define BX_PLUGGABLE
-#include "bochs.h"
-#if BX_NE2K_SUPPORT
-
-#define LOG_THIS bx_devices.pluginNE2kDevice->
-
-
-//
-//  Define the class. This is private to this module
-//
-class bx_null_pktmover_c : public eth_pktmover_c {
-public:
-  bx_null_pktmover_c(const char *netif, const char *macaddr,
-                    eth_rx_handler_t rxh,
-                    void *rxarg);
-  void sendpkt(void *buf, unsigned io_len);
-private:
-  int rx_timer_index;
-  static void rx_timer_handler(void *);
-  FILE *txlog, *txlog_txt, *rxlog, *rxlog_txt;
-};
-
-
-//
-//  Define the static class that registers the derived pktmover class,
-// and allocates one on request.
-//
-class bx_null_locator_c : public eth_locator_c {
-public:
-  bx_null_locator_c(void) : eth_locator_c("null") {}
-protected:
-  eth_pktmover_c *allocate(const char *netif, const char *macaddr,
-                          eth_rx_handler_t rxh,
-                          void *rxarg) {
-    return (new bx_null_pktmover_c(netif, macaddr, rxh, rxarg));
-  }
-} bx_null_match;
-
-
-//
-// Define the methods for the bx_null_pktmover derived class
-//
-
-// the constructor
-bx_null_pktmover_c::bx_null_pktmover_c(const char *netif, 
-                                      const char *macaddr,
-                                      eth_rx_handler_t rxh,
-                                      void *rxarg)
-{
-#if BX_ETH_NULL_LOGGING
-  // Start the rx poll 
-  this->rx_timer_index = 
-    bx_pc_system.register_timer(this, this->rx_timer_handler, 1000,
-                               1, 1, "eth_null"); // continuous, active
-  this->rxh   = rxh;
-  this->rxarg = rxarg;
-  // eventually Bryce wants txlog to dump in pcap format so that
-  // tcpdump -r FILE can read it and interpret packets.
-  txlog = fopen ("ne2k-tx.log", "wb");
-  if (!txlog) BX_PANIC (("open ne2k-tx.log failed"));
-  txlog_txt = fopen ("ne2k-txdump.txt", "wb");
-  if (!txlog_txt) BX_PANIC (("open ne2k-txdump.txt failed"));
-  fprintf (txlog_txt, "null packetmover readable log file\n");
-  fprintf (txlog_txt, "net IF = %s\n", netif);
-  fprintf (txlog_txt, "MAC address = ");
-  for (int i=0; i<6; i++) 
-    fprintf (txlog_txt, "%02x%s", 0xff & macaddr[i], i<5?":" : "");
-  fprintf (txlog_txt, "\n--\n");
-  fflush (txlog_txt);
-#endif
-}
-
-void
-bx_null_pktmover_c::sendpkt(void *buf, unsigned io_len)
-{
-#if BX_ETH_NULL_LOGGING
-  BX_DEBUG (("sendpkt length %u", io_len));
-  // dump raw bytes to a file, eventually dump in pcap format so that
-  // tcpdump -r FILE can interpret them for us.
-  unsigned int n = fwrite (buf, io_len, 1, txlog);
-  if (n != 1) BX_ERROR (("fwrite to txlog failed, io_len = %u", io_len));
-  // dump packet in hex into an ascii log file
-  fprintf (txlog_txt, "NE2K transmitting a packet, length %u\n", io_len);
-  Bit8u *charbuf = (Bit8u *)buf;
-  for (n=0; n<io_len; n++) {
-    if (((n % 16) == 0) && n>0)
-      fprintf (txlog_txt, "\n");
-    fprintf (txlog_txt, "%02x ", charbuf[n]);
-  }
-  fprintf (txlog_txt, "\n--\n");
-  // flush log so that we see the packets as they arrive w/o buffering
-  fflush (txlog);
-  fflush (txlog_txt);
-#endif
-}
-
-void bx_null_pktmover_c::rx_timer_handler (void *this_ptr)
-{
-#if BX_ETH_NULL_LOGGING
-  /// hey wait there is no receive data with a NULL ethernet, is there....
-
-  int io_len = 0;
-  Bit8u buf[1];
-  bx_null_pktmover_c *class_ptr = (bx_null_pktmover_c *) this_ptr;
-  if (io_len > 0) {
-    BX_DEBUG (("receive packet length %u", io_len));
-    // dump raw bytes to a file, eventually dump in pcap format so that
-    // tcpdump -r FILE can interpret them for us.
-    int n = fwrite (buf, io_len, 1, class_ptr->rxlog);
-    if (n != 1) BX_ERROR (("fwrite to rxlog failed, io_len = %u", io_len));
-    // dump packet in hex into an ascii log file
-    fprintf (class_ptr->rxlog_txt, "NE2K transmitting a packet, length %u\n", io_len);
-    Bit8u *charbuf = (Bit8u *)buf;
-    for (n=0; n<io_len; n++) {
-      if (((n % 16) == 0) && n>0)
-       fprintf (class_ptr->rxlog_txt, "\n");
-      fprintf (class_ptr->rxlog_txt, "%02x ", charbuf[n]);
-    }
-    fprintf (class_ptr->rxlog_txt, "\n--\n");
-    // flush log so that we see the packets as they arrive w/o buffering
-    fflush (class_ptr->rxlog);
-    fflush (class_ptr->rxlog_txt);
-  }
-#endif
-}
-
-#endif /* if BX_NE2K_SUPPORT */
diff --git a/tools/ioemu/iodev/eth_packetmaker.cc b/tools/ioemu/iodev/eth_packetmaker.cc
deleted file mode 100644 (file)
index 5ed5e47..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: eth_packetmaker.cc,v 1.8 2002/11/20 19:06:23 bdenney Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-// Define BX_PLUGGABLE in files that can be compiled into plugins.  For
-// platforms that require a special tag on exported symbols, BX_PLUGGABLE 
-// is used to know when we are exporting symbols and when we are importing.
-#define BX_PLUGGABLE
-#include "bochs.h"
-
-#if BX_NE2K_SUPPORT && defined(ETH_ARPBACK)
-
-#include "eth_packetmaker.h"
-
-
-bx_bool sendable(const eth_packet& outpacket) {
-  //FINISH ME!
-}
-
-Bit32u eth_IPmaker::datalen(const eth_packet& outpacket) {
-  Bit32u out;
-  out=((outpacket.buf[16]<<8)+outpacket.buf[17])-(4*(0xF & outpacket.buf[14]));
-  return out;
-}
-
-const Bit8u * eth_IPmaker::datagram(const eth_packet& outpacket) {
-  const Bit8u * out;
-  out=outpacket.buf+14+(4*(0xF & outpacket.buf[14]));
-  return out;
-}
-
-Bit32u eth_IPmaker::build_packet_header(Bit32u source, Bit32u dest, Bit8u protocol, Bit32u datalen) {
-  Bit32u temp;
-  Bit32u i;
-  memcpy(pending.buf,internal_mac,6);
-  memcpy(pending.buf+6,external_mac,6);
-  memcpy(pending.buf+12,ethtype_ip,2);
-  pending.buf[14]=0x45;
-  pending.buf[15]=0;
-  temp=datalen+20;
-  pending.buf[16]=(temp>>8) & 0xFF;
-  pending.buf[17]=temp & 0xFF;
-  pending.buf[18]=0;
-  pending.buf[19]=0;
-  pending.buf[20]=0;
-  pending.buf[21]=0;
-  pending.buf[22]=30;
-  pending.buf[23]=protocol;
-  pending.buf[24]=0;
-  pending.buf[25]=0;
-  pending.buf[26]=(source>>24) & 0xFF;
-  pending.buf[27]=(source>>16) & 0xFF;
-  pending.buf[28]=(source>>8) & 0xFF;
-  pending.buf[29]=(source) & 0xFF;
-  pending.buf[30]=(dest>>24) & 0xFF;
-  pending.buf[31]=(dest>>16) & 0xFF;
-  pending.buf[32]=(dest>>8) & 0xFF;
-  pending.buf[33]=(dest) & 0xFF;
-  //Compute Checksum
-  temp=0;
-  for(i=14;i<34;i=i+2) {
-    Bit32u addee=pending.buf[i];
-    addee=(addee<<8) & pending.buf[i+1];
-    temp=temp+addee;
-  }
-  temp=(temp>>16)+(temp&0xFFFF);
-  temp=(temp>>16)+(temp&0xFFFF);
-  pending.buf[24]=~(Bit8u)((temp>>8) & 0xFF);
-  pending.buf[25]=~(Bit8u)(temp & 0xFF);
-  return(34);
-}
-
-Bit8u eth_IPmaker::protocol(const eth_packet& outpacket) {
-  Bit8u out;
-  out=0xFF & *(outpacket.buf+23);
-}
-
-Bit32u eth_IPmaker::source(const eth_packet& outpacket) {
-  Bit32u out;
-  out=0xFF & *(outpacket.buf+26);
-  out=(out<<8) | (0xFF & *(outpacket.buf+27));
-  out=(out<<8) | (0xFF & *(outpacket.buf+28));
-  out=(out<<8) | (0xFF & *(outpacket.buf+29));
-  return out;
-}
-
-Bit32u eth_IPmaker::destination(const eth_packet& outpacket) {
-  Bit32u out;
-  out=0xFF & *(outpacket.buf+30);
-  out=(out<<8) | (0xFF & *(outpacket.buf+31));
-  out=(out<<8) | (0xFF & *(outpacket.buf+32));
-  out=(out<<8) | (0xFF & *(outpacket.buf+33));
-  return out;
-}
-
-void eth_IPmaker::init(void) {
-  is_pending=0;
-}
-
-void
-eth_ETHmaker::init(void) {
-  arper.init();
-}
-
-bx_bool
-eth_ETHmaker::getpacket(eth_packet& inpacket) {
-  return arper.getpacket(inpacket);
-}
-
-bx_bool
-eth_ETHmaker::ishandler(const eth_packet& outpacket) {
-  if((outpacket.len>=60) &&
-     ( (!memcmp(outpacket.buf, external_mac, 6))
-       || (!memcmp(outpacket.buf, broadcast_mac, 6)) ) &&
-     ( (!memcmp(outpacket.buf+12, ethtype_arp, 2)) ||
-       (!memcmp(outpacket.buf+12, ethtype_ip, 2)) ) &&
-     (outpacket.len<PACKET_BUF_SIZE)
-     ) {
-    return 1;
-  }
-  return 0;  
-}
-
-bx_bool
-eth_ETHmaker::sendpacket(const eth_packet& outpacket) {
-  return arper.sendpacket(outpacket);
-}
-
-
-
-void
-eth_ARPmaker::init(void) {
-  is_pending=0;
-  pending.len=0;
-}
-
-bx_bool
-eth_ARPmaker::getpacket(eth_packet& inpacket) {
-  if(is_pending) {
-    memcpy(inpacket.buf,pending.buf,pending.len);
-    inpacket.len=pending.len;
-    is_pending=0;
-    return 1;
-  }
-  return 0;
-}
-
-bx_bool
-eth_ARPmaker::ishandler(const eth_packet& outpacket) {
-  if((outpacket.len>=60) &&
-     (!memcmp(outpacket.buf+12, ethtype_arp, 2)) &&
-     (outpacket.len<PACKET_BUF_SIZE) &&
-     ( (!memcmp(outpacket.buf, external_mac, 6))
-       || (!memcmp(outpacket.buf, broadcast_mac, 6)) ) &&
-     (!memcmp(outpacket.buf+38, external_ip, 4))
-     ) {
-    return 1;
-  }
-  return 0;
-}
-
-bx_bool
-eth_ARPmaker::sendpacket(const eth_packet& outpacket) {
-  if(is_pending || !ishandler(outpacket)) {
-    return 0;
-  } else {
-    Bit32u tempcrc;
-    memcpy(pending.buf,outpacket.buf,outpacket.len); //move to temporary buffer
-    memcpy(pending.buf, pending.buf+6, 6); //set destination to sender
-    memcpy(pending.buf+6, external_mac, 6); //set sender to us
-    memcpy(pending.buf+32, pending.buf+22, 10); //move destination to sender
-    memcpy(pending.buf+22, external_mac, 6); //set sender to us
-    memcpy(pending.buf+28, external_ip, 4); //set sender to us
-    pending.buf[21]=2; //make this a reply and not a request
-    //tempcrc=mycrc.get_CRC(pending.buf,len);
-    //memcpy(pending.buf+len, &tempcrc, 4);
-    pending.len=outpacket.len; //+4
-    is_pending=1;
-    return 1;
-  }
-}
-
-#endif /* if BX_NE2K_SUPPORT && defined(ETH_ARPBACK) */
diff --git a/tools/ioemu/iodev/eth_packetmaker.h b/tools/ioemu/iodev/eth_packetmaker.h
deleted file mode 100644 (file)
index d442325..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: eth_packetmaker.h,v 1.6 2002/10/25 11:44:39 bdenney Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-
-#ifndef _ETH_PACKETMAKER_H_
-#define _ETH_PACKETMAKER_H_
-
-#include "../config.h"
-
-#ifdef ETH_ARPBACK
-
-#define PACKET_BUF_SIZE 2048
-static const Bit8u internal_mac[]={0xB0, 0xC4, 0x20, 0x20, 0x00, 0x00, 0x00};
-static const Bit8u external_mac[]={0xB0, 0xC4, 0x20, 0x20, 0x00, 0x00, 0x00};
-static const Bit8u external_ip[]={ 192, 168, 0, 2, 0x00 };
-static const Bit8u broadcast_mac[]={0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00};
-static const Bit8u ethtype_arp[]={0x08, 0x06, 0x00};
-static const Bit8u ethtype_ip[]={0x08, 0x00, 0x00};
-static const Bit8u prot_udp=17;
-static const Bit8u prot_tcp=6;
-
-
-class eth_packet {
-public:
-  Bit8u buf[PACKET_BUF_SIZE];
-  Bit32u len;
-};
-
-
-class eth_packetmaker {
-public:
-  virtual bx_bool getpacket(eth_packet& inpacket) = 0;
-  virtual bx_bool ishandler(const eth_packet& outpacket) = 0;
-  virtual bx_bool sendpacket(const eth_packet& outpacket) = 0;
-};
-
-
-class eth_ARPmaker : public eth_packetmaker {
-public:
-  void init(void);
-  bx_bool ishandler(const eth_packet& outpacket);
-  bx_bool sendpacket(const eth_packet& outpacket);
-  bx_bool getpacket(eth_packet& inpacket);
-private:
-  eth_packet pending;
-  bx_bool is_pending;
-};
-
-
-class eth_IPmaker : eth_packetmaker {
-public:
-  void init(void);
-  virtual bx_bool ishandler(const eth_packet& outpacket)=0;
-  virtual bx_bool sendpacket(const eth_packet& outpacket)=0;
-  virtual bx_bool getpacket(eth_packet& inpacket)=0;
-
-protected:
-  bx_bool sendable(const eth_packet& outpacket);
-
-  Bit32u source(const eth_packet& outpacket);
-  Bit32u destination(const eth_packet& outpacket);
-  Bit8u protocol(const eth_packet& outpacket);
-
-  const Bit8u * datagram(const eth_packet& outpacket);
-  Bit32u datalen(const eth_packet& outpacket);
-
-  //Build a header in pending, return header length in bytes.
-  Bit32u build_packet_header(Bit32u source, Bit32u dest, Bit8u protocol, Bit32u datalen);
-
-  eth_packet pending;
-  bx_bool is_pending;
-
-  //Bit8u Version; //=4 (4 bits)
-  //It better be!
-
-  //Bit8u IHL; //Header length in 32-bit bytes (4 bits)
-  //Used to strip layer
-
-  //Bit8u Type_of_Service; //not relevent, set to 0;
-  //Ignore on receive, set to 0 on send.
-
-  //Bit16u Total_Length;//length of the datagram in octets. use 576 or less;
-  //Use 576 or less on send.
-  //Use to get length on receive
-
-  //Bit16u Identification;//Identifier for assembling fragments
-  //Ignore, we'll drop fragments
-
-  //Bit8u Flags;//0,Don't fragment, More Fragments (vs last fragment)
-  //Set to 0 on send
-  //Drop if more fragments set.
-
-  //Bit16u Fragment Offset;//where in the datagram this fragment belongs
-  //Should be 0 for send and receive.
-
-  //Bit8u TTL;//Set to something sorta big.
-  //Shouldn't be 0 on receive
-  //Set to something big on send
-
-  //Bit8u Protocol;
-  //Defines Protocol.
-  //TCP=?, UDP=?
-
-  //Bit16u Header_Checksum;//16-bit one's complement of the one's complement
-                 //sum of all 16-bit words in header;
-  //Could check on receive, must set on send.
-
-  //Bit32u Source;//source address
-  //Bit32u Destination;//destination address
-};
-
-/*
-class eth_TCPmaker : eth_packetmaker {
-};
-
-class eth_UDPmaker : eth_packetmaker {
-};
-*/
-
-class eth_ETHmaker : public eth_packetmaker {
-public:
-  //handles all packets to a MAC addr.
-  void init(void);
-  virtual bx_bool getpacket(eth_packet& inpacket);
-  virtual bx_bool ishandler(const eth_packet& outpacket);
-  virtual bx_bool sendpacket(const eth_packet& outpacket);
-private:
-  eth_ARPmaker arper;
-};
-
-
-#endif // ETH_ARPBACK
-#endif // _ETH_PACKETMAKER_H_
-
diff --git a/tools/ioemu/iodev/eth_tap.cc b/tools/ioemu/iodev/eth_tap.cc
deleted file mode 100644 (file)
index cb1bf1d..0000000
+++ /dev/null
@@ -1,370 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: eth_tap.cc,v 1.16 2003/10/02 11:33:41 danielg4 Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2001  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-// eth_tap.cc  - TAP interface by Bryce Denney
-//
-// Here's how to get this working.  On the host machine:
-//    $ su root
-//    # /sbin/insmod ethertap
-//    Using /lib/modules/2.2.14-5.0/net/ethertap.o
-//    # mknod /dev/tap0 c 36 16          # if not already there
-//    # /sbin/ifconfig tap0 10.0.0.1
-//    # /sbin/route add -host 10.0.0.2 gw 10.0.0.1
-//
-// Now you have a tap0 device which you can on the ifconfig output.  The
-// tap0 interface has the IP address of 10.0.0.1.  The bochs machine will have
-// the IP address 10.0.0.2.
-//
-// Compile a bochs version from March 8, 2002 or later with --enable-ne2000.
-// Add this ne2k line to your .bochsrc to activate the tap device.
-//   ne2k: ioaddr=0x280, irq=9, mac=fe:fd:00:00:00:01, ethmod=tap, ethdev=tap0
-// Don't change the mac or ethmod!
-//
-// Boot up DLX Linux in Bochs.  Log in as root and then type the following
-// commands to set up networking:
-//   # ifconfig eth0 10.0.0.2
-//   # route add -net 10.0.0.0
-//   # route add default gw 10.0.0.1
-// Now you should be able to ping from guest OS to your host machine, if
-// you give its IP number.  I'm still having trouble with pings from the
-// host machine to the guest, so something is still not right.  Symptoms: I
-// ping from the host to the guest's IP address 10.0.0.2.  With tcpdump I can
-// see the ping going to Bochs, and then the ping reply coming from Bochs.
-// But the ping program itself does not see the responses....well every
-// once in a while it does, like 1 in 60 pings.
-//
-// host$ ping 10.0.0.2
-// PING 10.0.0.2 (10.0.0.2) from 10.0.0.1 : 56(84) bytes of data.
-// 
-// Netstat output:
-// 20:29:59.018776 fe:fd:0:0:0:0 fe:fd:0:0:0:1 0800 98: 10.0.0.1 > 10.0.0.2: icmp: echo request
-//      4500 0054 2800 0000 4001 3ea7 0a00 0001
-//      0a00 0002 0800 09d3 a53e 0400 9765 893c
-//      3949 0000 0809 0a0b 0c0d 0e0f 1011 1213
-//      1415 1617 1819
-// 20:29:59.023017 fe:fd:0:0:0:1 fe:fd:0:0:0:0 0800 98: 10.0.0.2 > 10.0.0.1: icmp: echo reply
-//      4500 0054 004a 0000 4001 665d 0a00 0002
-//      0a00 0001 0000 11d3 a53e 0400 9765 893c
-//      3949 0000 0809 0a0b 0c0d 0e0f 1011 1213
-//      1415 1617 1819
-//
-// I suspect it may be related to the fact that ping 10.0.0.1 from the 
-// host also doesn't work.  Why wouldn't the host respond to its own IP 
-// address on the tap0 device?
-//
-// Theoretically, if you set up packet forwarding (with masquerading) on the
-// host, you should be able to get Bochs talking to anyone on the internet.
-// 
-
-// Define BX_PLUGGABLE in files that can be compiled into plugins.  For
-// platforms that require a special tag on exported symbols, BX_PLUGGABLE 
-// is used to know when we are exporting symbols and when we are importing.
-#define BX_PLUGGABLE
-#include "bochs.h"
-#if BX_NE2K_SUPPORT
-
-#define LOG_THIS bx_devices.pluginNE2kDevice->
-
-#include <signal.h>
-#include <sys/param.h>
-#include <sys/ioctl.h>
-#ifndef __APPLE__
-#include <sys/poll.h>
-#endif
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <sys/socket.h>
-#include <sys/uio.h>
-#include <sys/wait.h>
-#if defined(__FreeBSD__) || defined(__APPLE__)  // Should be fixed for other *BSD
-#include <net/if.h>
-#else
-#include <asm/types.h>
-#include <linux/netlink.h>
-#include <linux/if.h>
-#endif
-#include <assert.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#define TAP_VIRTUAL_HW_ADDR             0xDEADBEEF
-#define BX_ETH_TAP_LOGGING 1
-#define BX_PACKET_BUFSIZ 2048  // Enough for an ether frame
-
-//
-//  Define the class. This is private to this module
-//
-class bx_tap_pktmover_c : public eth_pktmover_c {
-public:
-  bx_tap_pktmover_c(const char *netif, const char *macaddr,
-                    eth_rx_handler_t rxh,
-                    void *rxarg);
-  void sendpkt(void *buf, unsigned io_len);
-private:
-  int fd;
-  int rx_timer_index;
-  static void rx_timer_handler(void *);
-  void rx_timer ();
-  FILE *txlog, *txlog_txt, *rxlog, *rxlog_txt;
-};
-
-
-//
-//  Define the static class that registers the derived pktmover class,
-// and allocates one on request.
-//
-class bx_tap_locator_c : public eth_locator_c {
-public:
-  bx_tap_locator_c(void) : eth_locator_c("tap") {}
-protected:
-  eth_pktmover_c *allocate(const char *netif, const char *macaddr,
-                          eth_rx_handler_t rxh,
-                          void *rxarg) {
-    return (new bx_tap_pktmover_c(netif, macaddr, rxh, rxarg));
-  }
-} bx_tap_match;
-
-
-//
-// Define the methods for the bx_tap_pktmover derived class
-//
-
-// the constructor
-bx_tap_pktmover_c::bx_tap_pktmover_c(const char *netif, 
-                                      const char *macaddr,
-                                      eth_rx_handler_t rxh,
-                                      void *rxarg)
-{
-  int flags;
-  char filename[BX_PATHNAME_LEN];
-  if (strncmp (netif, "tap", 3) != 0) {
-    BX_PANIC (("eth_tap: interface name (%s) must be tap0..tap15", netif));
-  }
-  sprintf (filename, "/dev/%s", netif);
-
-#if defined(__linux__)
-  // check if the TAP devices is running, and turn on ARP.  This is based
-  // on code from the Mac-On-Linux project. http://http://www.maconlinux.org/
-  int sock = socket( AF_INET, SOCK_DGRAM, 0 );
-  if (sock < 0) {
-    BX_PANIC (("socket creation: %s", strerror(errno)));
-    return;
-  }
-  struct ifreq ifr;
-  memset( &ifr, 0, sizeof(ifr) );
-  strncpy( ifr.ifr_name, netif, sizeof(ifr.ifr_name) );
-  if( ioctl( sock, SIOCGIFFLAGS, &ifr ) < 0 ){
-    BX_PANIC (("SIOCGIFFLAGS on %s: %s", netif, strerror (errno)));
-    close(sock);
-    return;
-  }
-  if( !(ifr.ifr_flags & IFF_RUNNING ) ){
-    BX_PANIC (("%s device is not running", netif));
-    close(sock);
-    return;
-  }
-  if( (ifr.ifr_flags & IFF_NOARP ) ){
-    BX_INFO (("turn on ARP for %s device", netif));
-    ifr.ifr_flags &= ~IFF_NOARP;
-    if( ioctl( sock, SIOCSIFFLAGS, &ifr ) < 0 ) {
-      BX_PANIC (("SIOCSIFFLAGS: %s", strerror(errno)));
-      close(sock);
-      return;
-    }
-  }
-  close(sock);
-#endif
-
-  fd = open (filename, O_RDWR);
-  if (fd < 0) {
-    BX_PANIC (("open failed on %s: %s", netif, strerror (errno)));
-    return;
-  }
-
-  /* set O_ASYNC flag so that we can poll with read() */
-  if ((flags = fcntl( fd, F_GETFL)) < 0) {
-    BX_PANIC (("getflags on tap device: %s", strerror (errno)));
-  }
-  flags |= O_NONBLOCK;
-  if (fcntl( fd, F_SETFL, flags ) < 0) {
-    BX_PANIC (("set tap device flags: %s", strerror (errno)));
-  }
-
-  BX_INFO (("eth_tap: opened %s device", netif));
-
-  /* Execute the configuration script */
-  char intname[IFNAMSIZ];
-  strcpy(intname,netif);
-  char *scriptname=bx_options.ne2k.Oscript->getptr();
-  if((scriptname != NULL)
-   &&(strcmp(scriptname, "") != 0)
-   &&(strcmp(scriptname, "none") != 0)) {
-    if (execute_script(scriptname, intname) < 0)
-      BX_ERROR (("execute script '%s' on %s failed", scriptname, intname));
-    }
-
-  // Start the rx poll 
-  this->rx_timer_index = 
-    bx_pc_system.register_timer(this, this->rx_timer_handler, 1000,
-                               1, 1, "eth_tap"); // continuous, active
-  this->rxh   = rxh;
-  this->rxarg = rxarg;
-#if BX_ETH_TAP_LOGGING
-  // eventually Bryce wants txlog to dump in pcap format so that
-  // tcpdump -r FILE can read it and interpret packets.
-  txlog = fopen ("ne2k-tx.log", "wb");
-  if (!txlog) BX_PANIC (("open ne2k-tx.log failed"));
-  txlog_txt = fopen ("ne2k-txdump.txt", "wb");
-  if (!txlog_txt) BX_PANIC (("open ne2k-txdump.txt failed"));
-  fprintf (txlog_txt, "tap packetmover readable log file\n");
-  fprintf (txlog_txt, "net IF = %s\n", netif);
-  fprintf (txlog_txt, "MAC address = ");
-  for (int i=0; i<6; i++) 
-    fprintf (txlog_txt, "%02x%s", 0xff & macaddr[i], i<5?":" : "");
-  fprintf (txlog_txt, "\n--\n");
-  fflush (txlog_txt);
-
-  rxlog = fopen ("ne2k-rx.log", "wb");
-  if (!rxlog) BX_PANIC (("open ne2k-rx.log failed"));
-  rxlog_txt = fopen ("ne2k-rxdump.txt", "wb");
-  if (!rxlog_txt) BX_PANIC (("open ne2k-rxdump.txt failed"));
-  fprintf (rxlog_txt, "tap packetmover readable log file\n");
-  fprintf (rxlog_txt, "net IF = %s\n", netif);
-  fprintf (rxlog_txt, "MAC address = ");
-  for (int i=0; i<6; i++) 
-    fprintf (rxlog_txt, "%02x%s", 0xff & macaddr[i], i<5?":" : "");
-  fprintf (rxlog_txt, "\n--\n");
-  fflush (rxlog_txt);
-
-#endif
-}
-
-void
-bx_tap_pktmover_c::sendpkt(void *buf, unsigned io_len)
-{
-  Bit8u txbuf[BX_PACKET_BUFSIZ];
-  txbuf[0] = 0;
-  txbuf[1] = 0;
-#if defined(__FreeBSD__) || defined(__APPLE__)  // Should be fixed for other *BSD
-  memcpy (txbuf, buf, io_len);
-  unsigned int size = write (fd, txbuf, io_len);
-  if (size != io_len) {
-#else
-  memcpy (txbuf+2, buf, io_len);
-  unsigned int size = write (fd, txbuf, io_len+2);
-  if (size != io_len+2) {
-#endif
-    BX_PANIC (("write on tap device: %s", strerror (errno)));
-  } else {
-    BX_INFO (("wrote %d bytes + 2 byte pad on tap", io_len));
-  }
-#if BX_ETH_TAP_LOGGING
-  BX_DEBUG (("sendpkt length %u", io_len));
-  // dump raw bytes to a file, eventually dump in pcap format so that
-  // tcpdump -r FILE can interpret them for us.
-  int n = fwrite (buf, io_len, 1, txlog);
-  if (n != 1) BX_ERROR (("fwrite to txlog failed, io_len = %u", io_len));
-  // dump packet in hex into an ascii log file
-  fprintf (txlog_txt, "NE2K transmitting a packet, length %u\n", io_len);
-  Bit8u *charbuf = (Bit8u *)buf;
-  for (n=0; n<(int)io_len; n++) {
-    if (((n % 16) == 0) && n>0)
-      fprintf (txlog_txt, "\n");
-    fprintf (txlog_txt, "%02x ", charbuf[n]);
-  }
-  fprintf (txlog_txt, "\n--\n");
-  // flush log so that we see the packets as they arrive w/o buffering
-  fflush (txlog);
-  fflush (txlog_txt);
-#endif
-}
-
-void bx_tap_pktmover_c::rx_timer_handler (void *this_ptr)
-{
-  bx_tap_pktmover_c *class_ptr = (bx_tap_pktmover_c *) this_ptr;
-  class_ptr->rx_timer();
-}
-
-void bx_tap_pktmover_c::rx_timer ()
-{
-  int nbytes;
-  Bit8u buf[BX_PACKET_BUFSIZ];
-  Bit8u *rxbuf;
-  if (fd<0) return;
-  nbytes = read (fd, buf, sizeof(buf));
-
-  // hack: discard first two bytes
-#if defined(__FreeBSD__) || defined(__APPLE__)  // Should be fixed for other *BSD
-  rxbuf = buf;
-#else
-  rxbuf = buf+2;
-  nbytes-=2;
-#endif
-  
-  // hack: TAP device likes to create an ethernet header which has
-  // the same source and destination address FE:FD:00:00:00:00.
-  // Change the dest address to FE:FD:00:00:00:01.
-#if defined(__linux__)
-  rxbuf[5] = 1;
-#endif
-
-  if (nbytes>0)
-    BX_INFO (("tap read returned %d bytes", nbytes));
-  if (nbytes<0) {
-    if (errno != EAGAIN)
-      BX_ERROR (("tap read error: %s", strerror(errno)));
-    return;
-  }
-#if BX_ETH_TAP_LOGGING
-  if (nbytes > 0) {
-    BX_DEBUG (("receive packet length %u", nbytes));
-    // dump raw bytes to a file, eventually dump in pcap format so that
-    // tcpdump -r FILE can interpret them for us.
-    int n = fwrite (rxbuf, nbytes, 1, rxlog);
-    if (n != 1) BX_ERROR (("fwrite to rxlog failed, nbytes = %d", nbytes));
-    // dump packet in hex into an ascii log file
-    fprintf (rxlog_txt, "NE2K received a packet, length %u\n", nbytes);
-    for (n=0; n<nbytes; n++) {
-      if (((n % 16) == 0) && n>0)
-       fprintf (rxlog_txt, "\n");
-      fprintf (rxlog_txt, "%02x ", rxbuf[n]);
-    }
-    fprintf (rxlog_txt, "\n--\n");
-    // flush log so that we see the packets as they arrive w/o buffering
-    fflush (rxlog);
-    fflush (rxlog_txt);
-  }
-#endif
-  BX_DEBUG(("eth_tap: got packet: %d bytes, dst=%x:%x:%x:%x:%x:%x, src=%x:%x:%x:%x:%x:%x\n", nbytes, rxbuf[0], rxbuf[1], rxbuf[2], rxbuf[3], rxbuf[4], rxbuf[5], rxbuf[6], rxbuf[7], rxbuf[8], rxbuf[9], rxbuf[10], rxbuf[11]));
-  if (nbytes < 60) {
-    BX_INFO (("packet too short (%d), padding to 60", nbytes));
-    nbytes = 60;
-  }
-  (*rxh)(rxarg, rxbuf, nbytes);
-}
-
-#endif /* if BX_NE2K_SUPPORT */
diff --git a/tools/ioemu/iodev/eth_tuntap.cc b/tools/ioemu/iodev/eth_tuntap.cc
deleted file mode 100644 (file)
index f910fd5..0000000
+++ /dev/null
@@ -1,401 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: eth_tuntap.cc,v 1.9 2003/04/26 14:48:45 cbothamy Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2001  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-// eth_tuntap.cc  - TUN/TAP interface by Renzo Davoli <renzo@cs.unibo.it>
-//
-// WARNING: These instructions were written for ethertap, not TUN/TAP.
-//
-// Here's how to get this working.  On the host machine:
-//    $ su root
-//    # /sbin/insmod ethertap
-//    Using /lib/modules/2.2.14-5.0/net/ethertap.o
-//    # mknod /dev/tap0 c 36 16          # if not already there
-//    # /sbin/ifconfig tap0 10.0.0.1
-//    # /sbin/route add -host 10.0.0.2 gw 10.0.0.1
-//
-// Now you have a tap0 device which you can on the ifconfig output.  The
-// tap0 interface has the IP address of 10.0.0.1.  The bochs machine will have
-// the IP address 10.0.0.2.
-//
-// Compile a bochs version from March 8, 2002 or later with --enable-ne2000.
-// Add this ne2k line to your .bochsrc to activate the tap device.
-//   ne2k: ioaddr=0x280, irq=9, mac=fe:fd:00:00:00:01, ethmod=tap, ethdev=tap0
-// Don't change the mac or ethmod!
-//
-// Boot up DLX Linux in Bochs.  Log in as root and then type the following
-// commands to set up networking:
-//   # ifconfig eth0 10.0.0.2
-//   # route add -net 10.0.0.0
-//   # route add default gw 10.0.0.1
-// Now you should be able to ping from guest OS to your host machine, if
-// you give its IP number.  I'm still having trouble with pings from the
-// host machine to the guest, so something is still not right.  Symptoms: I
-// ping from the host to the guest's IP address 10.0.0.2.  With tcpdump I can
-// see the ping going to Bochs, and then the ping reply coming from Bochs.
-// But the ping program itself does not see the responses....well every
-// once in a while it does, like 1 in 60 pings.
-//
-// host$ ping 10.0.0.2
-// PING 10.0.0.2 (10.0.0.2) from 10.0.0.1 : 56(84) bytes of data.
-// 
-// Netstat output:
-// 20:29:59.018776 fe:fd:0:0:0:0 fe:fd:0:0:0:1 0800 98: 10.0.0.1 > 10.0.0.2: icmp: echo request
-//      4500 0054 2800 0000 4001 3ea7 0a00 0001
-//      0a00 0002 0800 09d3 a53e 0400 9765 893c
-//      3949 0000 0809 0a0b 0c0d 0e0f 1011 1213
-//      1415 1617 1819
-// 20:29:59.023017 fe:fd:0:0:0:1 fe:fd:0:0:0:0 0800 98: 10.0.0.2 > 10.0.0.1: icmp: echo reply
-//      4500 0054 004a 0000 4001 665d 0a00 0002
-//      0a00 0001 0000 11d3 a53e 0400 9765 893c
-//      3949 0000 0809 0a0b 0c0d 0e0f 1011 1213
-//      1415 1617 1819
-//
-// I suspect it may be related to the fact that ping 10.0.0.1 from the 
-// host also doesn't work.  Why wouldn't the host respond to its own IP 
-// address on the tap0 device?
-//
-// Theoretically, if you set up packet forwarding (with masquerading) on the
-// host, you should be able to get Bochs talking to anyone on the internet.
-// 
-
-// Define BX_PLUGGABLE in files that can be compiled into plugins.  For
-// platforms that require a special tag on exported symbols, BX_PLUGGABLE 
-// is used to know when we are exporting symbols and when we are importing.
-#define BX_PLUGGABLE
-#include "bochs.h"
-#if BX_NE2K_SUPPORT
-
-#define LOG_THIS bx_devices.pluginNE2kDevice->
-
-#include <signal.h>
-#include <sys/param.h>
-#include <sys/ioctl.h>
-#include <sys/poll.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <asm/types.h>
-#include <sys/socket.h>
-#include <sys/uio.h>
-#include <sys/wait.h>
-#include <linux/netlink.h>
-#include <linux/if.h>
-#include <linux/if_tun.h>
-#include <assert.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#define TUNTAP_VIRTUAL_HW_ADDR             0xDEADBEEF
-#define BX_ETH_TUNTAP_LOGGING 0
-#define BX_PACKET_BUFSIZ 2048  // Enough for an ether frame
-
-int tun_alloc(char *dev);
-
-//
-//  Define the class. This is private to this module
-//
-class bx_tuntap_pktmover_c : public eth_pktmover_c {
-public:
-  bx_tuntap_pktmover_c(const char *netif, const char *macaddr,
-                    eth_rx_handler_t rxh,
-                    void *rxarg);
-  void sendpkt(void *buf, unsigned io_len);
-private:
-  int fd;
-  int rx_timer_index;
-  static void rx_timer_handler(void *);
-  void rx_timer ();
-  FILE *txlog, *txlog_txt, *rxlog, *rxlog_txt;
-};
-
-
-//
-//  Define the static class that registers the derived pktmover class,
-// and allocates one on request.
-//
-class bx_tuntap_locator_c : public eth_locator_c {
-public:
-  bx_tuntap_locator_c(void) : eth_locator_c("tuntap") {}
-protected:
-  eth_pktmover_c *allocate(const char *netif, const char *macaddr,
-                          eth_rx_handler_t rxh,
-                          void *rxarg) {
-    return (new bx_tuntap_pktmover_c(netif, macaddr, rxh, rxarg));
-  }
-} bx_tuntap_match;
-
-
-//
-// Define the methods for the bx_tuntap_pktmover derived class
-//
-
-// the constructor
-bx_tuntap_pktmover_c::bx_tuntap_pktmover_c(const char *netif, 
-                                      const char *macaddr,
-                                      eth_rx_handler_t rxh,
-                                      void *rxarg)
-{
-  int flags;
-  if (strncmp (netif, "tun", 3) != 0) {
-    BX_PANIC (("eth_tuntap: interface name (%s) must be tun", netif));
-  }
-#ifdef NEVERDEF
-  char filename[BX_PATHNAME_LEN];
-  sprintf (filename, "/dev/net/%s", netif);
-
-  // check if the TUN/TAP devices is running, and turn on ARP.  This is based
-  // on code from the Mac-On-Linux project. http://http://www.maconlinux.org/
-  int sock = socket( AF_INET, SOCK_DGRAM, 0 );
-  if (sock < 0) {
-    BX_PANIC (("socket creation: %s", strerror(errno)));
-    return;
-  }
-  struct ifreq ifr;
-  memset( &ifr, 0, sizeof(ifr) );
-  strncpy( ifr.ifr_name, netif, sizeof(ifr.ifr_name) );
-  if( ioctl( sock, SIOCGIFFLAGS, &ifr ) < 0 ){
-    BX_PANIC (("SIOCGIFFLAGS on %s: %s", netif, strerror (errno)));
-    close(sock);
-    return;
-  }
-  if( !(ifr.ifr_flags & IFF_RUNNING ) ){
-    BX_PANIC (("%s device is not running", netif));
-    close(sock);
-    return;
-  }
-  if( (ifr.ifr_flags & IFF_NOARP ) ){
-    BX_INFO (("turn on ARP for %s device", netif));
-    ifr.ifr_flags &= ~IFF_NOARP;
-    if( ioctl( sock, SIOCSIFFLAGS, &ifr ) < 0 ) {
-      BX_PANIC (("SIOCSIFFLAGS: %s", strerror(errno)));
-      close(sock);
-      return;
-    }
-  }
-  close(sock);
-
-  fd = open (filename, O_RDWR);
-#endif 
-  char intname[IFNAMSIZ];
-  strcpy(intname,netif);
-  fd=tun_alloc(intname);
-  if (fd < 0) {
-    BX_PANIC (("open failed on %s: %s", netif, strerror (errno)));
-    return;
-  }
-
-  /* set O_ASYNC flag so that we can poll with read() */
-  if ((flags = fcntl( fd, F_GETFL)) < 0) {
-    BX_PANIC (("getflags on tun device: %s", strerror (errno)));
-  }
-  flags |= O_NONBLOCK;
-  if (fcntl( fd, F_SETFL, flags ) < 0) {
-    BX_PANIC (("set tun device flags: %s", strerror (errno)));
-  }
-
-  BX_INFO (("eth_tuntap: opened %s device", netif));
-
-  /* Execute the configuration script */
-  char *scriptname=bx_options.ne2k.Oscript->getptr();
-  if((scriptname != NULL)
-   &&(strcmp(scriptname, "") != 0)
-   &&(strcmp(scriptname, "none") != 0)) {
-    if (execute_script(scriptname, intname) < 0)
-      BX_ERROR (("execute script '%s' on %s failed", scriptname, intname));
-    }
-
-  // Start the rx poll 
-  this->rx_timer_index = 
-    bx_pc_system.register_timer(this, this->rx_timer_handler, 1000,
-                               1, 1, "eth_tuntap"); // continuous, active
-  this->rxh   = rxh;
-  this->rxarg = rxarg;
-#if BX_ETH_TUNTAP_LOGGING
-  // eventually Bryce wants txlog to dump in pcap format so that
-  // tcpdump -r FILE can read it and interpret packets.
-  txlog = fopen ("ne2k-tx.log", "wb");
-  if (!txlog) BX_PANIC (("open ne2k-tx.log failed"));
-  txlog_txt = fopen ("ne2k-txdump.txt", "wb");
-  if (!txlog_txt) BX_PANIC (("open ne2k-txdump.txt failed"));
-  fprintf (txlog_txt, "tuntap packetmover readable log file\n");
-  fprintf (txlog_txt, "net IF = %s\n", netif);
-  fprintf (txlog_txt, "MAC address = ");
-  for (int i=0; i<6; i++) 
-    fprintf (txlog_txt, "%02x%s", 0xff & macaddr[i], i<5?":" : "");
-  fprintf (txlog_txt, "\n--\n");
-  fflush (txlog_txt);
-
-  rxlog = fopen ("ne2k-rx.log", "wb");
-  if (!rxlog) BX_PANIC (("open ne2k-rx.log failed"));
-  rxlog_txt = fopen ("ne2k-rxdump.txt", "wb");
-  if (!rxlog_txt) BX_PANIC (("open ne2k-rxdump.txt failed"));
-  fprintf (rxlog_txt, "tuntap packetmover readable log file\n");
-  fprintf (rxlog_txt, "net IF = %s\n", netif);
-  fprintf (rxlog_txt, "MAC address = ");
-  for (int i=0; i<6; i++) 
-    fprintf (rxlog_txt, "%02x%s", 0xff & macaddr[i], i<5?":" : "");
-  fprintf (rxlog_txt, "\n--\n");
-  fflush (rxlog_txt);
-
-#endif
-}
-
-void
-bx_tuntap_pktmover_c::sendpkt(void *buf, unsigned io_len)
-{
-#ifdef NEVERDEF
-  Bit8u txbuf[BX_PACKET_BUFSIZ];
-  txbuf[0] = 0;
-  txbuf[1] = 0;
-  memcpy (txbuf+2, buf, io_len);
-  unsigned int size = write (fd, txbuf, io_len+2);
-  if (size != io_len+2) {
-    BX_PANIC (("write on tuntap device: %s", strerror (errno)));
-  } else {
-    BX_INFO (("wrote %d bytes + 2 byte pad on tuntap", io_len));
-  }
-#endif
-  unsigned int size = write (fd, buf, io_len);
-  if (size != io_len) {
-    BX_PANIC (("write on tuntap device: %s", strerror (errno)));
-  } else {
-    BX_INFO (("wrote %d bytes on tuntap", io_len));
-  }
-#if BX_ETH_TUNTAP_LOGGING
-  BX_DEBUG (("sendpkt length %u", io_len));
-  // dump raw bytes to a file, eventually dump in pcap format so that
-  // tcpdump -r FILE can interpret them for us.
-  int n = fwrite (buf, io_len, 1, txlog);
-  if (n != 1) BX_ERROR (("fwrite to txlog failed", io_len));
-  // dump packet in hex into an ascii log file
-  fprintf (txlog_txt, "NE2K transmitting a packet, length %u\n", io_len);
-  Bit8u *charbuf = (Bit8u *)buf;
-  for (n=0; n<io_len; n++) {
-    if (((n % 16) == 0) && n>0)
-      fprintf (txlog_txt, "\n");
-    fprintf (txlog_txt, "%02x ", charbuf[n]);
-  }
-  fprintf (txlog_txt, "\n--\n");
-  // flush log so that we see the packets as they arrive w/o buffering
-  fflush (txlog);
-  fflush (txlog_txt);
-#endif
-}
-
-void bx_tuntap_pktmover_c::rx_timer_handler (void *this_ptr)
-{
-  bx_tuntap_pktmover_c *class_ptr = (bx_tuntap_pktmover_c *) this_ptr;
-  class_ptr->rx_timer();
-}
-
-void bx_tuntap_pktmover_c::rx_timer ()
-{
-  int nbytes;
-  Bit8u buf[BX_PACKET_BUFSIZ];
-  Bit8u *rxbuf;
-  if (fd<0) return;
-  nbytes = read (fd, buf, sizeof(buf));
-
-#ifdef NEVERDEF
-  // hack: discard first two bytes
-  rxbuf = buf+2;
-  nbytes-=2;
-#else
-  rxbuf=buf;
-#endif
-
-  // hack: TUN/TAP device likes to create an ethernet header which has
-  // the same source and destination address FE:FD:00:00:00:00.
-  // Change the dest address to FE:FD:00:00:00:01.
-  rxbuf[5] = 1;
-
-  if (nbytes>0)
-    BX_INFO (("tuntap read returned %d bytes", nbytes));
-  if (nbytes<0) {
-    if (errno != EAGAIN)
-      BX_ERROR (("tuntap read error: %s", strerror(errno)));
-    return;
-  }
-#if BX_ETH_TUNTAP_LOGGING
-  if (nbytes > 0) {
-    BX_DEBUG (("receive packet length %u", nbytes));
-    // dump raw bytes to a file, eventually dump in pcap format so that
-    // tcpdump -r FILE can interpret them for us.
-    int n = fwrite (rxbuf, nbytes, 1, rxlog);
-    if (n != 1) BX_ERROR (("fwrite to rxlog failed", nbytes));
-    // dump packet in hex into an ascii log file
-    fprintf (rxlog_txt, "NE2K received a packet, length %u\n", nbytes);
-    for (n=0; n<nbytes; n++) {
-      if (((n % 16) == 0) && n>0)
-       fprintf (rxlog_txt, "\n");
-      fprintf (rxlog_txt, "%02x ", rxbuf[n]);
-    }
-    fprintf (rxlog_txt, "\n--\n");
-    // flush log so that we see the packets as they arrive w/o buffering
-    fflush (rxlog);
-    fflush (rxlog_txt);
-  }
-#endif
-  BX_DEBUG(("eth_tuntap: got packet: %d bytes, dst=%x:%x:%x:%x:%x:%x, src=%x:%x:%x:%x:%x:%x\n", nbytes, rxbuf[0], rxbuf[1], rxbuf[2], rxbuf[3], rxbuf[4], rxbuf[5], rxbuf[6], rxbuf[7], rxbuf[8], rxbuf[9], rxbuf[10], rxbuf[11]));
-  if (nbytes < 60) {
-    BX_INFO (("packet too short (%d), padding to 60", nbytes));
-    nbytes = 60;
-  }
-  (*rxh)(rxarg, rxbuf, nbytes);
-}
-
-
-  int tun_alloc(char *dev)
-  {
-      struct ifreq ifr;
-      int fd, err;
-
-      if( (fd = open("/dev/net/tun", O_RDWR)) < 0 )
-         return -1;
-
-      memset(&ifr, 0, sizeof(ifr));
-
-      /* Flags: IFF_TUN   - TUN device (no Ethernet headers) 
-       *        IFF_TAP   - TAP device  
-       *
-       *        IFF_NO_PI - Do not provide packet information  
-       */ 
-      ifr.ifr_flags = IFF_TAP | IFF_NO_PI; 
-      if( *dev )
-         strncpy(ifr.ifr_name, dev, IFNAMSIZ);
-
-      if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ){
-         close(fd);
-         return err;
-      }
-
-      //strcpy(dev, ifr.ifr_name);
-      ioctl( fd, TUNSETNOCSUM, 1 );
-
-      return fd;
-  }              
-
-#endif /* if BX_NE2K_SUPPORT */
diff --git a/tools/ioemu/iodev/extfpuirq.cc b/tools/ioemu/iodev/extfpuirq.cc
deleted file mode 100644 (file)
index 5d1ed98..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: extfpuirq.cc,v 1.5 2003/07/31 12:04:48 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-//
-// External circuit for MSDOS compatible FPU exceptions
-//
-
-// Define BX_PLUGGABLE in files that can be compiled into plugins.  For
-// platforms that require a special tag on exported symbols, BX_PLUGGABLE 
-// is used to know when we are exporting symbols and when we are importing.
-#define BX_PLUGGABLE
-
-#include "bochs.h"
-
-#define LOG_THIS theExternalFpuIrq->
-
-bx_extfpuirq_c *theExternalFpuIrq = NULL;
-
-  int
-libextfpuirq_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
-{
-  theExternalFpuIrq = new bx_extfpuirq_c ();
-  bx_devices.pluginExtFpuIrq = theExternalFpuIrq;
-  BX_REGISTER_DEVICE_DEVMODEL(plugin, type, theExternalFpuIrq, BX_PLUGIN_EXTFPUIRQ);
-  return(0); // Success
-}
-
-  void
-libextfpuirq_LTX_plugin_fini(void)
-{
-}
-
-bx_extfpuirq_c::bx_extfpuirq_c(void)
-{
-  put("EFIRQ");
-  settype(EXTFPUIRQLOG);
-}
-
-bx_extfpuirq_c::~bx_extfpuirq_c(void)
-{
-  // nothing for now
-  BX_DEBUG(("Exit."));
-}
-
-
-  void
-bx_extfpuirq_c::init(void)
-{
-  // called once when bochs initializes
-  DEV_register_iowrite_handler(this, write_handler, 0x00F0, "External FPU IRQ", 1);
-  DEV_register_irq(13, "External FPU IRQ");
-}
-
-  void
-bx_extfpuirq_c::reset(unsigned type)
-{
-  // We should handle IGNNE here
-  DEV_pic_lower_irq(13);
-}
-
-
-  // static IO port write callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-  void
-bx_extfpuirq_c::write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len)
-{
-#if !BX_USE_EFI_SMF
-  bx_extfpuirq_c *class_ptr = (bx_extfpuirq_c *) this_ptr;
-
-  class_ptr->write(address, value, io_len);
-}
-
-  void
-bx_extfpuirq_c::write(Bit32u address, Bit32u value, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif // !BX_USE_EFI_SMF
-
-  // We should handle IGNNE here
-  DEV_pic_lower_irq(13);
-}
-
diff --git a/tools/ioemu/iodev/extfpuirq.h b/tools/ioemu/iodev/extfpuirq.h
deleted file mode 100644 (file)
index c32e71a..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: extfpuirq.h,v 1.2 2003/01/07 08:17:15 cbothamy Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-#if BX_USE_EFI_SMF
-#  define BX_EXTFPUIRQ_SMF  static
-#  define BX_EXTFPUIRQ_THIS theExternalFpuIrq->
-#else
-#  define BX_EXTFPUIRQ_SMF
-#  define BX_EXTFPUIRQ_THIS this->
-#endif
-
-
-class bx_extfpuirq_c : public bx_devmodel_c {
-
-public:
-  bx_extfpuirq_c(void);
-  ~bx_extfpuirq_c(void);
-  virtual void   init(void);
-  virtual void   reset(unsigned type);
-
-private:
-
-  static void   write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);
-#if !BX_USE_EFI_SMF
-  void   write(Bit32u address, Bit32u value, unsigned io_len);
-#endif
-  };
diff --git a/tools/ioemu/iodev/floppy.cc b/tools/ioemu/iodev/floppy.cc
deleted file mode 100644 (file)
index e4090d5..0000000
+++ /dev/null
@@ -1,1633 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: floppy.cc,v 1.69 2003/12/18 20:04:49 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-//
-//
-// Floppy Disk Controller Docs:
-// Intel 82077A Data sheet
-//   ftp://void-core.2y.net/pub/docs/fdc/82077AA_FloppyControllerDatasheet.pdf
-// Intel 82078 Data sheet
-//   ftp://download.intel.com/design/periphrl/datashts/29047403.PDF
-// Other FDC references
-//   http://debs.future.easyspace.com/Programming/Hardware/FDC/floppy.html
-// And a port list:
-//   http://mudlist.eorbit.net/~adam/pickey/ports.html
-//
-
-// Define BX_PLUGGABLE in files that can be compiled into plugins.  For
-// platforms that require a special tag on exported symbols, BX_PLUGGABLE 
-// is used to know when we are exporting symbols and when we are importing.
-#define BX_PLUGGABLE
-
-
-extern "C" {
-#include <errno.h>
-}
-
-#ifdef __linux__
-extern "C" {
-#include <sys/ioctl.h>
-#include <linux/fd.h>
-}
-#endif
-#include "bochs.h"
-// windows.h included by bochs.h
-#ifdef WIN32
-extern "C" {
-#include <winioctl.h>
-}
-#endif
-#define LOG_THIS theFloppyController->
-
-bx_floppy_ctrl_c *theFloppyController;
-
-/* for main status register */
-#define FD_MS_MRQ  0x80
-#define FD_MS_DIO  0x40
-#define FD_MS_NDMA 0x20
-#define FD_MS_BUSY 0x10
-#define FD_MS_ACTD 0x08
-#define FD_MS_ACTC 0x04
-#define FD_MS_ACTB 0x02
-#define FD_MS_ACTA 0x01
-
-#define FROM_FLOPPY 10
-#define TO_FLOPPY   11
-
-#define FLOPPY_DMA_CHAN 2
-
-typedef struct {
-  unsigned id;
-  Bit8u trk;
-  Bit8u hd;
-  Bit8u spt;
-  unsigned sectors;
-} floppy_type_t;
-
-static floppy_type_t floppy_type[8] = {
-  {BX_FLOPPY_160K, 40, 1, 8, 320},
-  {BX_FLOPPY_180K, 40, 1, 9, 360},
-  {BX_FLOPPY_320K, 40, 2, 8, 640},
-  {BX_FLOPPY_360K, 40, 2, 9, 720},
-  {BX_FLOPPY_720K, 80, 2, 9, 1440},
-  {BX_FLOPPY_1_2,  80, 2, 15, 2400},
-  {BX_FLOPPY_1_44, 80, 2, 18, 2880},
-  {BX_FLOPPY_2_88, 80, 2, 36, 5760}
-};
-
-
-  int
-libfloppy_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
-{
-  theFloppyController = new bx_floppy_ctrl_c ();
-  bx_devices.pluginFloppyDevice = theFloppyController;
-  BX_REGISTER_DEVICE_DEVMODEL(plugin, type, theFloppyController, BX_PLUGIN_FLOPPY);
-  return(0); // Success
-}
-
-  void
-libfloppy_LTX_plugin_fini(void)
-{
-}
-
-
-bx_floppy_ctrl_c::bx_floppy_ctrl_c(void)
-{
-  put("FDD");
-  settype(FDLOG);
-  s.floppy_timer_index = BX_NULL_TIMER_HANDLE;
-}
-
-bx_floppy_ctrl_c::~bx_floppy_ctrl_c(void)
-{
-  // nothing for now
-  BX_DEBUG(("Exit."));
-}
-
-
-  void
-bx_floppy_ctrl_c::init(void)
-{
-  Bit8u i;
-
-  BX_DEBUG(("Init $Id: floppy.cc,v 1.69 2003/12/18 20:04:49 vruppert Exp $"));
-  DEV_dma_register_8bit_channel(2, dma_read, dma_write, "Floppy Drive");
-  DEV_register_irq(6, "Floppy Drive");
-  for (unsigned addr=0x03F2; addr<=0x03F7; addr++) {
-    DEV_register_ioread_handler(this, read_handler, addr, "Floppy Drive", 1);
-    DEV_register_iowrite_handler(this, write_handler, addr, "Floppy Drive", 1);
-    }
-
-
-  DEV_cmos_set_reg(0x10, 0x00); /* start out with: no drive 0, no drive 1 */
-
-  BX_FD_THIS s.num_supported_floppies = 0;
-
-  for (i=0; i<4; i++) {
-    BX_FD_THIS s.device_type[i] = BX_FLOPPY_NONE;
-    BX_FD_THIS s.media[i].type = BX_FLOPPY_NONE;
-    }
-
-  //
-  // Floppy A setup
-  //
-  BX_FD_THIS s.media[0].sectors_per_track = 0;
-  BX_FD_THIS s.media[0].tracks            = 0;
-  BX_FD_THIS s.media[0].heads             = 0;
-  BX_FD_THIS s.media[0].sectors           = 0;
-  BX_FD_THIS s.media[0].fd = -1;
-  BX_FD_THIS s.media_present[0] = 0;
-  BX_FD_THIS s.device_type[0] = bx_options.floppya.Odevtype->get ();
-
-  switch (BX_FD_THIS s.device_type[0]) {
-    case BX_FLOPPY_NONE:
-      DEV_cmos_set_reg(0x10, (DEV_cmos_get_reg(0x10) & 0x0f) | 0x00);
-      break;
-    case BX_FLOPPY_360K:
-      DEV_cmos_set_reg(0x10, (DEV_cmos_get_reg(0x10) & 0x0f) | 0x10);
-      break;
-    case BX_FLOPPY_1_2:
-      DEV_cmos_set_reg(0x10, (DEV_cmos_get_reg(0x10) & 0x0f) | 0x20);
-      break;
-    case BX_FLOPPY_720K:
-      DEV_cmos_set_reg(0x10, (DEV_cmos_get_reg(0x10) & 0x0f) | 0x30);
-      break;
-    case BX_FLOPPY_1_44:
-      DEV_cmos_set_reg(0x10, (DEV_cmos_get_reg(0x10) & 0x0f) | 0x40);
-      break;
-    case BX_FLOPPY_2_88:
-      DEV_cmos_set_reg(0x10, (DEV_cmos_get_reg(0x10) & 0x0f) | 0x50);
-      break;
-
-    // use CMOS reserved types
-    case BX_FLOPPY_160K:
-      DEV_cmos_set_reg(0x10, (DEV_cmos_get_reg(0x10) & 0x0f) | 0x60);
-      BX_INFO(("WARNING: 1st floppy uses of reserved CMOS floppy drive type 6"));
-      break;
-    case BX_FLOPPY_180K:
-      DEV_cmos_set_reg(0x10, (DEV_cmos_get_reg(0x10) & 0x0f) | 0x70);
-      BX_INFO(("WARNING: 1st floppy uses of reserved CMOS floppy drive type 7"));
-      break;
-    case BX_FLOPPY_320K:
-      DEV_cmos_set_reg(0x10, (DEV_cmos_get_reg(0x10) & 0x0f) | 0x80);
-      BX_INFO(("WARNING: 1st floppy uses of reserved CMOS floppy drive type 8"));
-      break;
-
-    default:
-      BX_PANIC(("unknown floppya type"));
-    }
-  if (BX_FD_THIS s.device_type[0] != BX_FLOPPY_NONE)
-    BX_FD_THIS s.num_supported_floppies++;
-
-  if (bx_options.floppya.Otype->get () != BX_FLOPPY_NONE) {
-    if ( bx_options.floppya.Ostatus->get () == BX_INSERTED) {
-      if (evaluate_media(bx_options.floppya.Otype->get (), bx_options.floppya.Opath->getptr (),
-                   & BX_FD_THIS s.media[0]))
-        BX_FD_THIS s.media_present[0] = 1;
-      else
-        bx_options.floppya.Ostatus->set(BX_EJECTED);
-#define MED (BX_FD_THIS s.media[0])
-        BX_INFO(("fd0: '%s' ro=%d, h=%d,t=%d,spt=%d", bx_options.floppya.Opath->getptr(),
-        MED.write_protected, MED.heads, MED.tracks, MED.sectors_per_track));
-#undef MED
-      }
-    }
-
-
-  //
-  // Floppy B setup
-  //
-  BX_FD_THIS s.media[1].sectors_per_track = 0;
-  BX_FD_THIS s.media[1].tracks            = 0;
-  BX_FD_THIS s.media[1].heads             = 0;
-  BX_FD_THIS s.media[1].sectors           = 0;
-  BX_FD_THIS s.media[1].fd = -1;
-  BX_FD_THIS s.media_present[1] = 0;
-  BX_FD_THIS s.device_type[1] = bx_options.floppyb.Odevtype->get ();
-
-  switch (BX_FD_THIS s.device_type[1]) {
-    case BX_FLOPPY_NONE:
-      DEV_cmos_set_reg(0x10, (DEV_cmos_get_reg(0x10) & 0xf0) | 0x00);
-      break;
-    case BX_FLOPPY_360K:
-      DEV_cmos_set_reg(0x10, (DEV_cmos_get_reg(0x10) & 0xf0) | 0x01);
-      break;
-    case BX_FLOPPY_1_2:
-      DEV_cmos_set_reg(0x10, (DEV_cmos_get_reg(0x10) & 0xf0) | 0x02);
-      break;
-    case BX_FLOPPY_720K:
-      DEV_cmos_set_reg(0x10, (DEV_cmos_get_reg(0x10) & 0xf0) | 0x03);
-      break;
-    case BX_FLOPPY_1_44:
-      DEV_cmos_set_reg(0x10, (DEV_cmos_get_reg(0x10) & 0xf0) | 0x04);
-      break;
-    case BX_FLOPPY_2_88:
-      DEV_cmos_set_reg(0x10, (DEV_cmos_get_reg(0x10) & 0xf0) | 0x05);
-      break;
-
-    // use CMOS reserved types
-    case BX_FLOPPY_160K:
-      DEV_cmos_set_reg(0x10, (DEV_cmos_get_reg(0x10) & 0xf0) | 0x06);
-      BX_INFO(("WARNING: 2nd floppy uses of reserved CMOS floppy drive type 6"));
-      break;
-    case BX_FLOPPY_180K:
-      DEV_cmos_set_reg(0x10, (DEV_cmos_get_reg(0x10) & 0xf0) | 0x07);
-      BX_INFO(("WARNING: 2nd floppy uses of reserved CMOS floppy drive type 7"));
-      break;
-    case BX_FLOPPY_320K:
-      DEV_cmos_set_reg(0x10, (DEV_cmos_get_reg(0x10) & 0xf0) | 0x08);
-      BX_INFO(("WARNING: 2nd floppy uses of reserved CMOS floppy drive type 8"));
-      break;
-
-    default:
-      BX_PANIC(("unknown floppyb type"));
-    }
-  if (BX_FD_THIS s.device_type[1] != BX_FLOPPY_NONE)
-    BX_FD_THIS s.num_supported_floppies++;
-
-  if (bx_options.floppyb.Otype->get () != BX_FLOPPY_NONE) {
-    if ( bx_options.floppyb.Ostatus->get () == BX_INSERTED) {
-      if (evaluate_media(bx_options.floppyb.Otype->get (), bx_options.floppyb.Opath->getptr (),
-                   & BX_FD_THIS s.media[1]))
-        BX_FD_THIS s.media_present[1] = 1;
-      else
-        bx_options.floppyb.Ostatus->set(BX_EJECTED);
-#define MED (BX_FD_THIS s.media[1])
-        BX_INFO(("fd1: '%s' ro=%d, h=%d,t=%d,spt=%d", bx_options.floppyb.Opath->getptr(),
-        MED.write_protected, MED.heads, MED.tracks, MED.sectors_per_track));
-#undef MED
-      }
-    }
-
-
-
-  /* CMOS Equipment Byte register */
-  if (BX_FD_THIS s.num_supported_floppies > 0) {
-    DEV_cmos_set_reg(0x14, (DEV_cmos_get_reg(0x14) & 0x3e) |
-                          ((BX_FD_THIS s.num_supported_floppies-1) << 6) | 1);
-  }
-  else
-    DEV_cmos_set_reg(0x14, (DEV_cmos_get_reg(0x14) & 0x3e));
-
-
-  if (BX_FD_THIS s.floppy_timer_index == BX_NULL_TIMER_HANDLE) {
-    BX_FD_THIS s.floppy_timer_index =
-      bx_pc_system.register_timer( this, timer_handler,
-      bx_options.Ofloppy_command_delay->get (), 0,0, "floppy");
-  }
-
-  BX_DEBUG(("bx_options.Ofloppy_command_delay = %u",
-    (unsigned) bx_options.Ofloppy_command_delay->get ()));
-}
-
-
-
-  void
-bx_floppy_ctrl_c::reset(unsigned type)
-{
-  Bit32u i;
-
-  BX_FD_THIS s.pending_irq = 0;
-  BX_FD_THIS s.reset_sensei = 0; /* no reset result present */
-
-  BX_FD_THIS s.main_status_reg = 0;
-  BX_FD_THIS s.status_reg0 = 0;
-  BX_FD_THIS s.status_reg1 = 0;
-  BX_FD_THIS s.status_reg2 = 0;
-  BX_FD_THIS s.status_reg3 = 0;
-
-  // software reset (via DOR port 0x3f2 bit 2) does not change DOR
-  if (type == BX_RESET_HARDWARE) {
-    BX_FD_THIS s.DOR = 0x0c;
-    // motor off, drive 3..0
-    // DMA/INT enabled
-    // normal operation
-    // drive select 0
-
-    // DIR and CCR affected only by hard reset
-    for (i=0; i<4; i++) {
-      BX_FD_THIS s.DIR[i] |= 0x80; // disk changed
-      }
-    BX_FD_THIS s.data_rate = 0; /* 500 Kbps */
-    }
-
-  for (i=0; i<4; i++) {
-    BX_FD_THIS s.cylinder[i] = 0;
-    BX_FD_THIS s.head[i] = 0;
-    BX_FD_THIS s.sector[i] = 0;
-    }
-
-  DEV_pic_lower_irq(6);
-  DEV_dma_set_drq(FLOPPY_DMA_CHAN, 0);
-  enter_idle_phase();
-}
-
-
-  // static IO port read callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-  Bit32u
-bx_floppy_ctrl_c::read_handler(void *this_ptr, Bit32u address, unsigned io_len)
-{
-#if !BX_USE_FD_SMF
-  bx_floppy_ctrl_c *class_ptr = (bx_floppy_ctrl_c *) this_ptr;
-
-  return( class_ptr->read(address, io_len) );
-}
-
-
-  /* reads from the floppy io ports */
-  Bit32u
-bx_floppy_ctrl_c::read(Bit32u address, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif  // !BX_USE_FD_SMF
-  Bit8u status, value;
-
-  if (bx_dbg.floppy)
-    BX_INFO(("read access to port %04x", (unsigned) address));
-
-  switch (address) {
-#if BX_DMA_FLOPPY_IO
-    case 0x3F2: // diskette controller digital output register
-      value = BX_FD_THIS s.DOR;
-      return(value);
-      break;
-
-    case 0x3F4: /* diskette controller main status register */
-      status = BX_FD_THIS s.main_status_reg;
-      return(status);
-      break;
-
-    case 0x3F5: /* diskette controller data */
-      if (BX_FD_THIS s.result_size == 0) {
-        BX_ERROR(("port 0x3f5: no results to read"));
-        BX_FD_THIS s.main_status_reg = 0;
-        return BX_FD_THIS s.result[0];
-        }
-
-      value = BX_FD_THIS s.result[BX_FD_THIS s.result_index++];
-      BX_FD_THIS s.main_status_reg &= 0xF0;
-      if (BX_FD_THIS s.result_index >= BX_FD_THIS s.result_size) {
-        if (!BX_FD_THIS s.reset_sensei) BX_FD_THIS s.pending_irq = 0;
-        DEV_pic_lower_irq(6);
-        enter_idle_phase();
-        }
-      return(value);
-      break;
-#endif  // #if BX_DMA_FLOPPY_IO
-
-    case 0x3F3: // Tape Drive Register
-      // see http://www.smsc.com/main/datasheets/37c93x.pdf page 18 for more details
-
-      switch( BX_FD_THIS s.DOR & 0x03 )
-      {
-        case 0x00:
-          if( (BX_FD_THIS s.DOR & 0x10) == 0) break;
-          return(2);
-        case 0x01:
-          if( (BX_FD_THIS s.DOR & 0x20) == 0) break;
-          return(1);
-      }
-      return(3);
-      
-    case 0x3F6: // Reserved for future floppy controllers
-                // This address shared with the hard drive controller
-      value = DEV_hd_read_handler(bx_devices.pluginHardDrive, address, io_len);
-      return( value );
-      break;
-
-    case 0x3F7: // diskette controller digital input register
-      // This address shared with the hard drive controller:
-      //   Bit  7   : floppy
-      //   Bits 6..0: hard drive
-      value = DEV_hd_read_handler(bx_devices.pluginHardDrive, address, io_len);
-      value &= 0x7f;
-      // add in diskette change line
-      value |= (BX_FD_THIS s.DIR[BX_FD_THIS s.DOR & 0x03] & 0x80);
-      return( value );
-      break;
-    default:
-      BX_ERROR(("io_read: unsupported address 0x%04x", (unsigned) address));
-      return(0);
-      break;
-    }
-}
-
-
-  // static IO port write callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-  void
-bx_floppy_ctrl_c::write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len)
-{
-#if !BX_USE_FD_SMF
-  bx_floppy_ctrl_c *class_ptr = (bx_floppy_ctrl_c *) this_ptr;
-
-  class_ptr->write(address, value, io_len);
-}
-
-  /* writes to the floppy io ports */
-  void
-bx_floppy_ctrl_c::write(Bit32u address, Bit32u value, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif  // !BX_USE_FD_SMF
-  Bit8u dma_and_interrupt_enable;
-  Bit8u normal_operation, prev_normal_operation;
-  Bit8u drive_select;
-  Bit8u motor_on_drive0, motor_on_drive1;
-
-  if (bx_dbg.floppy)
-    BX_INFO(("write access to port %04x, value=%02x",
-      (unsigned) address, (unsigned) value));
-
-  switch (address) {
-#if BX_DMA_FLOPPY_IO
-    case 0x3F2: /* diskette controller digital output register */
-      motor_on_drive1 = value & 0x20;
-      motor_on_drive0 = value & 0x10;
-      dma_and_interrupt_enable = value & 0x08;
-      if (!dma_and_interrupt_enable)
-        BX_DEBUG(("DMA and interrupt capabilities disabled"));
-      normal_operation = value & 0x04;
-      drive_select = value & 0x03;
-
-      prev_normal_operation = BX_FD_THIS s.DOR & 0x04;
-      BX_FD_THIS s.DOR = value;
-
-      if (prev_normal_operation==0 && normal_operation) {
-        // transition from RESET to NORMAL
-        bx_pc_system.activate_timer( BX_FD_THIS s.floppy_timer_index,
-             bx_options.Ofloppy_command_delay->get (), 0 );
-        }
-      else if (prev_normal_operation && normal_operation==0) {
-        // transition from NORMAL to RESET
-        BX_FD_THIS s.main_status_reg = FD_MS_BUSY;
-        BX_FD_THIS s.pending_command = 0xfe; // RESET pending
-
-        }
-        BX_DEBUG(("io_write: digital output register"));
-        BX_DEBUG(("  motor on, drive1 = %d", motor_on_drive1 > 0));
-        BX_DEBUG(("  motor on, drive0 = %d", motor_on_drive0 > 0));
-        BX_DEBUG(("  dma_and_interrupt_enable=%02x",
-          (unsigned) dma_and_interrupt_enable));
-        BX_DEBUG(("  normal_operation=%02x",
-          (unsigned) normal_operation));
-        BX_DEBUG(("  drive_select=%02x",
-          (unsigned) drive_select));
-      if (BX_FD_THIS s.device_type[drive_select] == BX_FLOPPY_NONE) {
-        BX_DEBUG(("WARNING: not existing drive selected"));
-        }
-      break;
-
-    case 0x3f4: /* diskette controller data rate select register */
-      BX_ERROR(("io_write: data rate select register unsupported"));
-      break;
-
-    case 0x3F5: /* diskette controller data */
-      BX_DEBUG(("command = %02x", (unsigned) value));
-      if (BX_FD_THIS s.command_complete) {
-        if (BX_FD_THIS s.pending_command!=0)
-          BX_PANIC(("io: 3f5: receiving new comm, old one (%02x) pending",
-            (unsigned) BX_FD_THIS s.pending_command));
-        BX_FD_THIS s.command[0] = value;
-        BX_FD_THIS s.command_complete = 0;
-        BX_FD_THIS s.command_index = 1;
-        /* read/write command in progress */
-        BX_FD_THIS s.main_status_reg = FD_MS_MRQ | FD_MS_BUSY;
-        switch (value) {
-          case 0x03: /* specify */
-            BX_FD_THIS s.command_size = 3;
-            break;
-          case 0x04: // get status
-            BX_FD_THIS s.command_size = 2;
-            break;
-          case 0x07: /* recalibrate */
-            BX_FD_THIS s.command_size = 2;
-            break;
-          case 0x08: /* sense interrupt status */
-            BX_FD_THIS s.command_size = 1;
-            break;
-          case 0x0f: /* seek */
-            BX_FD_THIS s.command_size = 3;
-            break;
-          case 0x4a: /* read ID */
-            BX_FD_THIS s.command_size = 2;
-            break;
-          case 0x4d: /* format track */
-            BX_FD_THIS s.command_size = 6;
-            break;
-          case 0x45:
-          case 0xc5: /* write normal data */
-            BX_FD_THIS s.command_size = 9;
-            break;
-          case 0x46:
-          case 0x66:
-          case 0xc6:
-          case 0xe6: /* read normal data */
-            BX_FD_THIS s.command_size = 9;
-            break;
-
-          case 0x13: // Configure command (Enhanced)
-            BX_FD_THIS s.command_size = 4;
-            break;
-
-          case 0x0e: // dump registers (Enhanced drives)
-          case 0x10: // Version command, standard controller returns 80h
-          case 0x18: // National Semiconductor version command; return 80h
-            // These commands are not implemented on the standard
-            // controller and return an error.  They are available on
-            // the enhanced controller.
-            BX_DEBUG(("io_write: 0x3f5: unsupported floppy command 0x%02x",
-              (unsigned) value));
-            BX_FD_THIS s.command_size = 0;   // make sure we don't try to process this command
-            BX_FD_THIS s.status_reg0 = 0x80; // status: invalid command
-            enter_result_phase();
-            break;
-
-          default:
-            BX_ERROR(("io_write: 0x3f5: invalid floppy command 0x%02x",
-              (unsigned) value));
-            BX_FD_THIS s.command_size = 0;   // make sure we don't try to process this command
-            BX_FD_THIS s.status_reg0 = 0x80; // status: invalid command
-            enter_result_phase();
-            break;
-          }
-        }
-      else {
-        BX_FD_THIS s.command[BX_FD_THIS s.command_index++] =
-          value;
-        }
-      if (BX_FD_THIS s.command_index ==
-        BX_FD_THIS s.command_size) {
-        /* read/write command not in progress any more */
-        floppy_command();
-        BX_FD_THIS s.command_complete = 1;
-        }
-      BX_DEBUG(("io_write: diskette controller data"));
-      return;
-      break;
-#endif  // #if BX_DMA_FLOPPY_IO
-
-    case 0x3F6: /* diskette controller (reserved) */
-      BX_DEBUG(("io_write: reserved register 0x3f6 unsupported"));
-      // this address shared with the hard drive controller
-      DEV_hd_write_handler(bx_devices.pluginHardDrive, address, value, io_len);
-      break;
-
-#if BX_DMA_FLOPPY_IO
-    case 0x3F7: /* diskette controller configuration control register */
-      BX_DEBUG(("io_write: config control register"));
-      BX_FD_THIS s.data_rate = value & 0x03;
-      switch (BX_FD_THIS s.data_rate) {
-        case 0: BX_DEBUG(("  500 Kbps")); break;
-        case 1: BX_DEBUG(("  300 Kbps")); break;
-        case 2: BX_DEBUG(("  250 Kbps")); break;
-        case 3: BX_DEBUG(("  1 Mbps")); break;
-      }
-      return;
-      break;
-
-   default:
-      BX_ERROR(("io_write ignored: 0x%04x = 0x%02x", (unsigned) address, (unsigned) value));
-      break;
-#endif  // #if BX_DMA_FLOPPY_IO
-    }
-}
-
-
-
-  void
-bx_floppy_ctrl_c::floppy_command(void)
-{
-#if BX_PROVIDE_CPU_MEMORY==0
-  BX_PANIC(("floppy_command(): uses DMA: not supported for"
-           " external environment"));
-#else
-  unsigned i;
-  Bit8u step_rate_time;
-  Bit8u head_unload_time;
-  Bit8u head_load_time;
-  Bit8u motor_on;
-  Bit8u head, drive, cylinder, sector, eot;
-  Bit8u sector_size, data_length;
-  Bit32u logical_sector;
-
-
-  BX_DEBUG(("FLOPPY COMMAND: "));
-  for (i=0; i<BX_FD_THIS s.command_size; i++)
-    BX_DEBUG(("[%02x] ", (unsigned) BX_FD_THIS s.command[i]));
-
-#if 0
-  /* execute phase of command is in progress (non DMA mode) */
-  BX_FD_THIS s.main_status_reg |= 20;
-#endif
-
-  BX_FD_THIS s.pending_command = BX_FD_THIS s.command[0];
-  switch (BX_FD_THIS s.pending_command) {
-    case 0x03: // specify
-      // execution: specified parameters are loaded
-      // result: no result bytes, no interrupt
-      step_rate_time = BX_FD_THIS s.command[1] >> 4;
-      head_unload_time = BX_FD_THIS s.command[1] & 0x0f;
-      head_load_time = BX_FD_THIS s.command[2] >> 1;
-      if (BX_FD_THIS s.command[2] & 0x01)
-        BX_ERROR(("non DMA mode selected"));
-      enter_idle_phase();
-      return;
-      break;
-
-    case 0x04: // get status
-      drive = (BX_FD_THIS s.command[1] & 0x03);
-      BX_FD_THIS s.head[drive] = (BX_FD_THIS s.command[1] >> 2) & 0x01;
-      BX_FD_THIS s.status_reg3 = 0x28 | (BX_FD_THIS s.head[drive]<<2) | drive
-        | (BX_FD_THIS s.media[drive].write_protected ? 0x40 : 0x00);
-      if (BX_FD_THIS s.cylinder[drive] == 0) BX_FD_THIS s.status_reg3 |= 0x10;
-      enter_result_phase();
-      return;
-      break;
-
-    case 0x07: // recalibrate
-      drive = (BX_FD_THIS s.command[1] & 0x03);
-      BX_FD_THIS s.DOR &= 0xfc;
-      BX_FD_THIS s.DOR |= drive;
-      BX_DEBUG(("floppy_command(): recalibrate drive %u",
-        (unsigned) drive));
-      motor_on = ( (BX_FD_THIS s.DOR>>(drive+4))
-                     & 0x01 );
-      if (motor_on == 0) {
-        BX_INFO(("floppy_command(): recal drive with motor off"));
-        }
-      if (drive==0)
-        BX_FD_THIS s.DOR |= 0x10; // turn on MOTA
-      else
-        BX_FD_THIS s.DOR |= 0x20; // turn on MOTB
-      bx_pc_system.activate_timer( BX_FD_THIS s.floppy_timer_index,
-        bx_options.Ofloppy_command_delay->get (), 0 );
-      /* command head to track 0
-       * controller set to non-busy
-       * error condition noted in Status reg 0's equipment check bit
-       * seek end bit set to 1 in Status reg 0 regardless of outcome
-       * The last two are taken care of in timer().
-       */
-      BX_FD_THIS s.cylinder[drive] = 0;
-      BX_FD_THIS s.main_status_reg = (1 << drive);
-      return;
-      break;
-
-    case 0x08: /* sense interrupt status */
-      /* execution:
-       *   get status
-       * result:
-       *   no interupt
-       *   byte0 = status reg0
-       *   byte1 = current cylinder number (0 to 79)
-       */
-      drive = BX_FD_THIS s.DOR & 0x03;
-      if (!BX_FD_THIS s.pending_irq) {
-        BX_FD_THIS s.status_reg0 = 0x80;
-        }
-      else {
-        if (BX_FD_THIS s.reset_sensei > 0) {
-          drive = 4 - BX_FD_THIS s.reset_sensei;
-          BX_FD_THIS s.status_reg0 &= 0xf8;
-          BX_FD_THIS s.status_reg0 |= (BX_FD_THIS s.head[drive] << 2) | drive;
-          BX_FD_THIS s.reset_sensei--;
-          }
-        }
-
-      BX_DEBUG(("sense interrupt status"));
-      enter_result_phase();
-      return;
-      break;
-
-    case 0x0f: /* seek */
-      /* command:
-       *   byte0 = 0F
-       *   byte1 = drive & head select
-       *   byte2 = cylinder number
-       * execution:
-       *   postion head over specified cylinder
-       * result:
-       *   no result bytes, issues an interrupt
-       */
-      drive = BX_FD_THIS s.command[1] & 0x03;
-      BX_FD_THIS s.DOR &= 0xfc;
-      BX_FD_THIS s.DOR |= drive;
-
-      BX_FD_THIS s.head[drive] = (BX_FD_THIS s.command[1] >> 2) & 0x01;
-      BX_FD_THIS s.cylinder[drive] = BX_FD_THIS s.command[2];
-      /* ??? should also check cylinder validity */
-      bx_pc_system.activate_timer( BX_FD_THIS s.floppy_timer_index,
-        bx_options.Ofloppy_command_delay->get (), 0 );
-      /* data reg not ready, drive busy */
-      BX_FD_THIS s.main_status_reg = (1 << drive);
-      return;
-      break;
-
-    case 0x13: // Configure
-      BX_DEBUG(("configure (eis     = 0x%02x)", BX_FD_THIS s.command[2] & 0x40 ));
-      BX_DEBUG(("configure (efifo   = 0x%02x)", BX_FD_THIS s.command[2] & 0x20 ));
-      BX_DEBUG(("configure (no poll = 0x%02x)", BX_FD_THIS s.command[2] & 0x10 ));
-      BX_DEBUG(("configure (fifothr = 0x%02x)", BX_FD_THIS s.command[2] & 0x0f ));
-      BX_DEBUG(("configure (pretrk  = 0x%02x)", BX_FD_THIS s.command[3] ));
-      enter_idle_phase();
-      return;
-      break;
-
-    case 0x4a: // read ID
-      drive = BX_FD_THIS s.command[1] & 0x03;
-      BX_FD_THIS s.head[drive] = (BX_FD_THIS s.command[1] >> 2) & 0x01;
-      BX_FD_THIS s.DOR &= 0xfc;
-      BX_FD_THIS s.DOR |= drive;
-
-      motor_on = (BX_FD_THIS s.DOR>>(drive+4)) & 0x01;
-      if (motor_on == 0) {
-        BX_ERROR(("floppy_command(): 0x4a: motor not on"));
-        BX_FD_THIS s.main_status_reg = FD_MS_BUSY;
-        return;
-        }
-      if (BX_FD_THIS s.device_type[drive] == BX_FLOPPY_NONE)
-        BX_PANIC(("floppy_command(): read ID: bad drive #%d", drive));
-      BX_FD_THIS s.status_reg0 = (BX_FD_THIS s.head[drive]<<2) | drive;
-      bx_pc_system.activate_timer( BX_FD_THIS s.floppy_timer_index,
-        bx_options.Ofloppy_command_delay->get (), 0 );
-      /* data reg not ready, controller busy */
-      BX_FD_THIS s.main_status_reg = FD_MS_BUSY;
-      return;
-      break;
-
-    case 0x4d: // format track
-        drive = BX_FD_THIS s.command[1] & 0x03;
-        BX_FD_THIS s.DOR &= 0xfc;
-        BX_FD_THIS s.DOR |= drive;
-
-        motor_on = (BX_FD_THIS s.DOR>>(drive+4)) & 0x01;
-        if (motor_on == 0)
-          BX_PANIC(("floppy_command(): format track: motor not on"));
-        BX_FD_THIS s.head[drive] = (BX_FD_THIS s.command[1] >> 2) & 0x01;
-        sector_size = BX_FD_THIS s.command[2];
-        BX_FD_THIS s.format_count = BX_FD_THIS s.command[3];
-        BX_FD_THIS s.format_fillbyte = BX_FD_THIS s.command[5];
-        if (BX_FD_THIS s.device_type[drive] == BX_FLOPPY_NONE)
-          BX_PANIC(("floppy_command(): format track: bad drive #%d", drive));
-
-        if (sector_size != 0x02) { // 512 bytes
-          BX_PANIC(("format track: sector size %d not supported", 128<<sector_size));
-          }
-        if (BX_FD_THIS s.format_count != BX_FD_THIS s.media[drive].sectors_per_track) {
-          BX_PANIC(("format track: %d sectors/track requested (%d expected)",
-                    BX_FD_THIS s.format_count, BX_FD_THIS s.media[drive].sectors_per_track));
-          }
-        if ( BX_FD_THIS s.media_present[drive] == 0 ) {
-          // media not in drive, return error
-          BX_INFO(("attempt to format track with media not present"));
-          BX_FD_THIS s.status_reg0 = 0x40 | (BX_FD_THIS s.head[drive]<<2) | drive; // abnormal termination
-          BX_FD_THIS s.status_reg1 = 0x25; // 0010 0101
-          BX_FD_THIS s.status_reg2 = 0x31; // 0011 0001
-          enter_result_phase();
-          return;
-          }
-        if (BX_FD_THIS s.media[drive].write_protected) {
-          // media write-protected, return error
-          BX_INFO(("attempt to format track with media write-protected"));
-          BX_FD_THIS s.status_reg0 = 0x40 | (BX_FD_THIS s.head[drive]<<2) | drive; // abnormal termination
-          BX_FD_THIS s.status_reg1 = 0x27; // 0010 0111
-          BX_FD_THIS s.status_reg2 = 0x31; // 0011 0001
-          enter_result_phase();
-          return;
-          }
-
-      /* 4 header bytes per sector are required */
-      BX_FD_THIS s.format_count <<= 2;
-
-      DEV_dma_set_drq(FLOPPY_DMA_CHAN, 1);
-
-      /* data reg not ready, controller busy */
-      BX_FD_THIS s.main_status_reg = FD_MS_BUSY;
-      BX_DEBUG(("format track"));
-      return;
-      break;
-
-    case 0x46: // read normal data, MT=0, SK=0
-    case 0x66: // read normal data, MT=0, SK=1
-    case 0xc6: // read normal data, MT=1, SK=0
-    case 0xe6: // read normal data, MT=1, SK=1
-    case 0x45: // write normal data, MT=0
-    case 0xc5: // write normal data, MT=1
-      BX_FD_THIS s.multi_track = (BX_FD_THIS s.command[0] >> 7);
-      if ( (BX_FD_THIS s.DOR & 0x08) == 0 )
-        BX_PANIC(("read/write command with DMA and int disabled"));
-      drive = BX_FD_THIS s.command[1] & 0x03;
-      BX_FD_THIS s.DOR &= 0xfc;
-      BX_FD_THIS s.DOR |= drive;
-
-      motor_on = (BX_FD_THIS s.DOR>>(drive+4)) & 0x01;
-      if (motor_on == 0)
-        BX_PANIC(("floppy_command(): read/write: motor not on"));
-      head = BX_FD_THIS s.command[3] & 0x01;
-      cylinder = BX_FD_THIS s.command[2]; /* 0..79 depending */
-      sector = BX_FD_THIS s.command[4];   /* 1..36 depending */
-      eot = BX_FD_THIS s.command[6];      /* 1..36 depending */
-      sector_size = BX_FD_THIS s.command[5];
-      data_length = BX_FD_THIS s.command[8];
-      BX_DEBUG(("read/write normal data"));
-      BX_DEBUG(("BEFORE"));
-      BX_DEBUG(("  drive    = %u", (unsigned) drive));
-      BX_DEBUG(("  head     = %u", (unsigned) head));
-      BX_DEBUG(("  cylinder = %u", (unsigned) cylinder));
-      BX_DEBUG(("  sector   = %u", (unsigned) sector));
-      BX_DEBUG(("  eot      = %u", (unsigned) eot));
-      if (BX_FD_THIS s.device_type[drive] == BX_FLOPPY_NONE)
-        BX_PANIC(("floppy_command(): read/write: bad drive #%d", drive));
-
-      // check that head number in command[1] bit two matches the head
-      // reported in the head number field.  Real floppy drives are
-      // picky about this, as reported in SF bug #439945, (Floppy drive
-      // read input error checking).
-      if (head != ((BX_FD_THIS s.command[1]>>2)&1)) {
-        BX_ERROR(("head number in command[1] doesn't match head field"));
-        BX_FD_THIS s.status_reg0 = 0x40 | (BX_FD_THIS s.head[drive]<<2) | drive; // abnormal termination
-        BX_FD_THIS s.status_reg1 = 0x04; // 0000 0100
-        BX_FD_THIS s.status_reg2 = 0x00; // 0000 0000
-        enter_result_phase();
-        return;
-      }
-
-      if ( BX_FD_THIS s.media_present[drive] == 0 ) {
-        // media not in drive, return error
-
-        BX_INFO(("attempt to read/write sector %u,"
-                     " sectors/track=%u with media not present", 
-                     (unsigned) sector,
-                     (unsigned) BX_FD_THIS s.media[drive].sectors_per_track));
-        BX_FD_THIS s.status_reg0 = 0x40 | (BX_FD_THIS s.head[drive]<<2) | drive; // abnormal termination
-        BX_FD_THIS s.status_reg1 = 0x25; // 0010 0101
-        BX_FD_THIS s.status_reg2 = 0x31; // 0011 0001
-        enter_result_phase();
-        return;
-        }
-
-      if (sector_size != 0x02) { // 512 bytes
-        BX_PANIC(("read/write command: sector size %d not supported", 128<<sector_size));
-        }
-      if ( cylinder >= BX_FD_THIS s.media[drive].tracks ) {
-        BX_PANIC(("io: norm r/w parms out of range: sec#%02xh cyl#%02xh eot#%02xh head#%02xh",
-          (unsigned) sector, (unsigned) cylinder, (unsigned) eot,
-          (unsigned) head));
-        return;
-      }
-
-      if (sector > BX_FD_THIS s.media[drive].sectors_per_track) {
-        // requested sector > last sector on track
-        BX_INFO(("attempt to read/write sector %u,"
-                     " sectors/track=%u", (unsigned) sector,
-                     (unsigned) BX_FD_THIS s.media[drive].sectors_per_track));
-        // set controller to where drive would have left off
-        // after it discovered the sector was past EOT
-        BX_FD_THIS s.cylinder[drive] = cylinder;
-        BX_FD_THIS s.head[drive]     = head;
-        BX_FD_THIS s.sector[drive]   = BX_FD_THIS s.media[drive].sectors_per_track;
-
-        // 0100 0HDD abnormal termination
-        BX_FD_THIS s.status_reg0 = 0x40 | (BX_FD_THIS s.head[drive]<<2) | drive;
-        // 1000 0101 end of cyl/NDAT/NID
-        BX_FD_THIS s.status_reg1 = 0x85;
-        // 0000 0000
-        BX_FD_THIS s.status_reg2 = 0x00;
-        enter_result_phase();
-        return;
-        }
-
-      if (cylinder != BX_FD_THIS s.cylinder[drive])
-        BX_DEBUG(("io: cylinder request != current cylinder"));
-
-        // original assumed all floppies had two sides...now it does not  *delete this comment line*
-        logical_sector = (cylinder * BX_FD_THIS s.media[drive].heads * BX_FD_THIS s.media[drive].sectors_per_track) +
-                       (head * BX_FD_THIS s.media[drive].sectors_per_track) +
-                       (sector - 1);
-
-      if (logical_sector >= BX_FD_THIS s.media[drive].sectors) {
-        BX_PANIC(("io: logical sector out of bounds"));
-        }
-
-      BX_FD_THIS s.cylinder[drive] = cylinder;
-      BX_FD_THIS s.sector[drive]   = sector;
-      BX_FD_THIS s.head[drive]     = head;
-
-      if ((BX_FD_THIS s.command[0] & 0x4f) == 0x46) { // read
-        floppy_xfer(drive, logical_sector*512, BX_FD_THIS s.floppy_buffer,
-                    512, FROM_FLOPPY);
-
-        DEV_dma_set_drq(FLOPPY_DMA_CHAN, 1);
-
-        /* data reg not ready, controller busy */
-        BX_FD_THIS s.main_status_reg = FD_MS_BUSY;
-        return;
-        }
-      else if ((BX_FD_THIS s.command[0] & 0x7f) == 0x45) { // write
-
-        DEV_dma_set_drq(FLOPPY_DMA_CHAN, 1);
-
-        /* data reg not ready, controller busy */
-        BX_FD_THIS s.main_status_reg = FD_MS_BUSY;
-        return;
-        }
-      else
-        BX_PANIC(("floppy_command(): unknown read/write command"));
-
-      return;
-      break;
-
-    default: // invalid or unsupported command; these are captured in write() above
-      BX_PANIC(("You should never get here! cmd = 0x%02x", 
-                BX_FD_THIS s.command[0]));
-    }
-#endif
-}
-
-  void
-bx_floppy_ctrl_c::floppy_xfer(Bit8u drive, Bit32u offset, Bit8u *buffer,
-            Bit32u bytes, Bit8u direction)
-{
-  int ret;
-
-  if (BX_FD_THIS s.device_type[drive] == BX_FLOPPY_NONE)
-    BX_PANIC(("floppy_xfer: bad drive #%d", drive));
-
-  if (bx_dbg.floppy) {
-    BX_INFO(("drive=%u", (unsigned) drive));
-    BX_INFO(("offset=%u", (unsigned) offset));
-    BX_INFO(("bytes=%u", (unsigned) bytes));
-    BX_INFO(("direction=%s", (direction==FROM_FLOPPY)? "from" : "to"));
-    }
-
-#if BX_WITH_MACOS
-  if (strcmp(bx_options.floppya.Opath->getptr (), SuperDrive))
-#endif
-    {
-    ret = lseek(BX_FD_THIS s.media[drive].fd, offset, SEEK_SET);
-    if (ret < 0) {
-      BX_PANIC(("could not perform lseek() on floppy image file"));
-      }
-    }
-
-  if (direction == FROM_FLOPPY) {
-#if BX_WITH_MACOS
-    if (!strcmp(bx_options.floppya.Opath->getptr (), SuperDrive))
-      ret = fd_read((char *) buffer, offset, bytes);
-    else
-#endif
-      ret = ::read(BX_FD_THIS s.media[drive].fd, (bx_ptr_t) buffer, bytes);
-    if (ret < int(bytes)) {
-      /* ??? */
-      if (ret > 0) {
-        BX_INFO(("partial read() on floppy image returns %u/%u",
-          (unsigned) ret, (unsigned) bytes));
-        memset(buffer + ret, 0, bytes - ret);
-        }
-      else {
-        BX_INFO(("read() on floppy image returns 0"));
-        memset(buffer, 0, bytes);
-        }
-      }
-    }
-
-  else { // TO_FLOPPY
-    BX_ASSERT (!BX_FD_THIS s.media[drive].write_protected);
-#if BX_WITH_MACOS
-    if (!strcmp(bx_options.floppya.Opath->getptr (), SuperDrive))
-      ret = fd_write((char *) buffer, offset, bytes);
-    else
-#endif
-      ret = ::write(BX_FD_THIS s.media[drive].fd, (bx_ptr_t) buffer, bytes);
-    if (ret < int(bytes)) {
-      BX_PANIC(("could not perform write() on floppy image file"));
-    }
-  }
-}
-
-
-
-  void
-bx_floppy_ctrl_c::timer_handler(void *this_ptr)
-{
-
-  bx_floppy_ctrl_c *class_ptr = (bx_floppy_ctrl_c *) this_ptr;
-
-  class_ptr->timer();
-}
-
-  void
-bx_floppy_ctrl_c::timer()
-{
-  Bit8u drive;
-
-  drive = BX_FD_THIS s.DOR & 0x03;
-  switch ( BX_FD_THIS s.pending_command ) {
-    case 0x07: // recal
-    case 0x0f: // seek
-      BX_FD_THIS s.status_reg0 = 0x20 | (BX_FD_THIS s.head[drive]<<2) | drive;
-      if (BX_FD_THIS s.device_type[drive] == BX_FLOPPY_NONE) {
-        BX_FD_THIS s.status_reg0 |= 0x50;
-        }
-      else if (BX_FD_THIS s.media_present[drive] == 0) {
-        BX_FD_THIS s.status_reg0 |= 0x40;
-        BX_FD_THIS s.status_reg1 = 0x25;
-        BX_FD_THIS s.status_reg2 = 0x31;
-        }
-
-      /* reset changeline */
-      if (drive > 1) return;
-      if (BX_FD_THIS s.media_present[drive])
-        BX_FD_THIS s.DIR[drive] &= ~0x80; // clear disk change line
-
-      enter_idle_phase();
-      raise_interrupt();
-      break;
-
-    case 0x4a: /* read ID */
-      enter_result_phase();
-      break;
-
-    case 0xfe: // (contrived) RESET
-      theFloppyController->reset(BX_RESET_SOFTWARE);
-      BX_FD_THIS s.pending_command = 0;
-      BX_FD_THIS s.status_reg0 = 0xc0;
-      raise_interrupt();
-      BX_FD_THIS s.reset_sensei = 4;
-      break;
-    
-    case 0x00: // nothing pending?
-      break;
-
-    default:
-      BX_PANIC(("floppy:timer(): unknown case %02x",
-        (unsigned) BX_FD_THIS s.pending_command));
-    }
-  return;
-}
-
-  void
-bx_floppy_ctrl_c::dma_write(Bit8u *data_byte)
-{
-  // A DMA write is from I/O to Memory
-  // We need to return then next data byte from the floppy buffer
-  // to be transfered via the DMA to memory. (read block from floppy)
-
-
-  *data_byte = BX_FD_THIS s.floppy_buffer[BX_FD_THIS s.floppy_buffer_index++];
-
-  if (BX_FD_THIS s.floppy_buffer_index >= 512) {
-    Bit8u drive;
-
-    drive = BX_FD_THIS s.DOR & 0x03;
-    increment_sector(); // increment to next sector before retrieving next one
-    BX_FD_THIS s.floppy_buffer_index = 0;
-    if (DEV_dma_get_tc()) { // Terminal Count line, done
-      BX_FD_THIS s.status_reg0 = (BX_FD_THIS s.head[drive] << 2) | drive;
-      BX_FD_THIS s.status_reg1 = 0;
-      BX_FD_THIS s.status_reg2 = 0;
-
-      if (bx_dbg.floppy) {
-        BX_INFO(("<<READ DONE>>"));
-        BX_INFO(("AFTER"));
-        BX_INFO(("  drive    = %u", (unsigned) drive));
-        BX_INFO(("  head     = %u", (unsigned) BX_FD_THIS s.head[drive]));
-        BX_INFO(("  cylinder = %u", (unsigned) BX_FD_THIS s.cylinder[drive]));
-        BX_INFO(("  sector   = %u", (unsigned) BX_FD_THIS s.sector[drive]));
-        }
-
-      DEV_dma_set_drq(FLOPPY_DMA_CHAN, 0);
-      enter_result_phase();
-      }
-    else { // more data to transfer
-      Bit32u logical_sector;
-
-      // original assumed all floppies had two sides...now it does not  *delete this comment line*
-      logical_sector = (BX_FD_THIS s.cylinder[drive] * BX_FD_THIS s.media[drive].heads *
-                        BX_FD_THIS s.media[drive].sectors_per_track) +
-                       (BX_FD_THIS s.head[drive] *
-                        BX_FD_THIS s.media[drive].sectors_per_track) +
-                       (BX_FD_THIS s.sector[drive] - 1);
-
-      floppy_xfer(drive, logical_sector*512, BX_FD_THIS s.floppy_buffer,
-                  512, FROM_FLOPPY);
-      }
-    }
-}
-
-  void
-bx_floppy_ctrl_c::dma_read(Bit8u *data_byte)
-{
-  // A DMA read is from Memory to I/O
-  // We need to write the data_byte which was already transfered from memory
-  // via DMA to I/O (write block to floppy)
-
-  Bit8u drive;
-  Bit32u logical_sector;
-
-  drive = BX_FD_THIS s.DOR & 0x03;
-  if (BX_FD_THIS s.pending_command == 0x4d) { // format track in progress
-    --BX_FD_THIS s.format_count;
-    switch (3 - (BX_FD_THIS s.format_count & 0x03)) {
-      case 0:
-        BX_FD_THIS s.cylinder[drive] = *data_byte;
-        break;
-      case 1:
-        if (*data_byte != BX_FD_THIS s.head[drive])
-          BX_ERROR(("head number does not match head field"));
-        break;
-      case 2:
-        BX_FD_THIS s.sector[drive] = *data_byte;
-        break;
-      case 3:
-        if (*data_byte != 2) BX_ERROR(("dma_read: sector size %d not supported", 128<<(*data_byte)));
-        BX_DEBUG(("formatting cylinder %u head %u sector %u",
-                  BX_FD_THIS s.cylinder[drive], BX_FD_THIS s.head[drive],
-                  BX_FD_THIS s.sector[drive]));
-        for (unsigned i = 0; i < 512; i++) {
-          BX_FD_THIS s.floppy_buffer[i] = BX_FD_THIS s.format_fillbyte;
-          }
-        // original assumed all floppies had two sides...now it does not *delete this comment line*
-        logical_sector = (BX_FD_THIS s.cylinder[drive] * BX_FD_THIS s.media[drive].heads * BX_FD_THIS s.media[drive].sectors_per_track) +
-                         (BX_FD_THIS s.head[drive] * BX_FD_THIS s.media[drive].sectors_per_track) +
-                         (BX_FD_THIS s.sector[drive] - 1);
-        floppy_xfer(drive, logical_sector*512, BX_FD_THIS s.floppy_buffer,
-                    512, TO_FLOPPY);
-        break;
-      }
-    if ((BX_FD_THIS s.format_count == 0) || (DEV_dma_get_tc())) {
-      BX_FD_THIS s.format_count = 0;
-      BX_FD_THIS s.status_reg0 = (BX_FD_THIS s.head[drive] << 2) | drive;
-      DEV_dma_set_drq(FLOPPY_DMA_CHAN, 0);
-      enter_result_phase();
-      }
-    return;
-    }
-
-  BX_FD_THIS s.floppy_buffer[BX_FD_THIS s.floppy_buffer_index++] = *data_byte;
-
-  if (BX_FD_THIS s.floppy_buffer_index >= 512) {
-    // original assumed all floppies had two sides...now it does not *delete this comment line*
-    logical_sector = (BX_FD_THIS s.cylinder[drive] * BX_FD_THIS s.media[drive].heads * BX_FD_THIS s.media[drive].sectors_per_track) +
-                     (BX_FD_THIS s.head[drive] * BX_FD_THIS s.media[drive].sectors_per_track) +
-                     (BX_FD_THIS s.sector[drive] - 1);
-  if ( BX_FD_THIS s.media[drive].write_protected ) {
-    // write protected error
-    BX_INFO(("tried to write disk %u, which is write-protected", drive));
-    // ST0: IC1,0=01  (abnormal termination: started execution but failed)
-    BX_FD_THIS s.status_reg0 = 0x40 | (BX_FD_THIS s.head[drive]<<2) | drive;
-    // ST1: DataError=1, NDAT=1, NotWritable=1, NID=1
-    BX_FD_THIS s.status_reg1 = 0x27; // 0010 0111
-    // ST2: CRCE=1, SERR=1, BCYL=1, NDAM=1.
-    BX_FD_THIS s.status_reg2 = 0x31; // 0011 0001
-    enter_result_phase();
-    return;
-    }
-    floppy_xfer(drive, logical_sector*512, BX_FD_THIS s.floppy_buffer,
-                512, TO_FLOPPY);
-    increment_sector(); // increment to next sector after writing current one
-    BX_FD_THIS s.floppy_buffer_index = 0;
-    if (DEV_dma_get_tc()) { // Terminal Count line, done
-      BX_FD_THIS s.status_reg0 = (BX_FD_THIS s.head[drive] << 2) | drive;
-      BX_FD_THIS s.status_reg1 = 0;
-      BX_FD_THIS s.status_reg2 = 0;
-
-      if (bx_dbg.floppy) {
-        BX_INFO(("<<WRITE DONE>>"));
-        BX_INFO(("AFTER"));
-        BX_INFO(("  drive    = %u", (unsigned) drive));
-        BX_INFO(("  head     = %u", (unsigned) BX_FD_THIS s.head[drive]));
-        BX_INFO(("  cylinder = %u", (unsigned) BX_FD_THIS s.cylinder[drive]));
-        BX_INFO(("  sector   = %u", (unsigned) BX_FD_THIS s.sector[drive]));
-        }
-
-      DEV_dma_set_drq(FLOPPY_DMA_CHAN, 0);
-      enter_result_phase();
-      }
-    else { // more data to transfer
-      } // else
-    } // if BX_FD_THIS s.floppy_buffer_index >= 512
-}
-
-  void
-bx_floppy_ctrl_c::raise_interrupt(void)
-{
-  DEV_pic_raise_irq(6);
-  BX_FD_THIS s.pending_irq = 1;
-  BX_FD_THIS s.reset_sensei = 0;
-}
-
-
-  void
-bx_floppy_ctrl_c::increment_sector(void)
-{
-  Bit8u drive;
-
-  drive = BX_FD_THIS s.DOR & 0x03;
-
-  // values after completion of data xfer
-  // ??? calculation depends on base_count being multiple of 512
-  BX_FD_THIS s.sector[drive] ++;
-  if (BX_FD_THIS s.sector[drive] > BX_FD_THIS s.media[drive].sectors_per_track) {
-    BX_FD_THIS s.sector[drive] = 1;
-    if (BX_FD_THIS s.multi_track) {
-      BX_FD_THIS s.head[drive] ++;
-      if (BX_FD_THIS s.head[drive] > 1) {
-        BX_FD_THIS s.head[drive] = 0;
-        BX_FD_THIS s.cylinder[drive] ++;
-        }
-      }
-    else {
-      BX_FD_THIS s.cylinder[drive] ++;
-      }
-    if (BX_FD_THIS s.cylinder[drive] >= BX_FD_THIS s.media[drive].tracks) {
-      // Set to 1 past last possible cylinder value.
-      // I notice if I set it to tracks-1, prama linux won't boot.
-      BX_FD_THIS s.cylinder[drive] = BX_FD_THIS s.media[drive].tracks;
-      BX_INFO(("increment_sector: clamping cylinder to max"));
-      }
-    }
-}
-
-  unsigned
-bx_floppy_ctrl_c::set_media_status(unsigned drive, unsigned status)
-{
-  char *path;
-  unsigned type;
-
-  if (drive == 0)
-    type = bx_options.floppya.Otype->get ();
-  else
-    type = bx_options.floppyb.Otype->get ();
-
-  // if setting to the current value, nothing to do
-  if ((status == BX_FD_THIS s.media_present[drive]) &&
-      ((status == 0) || (type == BX_FD_THIS s.media[drive].type)))
-    return(status);
-
-  if (status == 0) {
-    // eject floppy
-    if (BX_FD_THIS s.media[drive].fd >= 0) {
-      close( BX_FD_THIS s.media[drive].fd );
-      BX_FD_THIS s.media[drive].fd = -1;
-      }
-    BX_FD_THIS s.media_present[drive] = 0;
-    if (drive == 0) {
-      bx_options.floppya.Ostatus->set(BX_EJECTED);
-    } else {
-      bx_options.floppyb.Ostatus->set(BX_EJECTED);
-    }
-    BX_FD_THIS s.DIR[drive] |= 0x80; // disk changed line
-    return(0);
-    }
-  else {
-    // insert floppy
-    if (drive == 0) {
-      path = bx_options.floppya.Opath->getptr ();
-      }
-    else {
-      path = bx_options.floppyb.Opath->getptr ();
-      }
-    if (!strcmp(path, "none"))
-      return(0);
-    if (evaluate_media(type, path, & BX_FD_THIS s.media[drive])) {
-      BX_FD_THIS s.media_present[drive] = 1;
-      if (drive == 0) {
-#define MED (BX_FD_THIS s.media[0])
-        BX_INFO(("fd0: '%s' ro=%d, h=%d,t=%d,spt=%d", bx_options.floppya.Opath->getptr(),
-        MED.write_protected, MED.heads, MED.tracks, MED.sectors_per_track));
-#undef MED
-        bx_options.floppya.Ostatus->set(BX_INSERTED);
-      } else {
-#define MED (BX_FD_THIS s.media[1])
-        BX_INFO(("fd1: '%s' ro=%d, h=%d,t=%d,spt=%d", bx_options.floppyb.Opath->getptr(),
-        MED.write_protected, MED.heads, MED.tracks, MED.sectors_per_track));
-#undef MED
-        bx_options.floppyb.Ostatus->set(BX_INSERTED);
-      }
-      BX_FD_THIS s.DIR[drive] |= 0x80; // disk changed line
-      return(1);
-      }
-    else {
-      BX_FD_THIS s.media_present[drive] = 0;
-      if (drive == 0) {
-        bx_options.floppya.Ostatus->set(BX_EJECTED);
-      } else {
-        bx_options.floppyb.Ostatus->set(BX_EJECTED);
-      }
-      return(0);
-      }
-    }
-}
-
-  unsigned
-bx_floppy_ctrl_c::get_media_status(unsigned drive)
-{
-  return( BX_FD_THIS s.media_present[drive] );
-}
-
-#ifdef O_BINARY
-#define BX_RDONLY O_RDONLY | O_BINARY
-#define BX_RDWR O_RDWR | O_BINARY
-#else
-#define BX_RDONLY O_RDONLY
-#define BX_RDWR O_RDWR
-#endif
-
-  bx_bool
-bx_floppy_ctrl_c::evaluate_media(unsigned type, char *path, floppy_t *media)
-{
-  struct stat stat_buf;
-  int i, ret;
-  int idx = -1;
-#ifdef __linux__
-  struct floppy_struct floppy_geom;
-#endif
-#ifdef WIN32
-  char sTemp[1024];
-  bx_bool raw_floppy = 0;
-  HANDLE hFile;
-  DWORD bytes;
-  DISK_GEOMETRY dg;
-  unsigned tracks, heads, spt;
-#endif
-
-  if (type == BX_FLOPPY_NONE)
-    return(0);
-
-  //If media file is already open, close it before reopening.
-  if(media->fd >=0) {
-    close(media->fd);
-    media->fd=-1;
-  }
-
-  // open media file (image file or device)
-  media->write_protected = 0;
-#ifdef macintosh
-  media->fd = 0;
-  if (strcmp(bx_options.floppya.Opath->getptr (), SuperDrive))
-#endif
-#ifdef WIN32
-    if ( (isalpha(path[0])) && (path[1] == ':') && (strlen(path) == 2) ) {
-      raw_floppy = 1;
-      wsprintf(sTemp, "\\\\.\\%s", path);
-      hFile = CreateFile(sTemp, GENERIC_READ, FILE_SHARE_WRITE, NULL,
-                         OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
-      if (hFile == INVALID_HANDLE_VALUE) {
-        BX_ERROR(("Cannot open floppy drive"));
-        return(0);
-      } else {
-        if (!DeviceIoControl(hFile, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &dg, sizeof(dg), &bytes, NULL)) {
-          BX_ERROR(("No media in floppy drive"));
-          CloseHandle(hFile);
-          return(0);
-        } else {
-          tracks = (unsigned)dg.Cylinders.QuadPart;
-          heads  = (unsigned)dg.TracksPerCylinder;
-          spt    = (unsigned)dg.SectorsPerTrack;
-        }
-        CloseHandle(hFile);
-      }
-      media->fd = open(sTemp, BX_RDWR);
-    } else {
-      media->fd = open(path, BX_RDWR);
-    } 
-#else
-    media->fd = open(path, BX_RDWR);
-#endif
-
-  if (media->fd < 0) {
-    BX_INFO(( "tried to open '%s' read/write: %s",path,strerror(errno) ));
-    // try opening the file read-only
-    media->write_protected = 1;
-#ifdef macintosh
-  media->fd = 0;
-  if (strcmp(bx_options.floppya.Opath->getptr (), SuperDrive))
-#endif
-#ifdef WIN32
-    if (raw_floppy == 1) {
-      media->fd = open(sTemp, BX_RDONLY);
-    } else {
-      media->fd = open(path, BX_RDONLY);
-    }
-#else
-    media->fd = open(path, BX_RDONLY);
-#endif
-    if (media->fd < 0) {
-      // failed to open read-only too
-      BX_INFO(( "tried to open '%s' read only: %s",path,strerror(errno) ));
-      media->type = type;
-      return(0);
-    }
-  }
-
-#if BX_WITH_MACOS
-  if (!strcmp(bx_options.floppya.Opath->getptr (), SuperDrive))
-    ret = fd_stat(&stat_buf);
-  else
-    ret = fstat(media->fd, &stat_buf);
-#elif defined(WIN32)
-  if (raw_floppy) {
-    memset (&stat_buf, 0, sizeof(stat_buf));
-    stat_buf.st_mode = S_IFCHR;
-    ret = 0;
-  } else {
-    ret = fstat(media->fd, &stat_buf);
-  }
-#else
-  // unix
-  ret = fstat(media->fd, &stat_buf);
-#endif
-  if (ret) {
-    BX_PANIC(("fstat floppy 0 drive image file returns error: %s", strerror(errno)));
-    return(0);
-    }
-
-  for (i = 0; i < 8; i++) {
-    if (type == floppy_type[i].id) idx = i;
-  }
-  if (idx == -1 ) {
-    BX_PANIC(("evaluate_media: unknown media type"));
-    return(0);
-  }
-  if ( S_ISREG(stat_buf.st_mode) ) {
-    // regular file
-    switch (type) {
-      // use CMOS reserved types
-      case BX_FLOPPY_160K: // 160K 5.25"
-      case BX_FLOPPY_180K: // 180K 5.25"
-      case BX_FLOPPY_320K: // 320K 5.25"
-      // standard floppy types
-      case BX_FLOPPY_360K: // 360K 5.25"
-      case BX_FLOPPY_720K: // 720K 3.5"
-      case BX_FLOPPY_1_2: // 1.2M 5.25"
-      case BX_FLOPPY_2_88: // 2.88M 3.5"
-        media->type              = type;
-        media->tracks            = floppy_type[idx].trk;
-        media->heads             = floppy_type[idx].hd;
-        media->sectors_per_track = floppy_type[idx].spt;
-        media->sectors           = floppy_type[idx].sectors;
-        if (stat_buf.st_size > (media->sectors * 512)) {
-          BX_INFO(("evaluate_media: size of file '%s' (%lu) too large for selected type",
-                   path, (unsigned long) stat_buf.st_size));
-          return(0);
-        }
-        break;
-      default: // 1.44M 3.5"
-        media->type              = type;
-        if (stat_buf.st_size <= 1474560) {
-          media->tracks            = floppy_type[idx].trk;
-          media->heads             = floppy_type[idx].hd;
-          media->sectors_per_track = floppy_type[idx].spt;
-          }
-        else if (stat_buf.st_size == 1720320) {
-          media->sectors_per_track = 21;
-          media->tracks            = 80;
-          media->heads             = 2;
-          }
-        else if (stat_buf.st_size == 1763328) {
-          media->sectors_per_track = 21;
-          media->tracks            = 82;
-          media->heads             = 2;
-          }
-        else {
-          BX_INFO(("evaluate_media: file '%s' of unknown size %lu",
-            path, (unsigned long) stat_buf.st_size));
-          return(0);
-          }
-        media->sectors = media->heads * media->tracks * media->sectors_per_track;
-      }
-    return(1); // success
-    }
-
-  else if ( S_ISCHR(stat_buf.st_mode)
-#if BX_WITH_MACOS == 0
-#ifdef S_ISBLK
-            || S_ISBLK(stat_buf.st_mode)
-#endif
-#endif
-           ) {
-    // character or block device
-    // assume media is formatted to typical geometry for drive
-    media->type              = type;
-#ifdef __linux__
-    if (ioctl(media->fd, FDGETPRM, &floppy_geom) < 0) {
-      BX_ERROR(("cannot determine media geometry"));
-      return(0);
-    }
-    media->tracks            = floppy_geom.track;
-    media->heads             = floppy_geom.head;
-    media->sectors_per_track = floppy_geom.sect;
-    media->sectors           = floppy_geom.size;
-#elif defined(WIN32)
-    media->tracks            = tracks;
-    media->heads             = heads;
-    media->sectors_per_track = spt;
-    media->sectors = media->heads * media->tracks * media->sectors_per_track;
-#else
-    media->tracks            = floppy_type[idx].trk;
-    media->heads             = floppy_type[idx].hd;
-    media->sectors_per_track = floppy_type[idx].spt;
-    media->sectors           = floppy_type[idx].sectors;
-#endif
-    return(1); // success
-    }
-  else {
-    // unknown file type
-    BX_INFO(("unknown mode type"));
-    return(0);
-    }
-}
-
-
-void
-bx_floppy_ctrl_c::enter_result_phase(void)
-{
-
-  Bit8u drive;
-
-  drive = BX_FD_THIS s.DOR & 0x03;
-
-  /* these are always the same */
-  BX_FD_THIS s.result_index = 0;
-  BX_FD_THIS s.main_status_reg = FD_MS_MRQ | FD_MS_DIO | FD_MS_BUSY;
-
-  /* invalid command */
-  if ((BX_FD_THIS s.status_reg0 & 0xc0) == 0x80) {
-    BX_FD_THIS s.result_size = 1;
-    BX_FD_THIS s.result[0] = BX_FD_THIS s.status_reg0;
-    return;
-  } 
-
-  switch (BX_FD_THIS s.pending_command) {
-  case 0x04: // get status
-    BX_FD_THIS s.result_size = 1;
-    BX_FD_THIS s.result[0] = BX_FD_THIS s.status_reg3;
-    break;
-  case 0x08: // sense interrupt
-    BX_FD_THIS s.result_size = 2;
-    BX_FD_THIS s.result[0] = BX_FD_THIS s.status_reg0;
-    BX_FD_THIS s.result[1] = BX_FD_THIS s.cylinder[drive];
-    break;
-  case 0x4a: // read ID
-  case 0x4d: // format track
-  case 0x46: // read normal data
-  case 0x66:
-  case 0xc6:
-  case 0xe6:
-  case 0x45: // write normal data
-  case 0xc5:
-    BX_FD_THIS s.result_size = 7;
-    BX_FD_THIS s.result[0] = BX_FD_THIS s.status_reg0;    
-    BX_FD_THIS s.result[1] = BX_FD_THIS s.status_reg1;
-    BX_FD_THIS s.result[2] = BX_FD_THIS s.status_reg2;
-    BX_FD_THIS s.result[3] = BX_FD_THIS s.cylinder[drive];
-    BX_FD_THIS s.result[4] = BX_FD_THIS s.head[drive];
-    BX_FD_THIS s.result[5] = BX_FD_THIS s.sector[drive];
-    BX_FD_THIS s.result[6] = 2; /* sector size code */
-    raise_interrupt();
-    break;
-  }
-}
-
-void
-bx_floppy_ctrl_c::enter_idle_phase(void)
-{
-  BX_FD_THIS s.main_status_reg &= 0x0f;      // leave drive status untouched
-  BX_FD_THIS s.main_status_reg |= FD_MS_MRQ; // data register ready
-
-  BX_FD_THIS s.command_complete = 1; /* waiting for new command */
-  BX_FD_THIS s.command_index = 0;
-  BX_FD_THIS s.command_size = 0;
-  BX_FD_THIS s.pending_command = 0;
-
-  BX_FD_THIS s.floppy_buffer_index = 0;
-}
-
diff --git a/tools/ioemu/iodev/floppy.h b/tools/ioemu/iodev/floppy.h
deleted file mode 100644 (file)
index d874539..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: floppy.h,v 1.16 2002/11/30 09:39:29 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-
-#define FROM_FLOPPY 10
-#define TO_FLOPPY   11
-
-#if BX_USE_FD_SMF
-#  define BX_FD_SMF  static
-#  define BX_FD_THIS theFloppyController->
-#else
-#  define BX_FD_SMF
-#  define BX_FD_THIS this->
-#endif
-
-typedef struct {
-  int      fd;         /* file descriptor of floppy image file */
-  unsigned sectors_per_track;    /* number of sectors/track */
-  unsigned sectors;    /* number of formatted sectors on diskette */
-  unsigned tracks;      /* number of tracks */
-  unsigned heads;      /* number of heads */
-  unsigned type;
-  unsigned write_protected;
-  } floppy_t;
-
-class bx_floppy_ctrl_c : public bx_floppy_stub_c {
-public:
-
-  bx_floppy_ctrl_c(void);
-  ~bx_floppy_ctrl_c(void);
-  virtual void   init(void);
-  virtual void   reset(unsigned type);
-  virtual unsigned set_media_status(unsigned drive, unsigned status);
-  virtual unsigned get_media_status(unsigned drive);
-
-private:
-
-  struct {
-    Bit8u   data_rate;
-
-    Bit8u   command[10]; /* largest command size ??? */
-    Bit8u   command_index;
-    Bit8u   command_size;
-    bx_bool command_complete;
-    Bit8u   pending_command;
-
-    bx_bool multi_track;
-    bx_bool pending_irq;
-    Bit8u   reset_sensei;
-    Bit8u   format_count;
-    Bit8u   format_fillbyte;
-
-    Bit8u   result[10];
-    Bit8u   result_index;
-    Bit8u   result_size;
-
-    Bit8u   DOR; // Digital Ouput Register
-    Bit8u   TDR; // Tape Drive Register
-    Bit8u   cylinder[4]; // really only using 2 drives
-    Bit8u   head[4];     // really only using 2 drives
-    Bit8u   sector[4];   // really only using 2 drives
-
-    /* MAIN STATUS REGISTER
-     * b7: MRQ: main request 1=data register ready     0=data register not ready
-     * b6: DIO: data input/output:
-     *     1=controller->CPU (ready for data read)
-     *     0=CPU->controller (ready for data write)
-     * b5: NDMA: non-DMA mode: 1=controller not in DMA modes
-     *                         0=controller in DMA mode
-     * b4: BUSY: instruction(device busy) 1=active 0=not active
-     * b3-0: ACTD, ACTC, ACTB, ACTA:
-     *       drive D,C,B,A in positioning mode 1=active 0=not active
-     */
-    Bit8u   main_status_reg;
-
-    Bit8u   status_reg0;
-    Bit8u   status_reg1;
-    Bit8u   status_reg2;
-    Bit8u   status_reg3;
-
-    // drive field allows up to 4 drives, even though probably only 2 will
-    // ever be used.
-    floppy_t media[4];
-    unsigned num_supported_floppies;
-    Bit8u    floppy_buffer[512+2]; // 2 extra for good measure
-    unsigned floppy_buffer_index;
-    int      floppy_timer_index;
-    bx_bool  media_present[2];
-    Bit8u    device_type[4];
-    Bit8u    DIR[4]; // Digital Input Register:
-                  // b7: 0=diskette is present and has not been changed
-                  //     1=diskette missing or changed
-    } s;  // state information
-
-  static Bit32u read_handler(void *this_ptr, Bit32u address, unsigned io_len);
-  static void   write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);
-#if !BX_USE_FD_SMF
-  Bit32u read(Bit32u address, unsigned io_len);
-  void   write(Bit32u address, Bit32u value, unsigned io_len);
-#endif
-  BX_FD_SMF void   dma_write(Bit8u *data_byte);
-  BX_FD_SMF void   dma_read(Bit8u *data_byte);
-  BX_FD_SMF void   floppy_command(void);
-  BX_FD_SMF void   floppy_xfer(Bit8u drive, Bit32u offset, Bit8u *buffer, Bit32u bytes, Bit8u direction);
-  BX_FD_SMF void   raise_interrupt(void);
-  BX_FD_SMF void   enter_idle_phase(void);
-  BX_FD_SMF void   enter_result_phase(void);
-  static void   timer_handler(void *);
-
-public:
-  BX_FD_SMF void   timer(void);
-  BX_FD_SMF void   increment_sector(void);
-  BX_FD_SMF bx_bool evaluate_media(unsigned type, char *path, floppy_t *floppy);
-  };
diff --git a/tools/ioemu/iodev/gameport.cc b/tools/ioemu/iodev/gameport.cc
deleted file mode 100644 (file)
index 9adefa6..0000000
+++ /dev/null
@@ -1,242 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: gameport.cc,v 1.5 2003/12/29 21:48:56 cbothamy Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2003  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-//
-// Standard PC gameport
-//
-
-// Define BX_PLUGGABLE in files that can be compiled into plugins.  For
-// platforms that require a special tag on exported symbols, BX_PLUGGABLE 
-// is used to know when we are exporting symbols and when we are importing.
-#define BX_PLUGGABLE
-
-#include "bochs.h"
-
-#ifdef __linux__
-
-#include <linux/joystick.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <stdio.h>
-
-#elif defined(WIN32)
-
-#ifndef JOY_BUTTON1
-#define JOY_BUTTON1 1
-#define JOY_BUTTON2 2
-UINT STDCALL joyGetPos(UINT, LPJOYINFO);
-#endif
-
-#define JOYSTICKID1 0
-
-#endif
-
-#define LOG_THIS theGameport->
-
-bx_gameport_c *theGameport = NULL;
-
-  int
-libgameport_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
-{
-  theGameport = new bx_gameport_c ();
-  bx_devices.pluginGameport = theGameport;
-  BX_REGISTER_DEVICE_DEVMODEL(plugin, type, theGameport, BX_PLUGIN_GAMEPORT);
-  return(0); // Success
-}
-
-  void
-libgameport_LTX_plugin_fini(void)
-{
-}
-
-bx_gameport_c::bx_gameport_c(void)
-{
-  put("GAME");
-  settype(EXTFPUIRQLOG);
-}
-
-bx_gameport_c::~bx_gameport_c(void)
-{
-  if (joyfd >= 0) close(joyfd);
-  BX_DEBUG(("Exit."));
-}
-
-
-  void
-bx_gameport_c::init(void)
-{
-  // Allocate the gameport IO address range 0x200..0x207
-  for (unsigned addr=0x200; addr<0x208; addr++) {
-    DEV_register_ioread_handler(this, read_handler, addr, "Gameport", 1);
-    DEV_register_iowrite_handler(this, write_handler, addr, "Gameport", 1);
-  }
-
-  BX_GAMEPORT_THIS port = 0xf0;
-  BX_GAMEPORT_THIS write_usec = 0;
-  BX_GAMEPORT_THIS timer_x = 0;
-  BX_GAMEPORT_THIS timer_y = 0;
-
-#ifdef __linux__
-  BX_GAMEPORT_THIS joyfd = open("/dev/input/js0", O_RDONLY);
-  if (BX_GAMEPORT_THIS joyfd >= 0) {
-    for (unsigned i=0; i<4; i++) poll_joydev();
-  }
-#elif defined(WIN32)
-  JOYINFO joypos;
-  if (joyGetPos(JOYSTICKID1, &joypos) == JOYERR_NOERROR) {
-    BX_GAMEPORT_THIS joyfd = 1;
-  } else {
-    BX_GAMEPORT_THIS joyfd = -1;
-  }
-#else
-  BX_GAMEPORT_THIS joyfd = -1;
-#endif
-}
-
-  void
-bx_gameport_c::reset(unsigned type)
-{
-  // nothing for now
-}
-
-  void
-bx_gameport_c::poll_joydev(void)
-{
-#ifdef __linux__
-  struct js_event e;
-  fd_set joyfds;
-  struct timeval tv;
-
-  memset(&tv, 0, sizeof(tv));
-  FD_ZERO(&joyfds);
-  FD_SET(BX_GAMEPORT_THIS joyfd, &joyfds);
-  e.type = 0;
-  if (select(BX_GAMEPORT_THIS joyfd+1, &joyfds, NULL, NULL, &tv)) {
-    read(BX_GAMEPORT_THIS joyfd, &e, sizeof(struct js_event));
-    if (e.type & JS_EVENT_BUTTON) {
-      if (e.value == 1) {
-        BX_GAMEPORT_THIS port &= ~(0x10 << e.number);
-      } else {
-        BX_GAMEPORT_THIS port |= (0x10 << e.number);
-      }
-    }
-    if (e.type & JS_EVENT_AXIS) {
-      if (e.number == 0) {
-        BX_GAMEPORT_THIS delay_x = 25 + ((e.value + 0x8000) / 60);
-      }
-      if (e.number == 1) {
-        BX_GAMEPORT_THIS delay_y = 25 + ((e.value + 0x8000) / 62);
-      }
-    }
-  }
-#elif defined(WIN32)
-  JOYINFO joypos;
-  if (joyGetPos(JOYSTICKID1, &joypos) == JOYERR_NOERROR) {
-    if (joypos.wButtons & JOY_BUTTON1) {
-      BX_GAMEPORT_THIS port &= ~0x10;
-    } else {
-      BX_GAMEPORT_THIS port |= 0x10;
-    }
-    if (joypos.wButtons & JOY_BUTTON2) {
-      BX_GAMEPORT_THIS port &= ~0x20;
-    } else {
-      BX_GAMEPORT_THIS port |= 0x20;
-    }
-    BX_GAMEPORT_THIS delay_x = 25 + (joypos.wXpos / 60);
-    BX_GAMEPORT_THIS delay_y = 25 + (joypos.wYpos / 60);
-  }
-#endif
-}
-
-
-  // static IO port read callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-  Bit32u
-bx_gameport_c::read_handler(void *this_ptr, Bit32u address, unsigned io_len)
-{
-#if !BX_USE_GAME_SMF
-  bx_gameport_c *class_ptr = (bx_gameport_c *) this_ptr;
-
-  return( class_ptr->read(address, io_len) );
-}
-
-
-  Bit32u
-bx_gameport_c::read(Bit32u address, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif // !BX_USE_GAME_SMF
-  Bit64u usec;
-
-  if (BX_GAMEPORT_THIS joyfd >= 0) {
-    poll_joydev();
-    usec = bx_pc_system.time_usec();
-    if (BX_GAMEPORT_THIS timer_x) {
-      if ((usec - BX_GAMEPORT_THIS write_usec) >= BX_GAMEPORT_THIS delay_x) {
-        BX_GAMEPORT_THIS port &= 0xfe;
-        BX_GAMEPORT_THIS timer_x = 0;
-      }
-    }
-    if (BX_GAMEPORT_THIS timer_y) {
-      if ((usec - BX_GAMEPORT_THIS write_usec) >= BX_GAMEPORT_THIS delay_y) {
-        BX_GAMEPORT_THIS port &= 0xfd;
-        BX_GAMEPORT_THIS timer_y = 0;
-      }
-    }
-  } else {
-    BX_DEBUG(("read: joystick not present"));
-  }
-  return BX_GAMEPORT_THIS port;
-}
-
-
-  // static IO port write callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-  void
-bx_gameport_c::write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len)
-{
-#if !BX_USE_GAME_SMF
-  bx_gameport_c *class_ptr = (bx_gameport_c *) this_ptr;
-
-  class_ptr->write(address, value, io_len);
-}
-
-  void
-bx_gameport_c::write(Bit32u address, Bit32u value, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif // !BX_USE_GAME_SMF
-
-  BX_GAMEPORT_THIS write_usec = bx_pc_system.time_usec();
-  BX_GAMEPORT_THIS timer_x = 1;
-  BX_GAMEPORT_THIS timer_y = 1;
-  BX_GAMEPORT_THIS port |= 0x0f;
-}
diff --git a/tools/ioemu/iodev/gameport.h b/tools/ioemu/iodev/gameport.h
deleted file mode 100644 (file)
index d4acddd..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: gameport.h,v 1.1 2003/06/21 12:55:19 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2003  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-#if BX_USE_GAME_SMF
-#  define BX_GAMEPORT_SMF  static
-#  define BX_GAMEPORT_THIS theGameport->
-#else
-#  define BX_GAMEPORT_SMF
-#  define BX_GAMEPORT_THIS this->
-#endif
-
-
-class bx_gameport_c : public bx_devmodel_c {
-
-public:
-  bx_gameport_c(void);
-  ~bx_gameport_c(void);
-  virtual void   init(void);
-  virtual void   reset(unsigned type);
-
-private:
-
-  int     joyfd;
-  Bit8u   port;
-  Bit16u  delay_x;
-  Bit16u  delay_y;
-  bx_bool timer_x;
-  bx_bool timer_y;
-  Bit64u  write_usec;
-
-  BX_GAMEPORT_SMF void poll_joydev(void);
-
-  static Bit32u read_handler(void *this_ptr, Bit32u address, unsigned io_len);
-  static void   write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);
-#if !BX_USE_GAME_SMF
-  Bit32u read(Bit32u address, unsigned io_len);
-  void   write(Bit32u address, Bit32u value, unsigned io_len);
-#endif
-  };
diff --git a/tools/ioemu/iodev/guest2host.h b/tools/ioemu/iodev/guest2host.h
deleted file mode 100644 (file)
index 0003662..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: guest2host.h,v 1.8 2002/12/06 18:48:08 bdenney Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2001  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-
-#define BX_MAX_G2H_CHANNELS 8
-#define BX_G2H_ERROR        ((unsigned) -1)
-  // IO port number for this interface.  Align on dword boundary.
-#define BX_G2H_PORT  0x2000
-  // Magic number which is first dword passed by guest
-#define BX_G2H_MAGIC 0xffeeddcc
-  // Number of dwords in packet from guest
-#define BX_G2H_PACKET_SIZE 5
-
-
-
-typedef Bit32u bx_guest_packet_t[BX_G2H_PACKET_SIZE];
-typedef void (*bx_g2h_callback_t)(bx_guest_packet_t *);
-
-
-
-class bx_g2h_c : public logfunctions {
-public:
-  bx_g2h_c(void);
-  ~bx_g2h_c(void);
-  static void   init(void);
-  void reset (unsigned type);
-  unsigned acquire_channel(bx_g2h_callback_t);
-  unsigned deacquire_channel(unsigned channel);
-
-private:
-
-  static Bit32u inp_handler(void *this_ptr, Bit32u addr, unsigned io_len);
-  static void   outp_handler(void *this_ptr, Bit32u addr,
-                              Bit32u value, unsigned io_len);
-  // state info
-  struct {
-    struct {
-      bx_g2h_callback_t f;
-      bx_bool used;
-      } callback[BX_MAX_G2H_CHANNELS];
-
-    // Define the data received from the guest OS.
-    //   dword0: magic number, should be BX_G2H_MAGIC
-    //   dword1: channel ID
-    //   dword2: address of data structure in guest physical memory
-    //   dword3: size of data structure in guest physical memory
-    //   dword4: address of return data structure in guest physical memory
-    unsigned packet_count;
-    bx_guest_packet_t guest_packet;
-    } s;
-  };
-
-extern bx_g2h_c bx_g2h;
diff --git a/tools/ioemu/iodev/harddrv.cc b/tools/ioemu/iodev/harddrv.cc
deleted file mode 100644 (file)
index cc44ce0..0000000
+++ /dev/null
@@ -1,4880 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: harddrv.cc,v 1.114.2.2 2004/02/06 22:14:35 danielg4 Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-// Useful docs:
-// AT Attachment with Packet Interface
-// working draft by T13 at www.t13.org
-
-
-
-// Define BX_PLUGGABLE in files that can be compiled into plugins.  For
-// platforms that require a special tag on exported symbols, BX_PLUGGABLE
-// is used to know when we are exporting symbols and when we are importing.
-#define BX_PLUGGABLE
-
-#include "bochs.h"
-
-#if BX_HAVE_SYS_MMAN_H
-#include <sys/mman.h>
-#endif
-
-#define LOG_THIS theHardDrive->
-
-// WARNING: dangerous options!
-// These options provoke certain kinds of errors for testing purposes when they
-// are set to a nonzero value.  DO NOT ENABLE THEM when using any disk image
-// you care about.
-#define TEST_READ_BEYOND_END 0
-#define TEST_WRITE_BEYOND_END 0
-#ifdef __GNUC__
-#  if TEST_READ_BEYOND_END || TEST_WRITE_BEYOND_END
-#    warning BEWARE: Dangerous options are enabled in harddrv.cc. If you are not trying to provoke hard drive errors you should disable them right now.
-#  endif
-#endif
-// end of dangerous options.
-
-
-#define INDEX_PULSE_CYCLE 10
-
-#define PACKET_SIZE 12
-
-static unsigned max_multiple_sectors  = 0; // was 0x3f
-static unsigned curr_multiple_sectors = 0; // was 0x3f
-
-// some packet handling macros
-#define EXTRACT_FIELD(arr,byte,start,num_bits) (((arr)[(byte)] >> (start)) & ((1 << (num_bits)) - 1))
-#define get_packet_field(c,b,s,n) (EXTRACT_FIELD((BX_SELECTED_CONTROLLER((c)).buffer),(b),(s),(n)))
-#define get_packet_byte(c,b) (BX_SELECTED_CONTROLLER((c)).buffer[(b)])
-#define get_packet_word(c,b) (((uint16)BX_SELECTED_CONTROLLER((c)).buffer[(b)] << 8) | BX_SELECTED_CONTROLLER((c)).buffer[(b)+1])
-
-
-#define BX_CONTROLLER(c,a) (BX_HD_THIS channels[(c)].drives[(a)]).controller
-#define BX_DRIVE(c,a) (BX_HD_THIS channels[(c)].drives[(a)])
-
-#define BX_DRIVE_IS_PRESENT(c,a) (BX_HD_THIS channels[(c)].drives[(a)].device_type != IDE_NONE)
-#define BX_DRIVE_IS_HD(c,a) (BX_HD_THIS channels[(c)].drives[(a)].device_type == IDE_DISK)
-#define BX_DRIVE_IS_CD(c,a) (BX_HD_THIS channels[(c)].drives[(a)].device_type == IDE_CDROM)
-
-#define BX_MASTER_IS_PRESENT(c) BX_DRIVE_IS_PRESENT((c),0)
-#define BX_SLAVE_IS_PRESENT(c) BX_DRIVE_IS_PRESENT((c),1)
-#define BX_ANY_IS_PRESENT(c) (BX_DRIVE_IS_PRESENT((c),0) || BX_DRIVE_IS_PRESENT((c),1))
-
-#define BX_SELECTED_CONTROLLER(c) (BX_CONTROLLER((c),BX_HD_THIS channels[(c)].drive_select))
-#define BX_SELECTED_DRIVE(c) (BX_DRIVE((c),BX_HD_THIS channels[(c)].drive_select))
-#define BX_MASTER_SELECTED(c) (!BX_HD_THIS channels[(c)].drive_select)
-#define BX_SLAVE_SELECTED(c)  (BX_HD_THIS channels[(c)].drive_select)
-
-#define BX_SELECTED_IS_PRESENT(c) (BX_DRIVE_IS_PRESENT((c),BX_SLAVE_SELECTED((c))))
-#define BX_SELECTED_IS_HD(c) (BX_DRIVE_IS_HD((c),BX_SLAVE_SELECTED((c))))
-#define BX_SELECTED_IS_CD(c) (BX_DRIVE_IS_CD((c),BX_SLAVE_SELECTED((c))))
-
-#define BX_SELECTED_MODEL(c) (BX_HD_THIS channels[(c)].drives[BX_HD_THIS channels[(c)].drive_select].model_no)
-#define BX_SELECTED_TYPE_STRING(channel) ((BX_SELECTED_IS_CD(channel)) ? "CD-ROM" : "DISK")
-
-#define WRITE_FEATURES(c,a) do { uint8 _a = a; BX_CONTROLLER((c),0).features = _a; BX_CONTROLLER((c),1).features = _a; } while(0)
-#define WRITE_SECTOR_COUNT(c,a) do { uint8 _a = a; BX_CONTROLLER((c),0).sector_count = _a; BX_CONTROLLER((c),1).sector_count = _a; } while(0)
-#define WRITE_SECTOR_NUMBER(c,a) do { uint8 _a = a; BX_CONTROLLER((c),0).sector_no = _a; BX_CONTROLLER((c),1).sector_no = _a; } while(0)
-#define WRITE_CYLINDER_LOW(c,a) do { uint8 _a = a; BX_CONTROLLER((c),0).cylinder_no = (BX_CONTROLLER((c),0).cylinder_no & 0xff00) | _a; BX_CONTROLLER((c),1).cylinder_no = (BX_CONTROLLER((c),1).cylinder_no & 0xff00) | _a; } while(0)
-#define WRITE_CYLINDER_HIGH(c,a) do { uint16 _a = a; BX_CONTROLLER((c),0).cylinder_no = (_a << 8) | (BX_CONTROLLER((c),0).cylinder_no & 0xff); BX_CONTROLLER((c),1).cylinder_no = (_a << 8) | (BX_CONTROLLER((c),1).cylinder_no & 0xff); } while(0)
-#define WRITE_HEAD_NO(c,a) do { uint8 _a = a; BX_CONTROLLER((c),0).head_no = _a; BX_CONTROLLER((c),1).head_no = _a; } while(0)
-#define WRITE_LBA_MODE(c,a) do { uint8 _a = a; BX_CONTROLLER((c),0).lba_mode = _a; BX_CONTROLLER((c),1).lba_mode = _a; } while(0)
-
-bx_hard_drive_c *theHardDrive = NULL;
-
-  int
-libharddrv_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
-{
-  theHardDrive = new bx_hard_drive_c ();
-  bx_devices.pluginHardDrive = theHardDrive;
-  BX_REGISTER_DEVICE_DEVMODEL(plugin, type, theHardDrive, BX_PLUGIN_HARDDRV);
-  return(0); // Success
-}
-
-  void
-libharddrv_LTX_plugin_fini(void)
-{
-}
-
-bx_hard_drive_c::bx_hard_drive_c(void)
-{
-#if DLL_HD_SUPPORT
-#   error code must be fixed to use DLL_HD_SUPPORT and 4 ata channels
-#endif
-
-    for (Bit8u channel=0; channel<BX_MAX_ATA_CHANNEL; channel++) {
-      channels[channel].drives[0].hard_drive =  NULL;
-      channels[channel].drives[1].hard_drive =  NULL;
-      put("HD");
-      settype(HDLOG);
-    }
-}
-
-
-bx_hard_drive_c::~bx_hard_drive_c(void)
-{
-       BX_DEBUG(("Exit."));
-  for (Bit8u channel=0; channel<BX_MAX_ATA_CHANNEL; channel++) {
-    if (channels[channel].drives[0].hard_drive != NULL )      /* DT 17.12.2001 21:55 */
-    {
-      delete channels[channel].drives[0].hard_drive;
-      channels[channel].drives[0].hard_drive =  NULL;
-    }
-    if ( channels[channel].drives[1].hard_drive != NULL )
-    {
-      delete channels[channel].drives[1].hard_drive;
-      channels[channel].drives[1].hard_drive =  NULL;        /* DT 17.12.2001 21:56 */
-    }
-  }
-}
-
-
-
-
-  void
-bx_hard_drive_c::init(void)
-{
-  Bit8u channel;
-  char  string[5];
-
-  BX_DEBUG(("Init $Id: harddrv.cc,v 1.114.2.2 2004/02/06 22:14:35 danielg4 Exp $"));
-
-  for (channel=0; channel<BX_MAX_ATA_CHANNEL; channel++) {
-    if (bx_options.ata[channel].Opresent->get() == 1) {
-      BX_HD_THIS channels[channel].ioaddr1 = bx_options.ata[channel].Oioaddr1->get();
-      BX_HD_THIS channels[channel].ioaddr2 = bx_options.ata[channel].Oioaddr2->get();
-      BX_HD_THIS channels[channel].irq = bx_options.ata[channel].Oirq->get();
-
-      // Coherency check
-      if ( (BX_HD_THIS channels[channel].ioaddr1 == 0) ||
-           (BX_HD_THIS channels[channel].ioaddr2 == 0) ||
-           (BX_HD_THIS channels[channel].irq == 0) ) {
-        BX_PANIC(("incoherency for ata channel %d: io1=0x%x, io2=%x, irq=%d",
-         channel,
-         BX_HD_THIS channels[channel].ioaddr1,
-         BX_HD_THIS channels[channel].ioaddr2,
-         BX_HD_THIS channels[channel].irq));
-        }
-      }
-    else {
-      BX_HD_THIS channels[channel].ioaddr1 = 0;
-      BX_HD_THIS channels[channel].ioaddr2 = 0;
-      BX_HD_THIS channels[channel].irq = 0;
-      }
-    }
-
-  for (channel=0; channel<BX_MAX_ATA_CHANNEL; channel++) {
-    sprintf(string ,"ATA%d", channel);
-
-    if (BX_HD_THIS channels[channel].irq != 0) 
-      DEV_register_irq(BX_HD_THIS channels[channel].irq, strdup(string));
-
-    if (BX_HD_THIS channels[channel].ioaddr1 != 0) {
-      DEV_register_ioread_handler(this, read_handler,
-                           BX_HD_THIS channels[channel].ioaddr1, strdup(string), 6);
-      DEV_register_iowrite_handler(this, write_handler,
-                           BX_HD_THIS channels[channel].ioaddr1, strdup(string), 6);
-      for (unsigned addr=0x1; addr<=0x7; addr++) {
-        DEV_register_ioread_handler(this, read_handler,
-                             BX_HD_THIS channels[channel].ioaddr1+addr, strdup(string), 1);
-        DEV_register_iowrite_handler(this, write_handler,
-                             BX_HD_THIS channels[channel].ioaddr1+addr, strdup(string), 1);
-        }
-      }
-
-    // We don't want to register addresses 0x3f6 and 0x3f7 as they are handled by the floppy controller
-    if ((BX_HD_THIS channels[channel].ioaddr2 != 0) && (BX_HD_THIS channels[channel].ioaddr2 != 0x3f0)) {
-      for (unsigned addr=0x6; addr<=0x7; addr++) {
-        DEV_register_ioread_handler(this, read_handler,
-                              BX_HD_THIS channels[channel].ioaddr2+addr, strdup(string), 1);
-        DEV_register_iowrite_handler(this, write_handler,
-                              BX_HD_THIS channels[channel].ioaddr2+addr, strdup(string), 1);
-        }
-      }
-     
-     BX_HD_THIS channels[channel].drive_select = 0;
-    }
-
-  channel = 0;
-  for (channel=0; channel<BX_MAX_ATA_CHANNEL; channel++) {
-    for (Bit8u device=0; device<2; device ++) {
-
-         // Initialize controller state, even if device is not present
-      BX_CONTROLLER(channel,device).status.busy           = 0;
-      BX_CONTROLLER(channel,device).status.drive_ready    = 1;
-      BX_CONTROLLER(channel,device).status.write_fault    = 0;
-      BX_CONTROLLER(channel,device).status.seek_complete  = 1;
-      BX_CONTROLLER(channel,device).status.drq            = 0;
-      BX_CONTROLLER(channel,device).status.corrected_data = 0;
-      BX_CONTROLLER(channel,device).status.index_pulse    = 0;
-      BX_CONTROLLER(channel,device).status.index_pulse_count = 0;
-      BX_CONTROLLER(channel,device).status.err            = 0;
-
-      BX_CONTROLLER(channel,device).error_register = 0x01; // diagnostic code: no error
-      BX_CONTROLLER(channel,device).head_no        = 0;
-      BX_CONTROLLER(channel,device).sector_count   = 1;
-      BX_CONTROLLER(channel,device).sector_no      = 1;
-      BX_CONTROLLER(channel,device).cylinder_no    = 0;
-      BX_CONTROLLER(channel,device).current_command = 0x00;
-      BX_CONTROLLER(channel,device).buffer_index = 0;
-
-      BX_CONTROLLER(channel,device).control.reset       = 0;
-      BX_CONTROLLER(channel,device).control.disable_irq = 0;
-      BX_CONTROLLER(channel,device).reset_in_progress   = 0;
-
-      BX_CONTROLLER(channel,device).sectors_per_block   = 0x80;
-      BX_CONTROLLER(channel,device).lba_mode            = 0;
-      
-         BX_CONTROLLER(channel,device).features            = 0;
-       
-         // If not present
-      BX_HD_THIS channels[channel].drives[device].device_type           = IDE_NONE;
-      if (!bx_options.atadevice[channel][device].Opresent->get()) {
-        continue;
-        }
-
-      // Make model string
-      strncpy((char*)BX_HD_THIS channels[channel].drives[device].model_no, 
-        bx_options.atadevice[channel][device].Omodel->getptr(), 40);
-      while (strlen((char *)BX_HD_THIS channels[channel].drives[device].model_no) < 40) {
-        strcat ((char*)BX_HD_THIS channels[channel].drives[device].model_no, " ");
-        }
-
-      if (bx_options.atadevice[channel][device].Otype->get() == BX_ATA_DEVICE_DISK) {
-        BX_DEBUG(( "Hard-Disk on target %d/%d",channel,device));
-        BX_HD_THIS channels[channel].drives[device].device_type           = IDE_DISK;
-
-        int cyl = bx_options.atadevice[channel][device].Ocylinders->get ();
-        int heads = bx_options.atadevice[channel][device].Oheads->get ();
-        int spt = bx_options.atadevice[channel][device].Ospt->get ();
-        Bit64u disk_size = (Bit64u)cyl * heads * spt * 512;
-
-        /* instantiate the right class */
-        switch (bx_options.atadevice[channel][device].Omode->get()) {
-
-          case BX_ATA_MODE_FLAT:
-            BX_INFO(("HD on ata%d-%d: '%s' 'flat' mode ", channel, device, 
-                                    bx_options.atadevice[channel][device].Opath->getptr ()));
-            channels[channel].drives[device].hard_drive = new default_image_t();
-            break;
-
-          case BX_ATA_MODE_CONCAT:
-            BX_INFO(("HD on ata%d-%d: '%s' 'concat' mode ", channel, device, 
-                                    bx_options.atadevice[channel][device].Opath->getptr ()));
-            channels[channel].drives[device].hard_drive = new concat_image_t();
-            break;
-
-#if EXTERNAL_DISK_SIMULATOR
-          case BX_ATA_MODE_EXTDISKSIM:
-            BX_INFO(("HD on ata%d-%d: '%s' 'External Simulator' mode ", channel, device, 
-                                    bx_options.atadevice[channel][device].Opath->getptr ()));
-            channels[channel].drives[device].hard_drive = new EXTERNAL_DISK_SIMULATOR_CLASS();
-            break;
-#endif //EXTERNAL_DISK_SIMULATOR
-
-#if DLL_HD_SUPPORT
-          case BX_ATA_MODE_DLL_HD:
-            BX_INFO(("HD on ata%d-%d: '%s' 'dll' mode ", channel, device, 
-                                    bx_options.atadevice[channel][device].Opath->getptr ()));
-            channels[channel].drives[device].hard_drive = new dll_image_t();
-            break;
-#endif //DLL_HD_SUPPORT
-
-          case BX_ATA_MODE_SPARSE:
-            BX_INFO(("HD on ata%d-%d: '%s' 'sparse' mode ", channel, device, 
-                                    bx_options.atadevice[channel][device].Opath->getptr ()));
-            channels[channel].drives[device].hard_drive = new sparse_image_t();
-            break;
-
-#if 0
-          case BX_ATA_MODE_VMWARE3:
-            BX_INFO(("HD on ata%d-%d: '%s' 'vmware3' mode ", channel, device, 
-                                    bx_options.atadevice[channel][device].Opath->getptr ()));
-            channels[channel].drives[device].hard_drive = new vmware3_image_t();
-            break;
-
-          case BX_ATA_MODE_SPLIT:
-            BX_INFO(("HD on ata%d-%d: '%s' 'split' mode ", channel, device, 
-                                    bx_options.atadevice[channel][device].Opath->getptr ()));
-            channels[channel].drives[device].hard_drive = new split_image_t();
-            break;
-#endif
-
-          case BX_ATA_MODE_UNDOABLE:
-            BX_INFO(("HD on ata%d-%d: '%s' 'undoable' mode ", channel, device, 
-                                    bx_options.atadevice[channel][device].Opath->getptr ()));
-            channels[channel].drives[device].hard_drive = new undoable_image_t(disk_size,
-                            bx_options.atadevice[channel][device].Ojournal->getptr());
-            break;
-
-          case BX_ATA_MODE_GROWING:
-            BX_INFO(("HD on ata%d-%d: '%s' 'growing' mode ", channel, device, 
-                                    bx_options.atadevice[channel][device].Opath->getptr ()));
-            channels[channel].drives[device].hard_drive = new growing_image_t(disk_size);
-            break;
-
-          case BX_ATA_MODE_VOLATILE:
-            BX_INFO(("HD on ata%d-%d: '%s' 'volatile' mode ", channel, device, 
-                                    bx_options.atadevice[channel][device].Opath->getptr ()));
-            channels[channel].drives[device].hard_drive = new volatile_image_t(disk_size,
-                            bx_options.atadevice[channel][device].Ojournal->getptr());
-            break;
-
-#if 0
-#if BX_COMPRESSED_HD_SUPPORT
-          case BX_ATA_MODE_Z_UNDOABLE:
-            BX_PANIC(("z-undoable disk support not implemented"));
-            BX_INFO(("HD on ata%d-%d: '%s' 'z-undoable' mode ", channel, device, 
-                                    bx_options.atadevice[channel][device].Opath->getptr ()));
-            channels[channel].drives[device].hard_drive = new z_undoable_image_t(disk_size,
-                            bx_options.atadevice[channel][device].Ojournal->getptr());
-            break;
-
-          case BX_ATA_MODE_Z_VOLATILE:
-            BX_PANIC(("z-volatile disk support not implemented"));
-            BX_INFO(("HD on ata%d-%d: '%s' 'z-volatile' mode ", channel, device, 
-                                    bx_options.atadevice[channel][device].Opath->getptr ()));
-            channels[channel].drives[device].hard_drive = new z_volatile_image_t(disk_size,
-                            bx_options.atadevice[channel][device].Ojournal->getptr());
-            break;
-#endif //BX_COMPRESSED_HD_SUPPORT
-#endif
-
-          default:
-            BX_PANIC(("HD on ata%d-%d: '%s' unsupported HD mode : %s", channel, device, 
-                      bx_options.atadevice[channel][device].Opath->getptr (),
-                      atadevice_mode_names[bx_options.atadevice[channel][device].Omode->get()]));
-            break;
-        }
-
-        BX_HD_THIS channels[channel].drives[device].hard_drive->cylinders = cyl;
-        BX_HD_THIS channels[channel].drives[device].hard_drive->heads = heads;
-        BX_HD_THIS channels[channel].drives[device].hard_drive->sectors = spt;
-
-        if (cyl == 0 || heads == 0 || spt == 0) {
-          BX_PANIC(("ata%d/%d cannot have zero cylinders, heads, or sectors/track", channel, device));
-          }
-
-        /* open hard drive image file */
-        if ((BX_HD_THIS channels[channel].drives[device].hard_drive->open(bx_options.atadevice[channel][device].Opath->getptr ())) < 0) {
-          BX_PANIC(("ata%d-%d: could not open hard drive image file '%s'", channel, device, bx_options.atadevice[channel][device].Opath->getptr ()));
-          }
-        }
-      else if (bx_options.atadevice[channel][device].Otype->get() == BX_ATA_DEVICE_CDROM) {
-        BX_DEBUG(( "CDROM on target %d/%d",channel,device));
-        BX_HD_THIS channels[channel].drives[device].device_type = IDE_CDROM;
-        BX_HD_THIS channels[channel].drives[device].cdrom.locked = 0;
-        BX_HD_THIS channels[channel].drives[device].sense.sense_key = SENSE_NONE;
-        BX_HD_THIS channels[channel].drives[device].sense.asc = 0;
-        BX_HD_THIS channels[channel].drives[device].sense.ascq = 0;
-       
-        // Check bit fields
-        BX_CONTROLLER(channel,device).sector_count = 0;
-        BX_CONTROLLER(channel,device).interrupt_reason.c_d = 1;
-        if (BX_CONTROLLER(channel,device).sector_count != 0x01)
-              BX_PANIC(("interrupt reason bit field error"));
-
-        BX_CONTROLLER(channel,device).sector_count = 0;
-        BX_CONTROLLER(channel,device).interrupt_reason.i_o = 1;
-        if (BX_CONTROLLER(channel,device).sector_count != 0x02)
-              BX_PANIC(("interrupt reason bit field error"));
-
-       BX_CONTROLLER(channel,device).sector_count = 0;
-       BX_CONTROLLER(channel,device).interrupt_reason.rel = 1;
-       if (BX_CONTROLLER(channel,device).sector_count != 0x04)
-             BX_PANIC(("interrupt reason bit field error"));
-
-       BX_CONTROLLER(channel,device).sector_count = 0;
-       BX_CONTROLLER(channel,device).interrupt_reason.tag = 3;
-       if (BX_CONTROLLER(channel,device).sector_count != 0x18)
-             BX_PANIC(("interrupt reason bit field error"));
-       BX_CONTROLLER(channel,device).sector_count = 0;
-
-       // allocate low level driver
-#ifdef LOWLEVEL_CDROM
-       BX_HD_THIS channels[channel].drives[device].cdrom.cd = new LOWLEVEL_CDROM(bx_options.atadevice[channel][device].Opath->getptr ());
-        BX_INFO(("CD on ata%d-%d: '%s'",channel, device, bx_options.atadevice[channel][device].Opath->getptr ()));
-
-       if (bx_options.atadevice[channel][device].Ostatus->get () == BX_INSERTED) {
-             if (BX_HD_THIS channels[channel].drives[device].cdrom.cd->insert_cdrom()) {
-                   BX_INFO(( "Media present in CD-ROM drive"));
-                   BX_HD_THIS channels[channel].drives[device].cdrom.ready = 1;
-                   BX_HD_THIS channels[channel].drives[device].cdrom.capacity = BX_HD_THIS channels[channel].drives[device].cdrom.cd->capacity();
-             } else {              
-                   BX_INFO(( "Could not locate CD-ROM, continuing with media not present"));
-                   BX_HD_THIS channels[channel].drives[device].cdrom.ready = 0;
-                   bx_options.atadevice[channel][device].Ostatus->set(BX_EJECTED);
-             }
-       } else {
-#endif
-             BX_INFO(( "Media not present in CD-ROM drive" ));
-             BX_HD_THIS channels[channel].drives[device].cdrom.ready = 0;
-#ifdef LOWLEVEL_CDROM
-       }
-#endif
-      }
-    }
-  }
-
-#if BX_PDC20230C_VLBIDE_SUPPORT
-      BX_HD_THIS pdc20230c.prog_mode = 0;
-      BX_HD_THIS pdc20230c.prog_count = 0;
-      BX_HD_THIS pdc20230c.p1f3_value = 0;
-      BX_HD_THIS pdc20230c.p1f4_value = 0;
-#endif
-
-
-  // generate CMOS values for hard drive if not using a CMOS image
-  if (!bx_options.cmos.OcmosImage->get ()) {
-    DEV_cmos_set_reg(0x12, 0x00); // start out with: no drive 0, no drive 1
-
-    if (BX_DRIVE_IS_HD(0,0)) {
-      // Flag drive type as Fh, use extended CMOS location as real type
-      DEV_cmos_set_reg(0x12, (DEV_cmos_get_reg(0x12) & 0x0f) | 0xf0);
-      DEV_cmos_set_reg(0x19, 47); // user definable type
-      // AMI BIOS: 1st hard disk #cyl low byte
-      DEV_cmos_set_reg(0x1b, (bx_options.atadevice[0][0].Ocylinders->get () & 0x00ff));
-      // AMI BIOS: 1st hard disk #cyl high byte
-      DEV_cmos_set_reg(0x1c, (bx_options.atadevice[0][0].Ocylinders->get () & 0xff00) >> 8);
-      // AMI BIOS: 1st hard disk #heads
-      DEV_cmos_set_reg(0x1d, (bx_options.atadevice[0][0].Oheads->get ()));
-      // AMI BIOS: 1st hard disk write precompensation cylinder, low byte
-      DEV_cmos_set_reg(0x1e, 0xff); // -1
-      // AMI BIOS: 1st hard disk write precompensation cylinder, high byte
-      DEV_cmos_set_reg(0x1f, 0xff); // -1
-      // AMI BIOS: 1st hard disk control byte
-      DEV_cmos_set_reg(0x20, (0xc0 | ((bx_options.atadevice[0][0].Oheads->get () > 8) << 3)));
-      // AMI BIOS: 1st hard disk landing zone, low byte
-      DEV_cmos_set_reg(0x21, DEV_cmos_get_reg(0x1b));
-      // AMI BIOS: 1st hard disk landing zone, high byte
-      DEV_cmos_set_reg(0x22, DEV_cmos_get_reg(0x1c));
-      // AMI BIOS: 1st hard disk sectors/track
-      DEV_cmos_set_reg(0x23, bx_options.atadevice[0][0].Ospt->get ());
-    }
-
-    //set up cmos for second hard drive
-    if (BX_DRIVE_IS_HD(0,1)) {
-      BX_DEBUG(("1: I will put 0xf into the second hard disk field"));
-      // fill in lower 4 bits of 0x12 for second HD
-      DEV_cmos_set_reg(0x12, (DEV_cmos_get_reg(0x12) & 0xf0) | 0x0f);
-      DEV_cmos_set_reg(0x1a, 47); // user definable type
-      // AMI BIOS: 2nd hard disk #cyl low byte
-      DEV_cmos_set_reg(0x24, (bx_options.atadevice[0][1].Ocylinders->get () & 0x00ff));
-      // AMI BIOS: 2nd hard disk #cyl high byte
-      DEV_cmos_set_reg(0x25, (bx_options.atadevice[0][1].Ocylinders->get () & 0xff00) >> 8);
-      // AMI BIOS: 2nd hard disk #heads
-      DEV_cmos_set_reg(0x26, (bx_options.atadevice[0][1].Oheads->get ()));
-      // AMI BIOS: 2nd hard disk write precompensation cylinder, low byte
-      DEV_cmos_set_reg(0x27, 0xff); // -1
-      // AMI BIOS: 2nd hard disk write precompensation cylinder, high byte
-      DEV_cmos_set_reg(0x28, 0xff); // -1
-      // AMI BIOS: 2nd hard disk, 0x80 if heads>8
-      DEV_cmos_set_reg(0x29, (bx_options.atadevice[0][1].Oheads->get () > 8) ? 0x80 : 0x00);
-      // AMI BIOS: 2nd hard disk landing zone, low byte
-      DEV_cmos_set_reg(0x2a, DEV_cmos_get_reg(0x24));
-      // AMI BIOS: 2nd hard disk landing zone, high byte
-      DEV_cmos_set_reg(0x2b, DEV_cmos_get_reg(0x25));
-      // AMI BIOS: 2nd hard disk sectors/track
-      DEV_cmos_set_reg(0x2c, bx_options.atadevice[0][1].Ospt->get ());
-    }
-
-    DEV_cmos_set_reg(0x39, 0);
-    DEV_cmos_set_reg(0x3a, 0);
-    for (channel=0; channel<BX_MAX_ATA_CHANNEL; channel++) {
-      for (Bit8u device=0; device<2; device ++) {
-        if (bx_options.atadevice[channel][device].Opresent->get()) {
-          if (BX_DRIVE_IS_HD(channel,device)) {
-            Bit16u cylinders = bx_options.atadevice[channel][device].Ocylinders->get();
-            Bit16u heads = bx_options.atadevice[channel][device].Oheads->get();
-            Bit16u spt = bx_options.atadevice[channel][device].Ospt->get();
-            Bit8u  translation = bx_options.atadevice[channel][device].Otranslation->get();
-
-            Bit8u reg = 0x39 + channel/2;
-            Bit8u bitshift = 2 * (device+(2 * (channel%2)));
-     
-            // Find the right translation if autodetect
-            if (translation == BX_ATA_TRANSLATION_AUTO) {
-              if((cylinders <= 1024) && (heads <= 16) && (spt <= 63)) {
-                translation = BX_ATA_TRANSLATION_NONE;
-                } 
-              else if (((Bit32u)cylinders * (Bit32u)heads) <= 131072) {
-                translation = BX_ATA_TRANSLATION_LARGE;
-                } 
-              else translation = BX_ATA_TRANSLATION_LBA;
-
-              BX_INFO(("translation on ata%d-%d set to '%s'",channel, device, 
-                        translation==BX_ATA_TRANSLATION_NONE?"none":
-                        translation==BX_ATA_TRANSLATION_LARGE?"large":
-                        "lba"));
-              }
-
-            // FIXME we should test and warn 
-            // - if LBA and spt != 63
-            // - if RECHS and heads != 16
-            // - if NONE and size > 1024*16*SPT blocks
-            // - if LARGE and size > 8192*16*SPT blocks
-            // - if RECHS and size > 1024*240*SPT blocks
-            // - if LBA and size > 1024*255*63, not that we can do much about it
-
-            switch(translation) {
-              case BX_ATA_TRANSLATION_NONE:
-                DEV_cmos_set_reg(reg, DEV_cmos_get_reg(reg) | (0 << bitshift));
-                break;
-              case BX_ATA_TRANSLATION_LBA:
-                DEV_cmos_set_reg(reg, DEV_cmos_get_reg(reg) | (1 << bitshift));
-                break;
-              case BX_ATA_TRANSLATION_LARGE:
-                DEV_cmos_set_reg(reg, DEV_cmos_get_reg(reg) | (2 << bitshift));
-                break;
-              case BX_ATA_TRANSLATION_RECHS:
-                DEV_cmos_set_reg(reg, DEV_cmos_get_reg(reg) | (3 << bitshift));
-                break;
-              }
-            }
-          }
-        }
-      }
-
-    // Set the "non-extended" boot device. This will default to DISKC if cdrom
-    if ( bx_options.Obootdrive->get () != BX_BOOT_FLOPPYA) {
-      // system boot sequence C:, A:
-      DEV_cmos_set_reg(0x2d, DEV_cmos_get_reg(0x2d) & 0xdf);
-      }
-    else { // 'a'
-      // system boot sequence A:, C:
-      DEV_cmos_set_reg(0x2d, DEV_cmos_get_reg(0x2d) | 0x20);
-      }
-
-    // Set the "extended" boot device, byte 0x3D (needed for cdrom booting)
-    if ( bx_options.Obootdrive->get () == BX_BOOT_FLOPPYA) {
-      // system boot sequence A:
-      DEV_cmos_set_reg(0x3d, 0x01);
-      BX_INFO(("Boot device will be 'a'"));
-      }
-    else if ( bx_options.Obootdrive->get () == BX_BOOT_DISKC) { 
-      // system boot sequence C:
-      DEV_cmos_set_reg(0x3d, 0x02);
-      BX_INFO(("Boot device will be 'c'"));
-      }
-    else if ( bx_options.Obootdrive->get () == BX_BOOT_CDROM) { 
-      // system boot sequence cdrom
-      DEV_cmos_set_reg(0x3d, 0x03);
-      BX_INFO(("Boot device will be 'cdrom'"));
-      }
-      
-    // Set the signature check flag in cmos, inverted for compatibility
-    DEV_cmos_set_reg(0x38, bx_options.OfloppySigCheck->get());
-    BX_INFO(("Floppy boot signature check is %sabled", bx_options.OfloppySigCheck->get() ? "dis" : "en"));
-    }
-
-}
-
-  void
-bx_hard_drive_c::reset(unsigned type)
-{
-  for (unsigned channel=0; channel<BX_MAX_ATA_CHANNEL; channel++) {
-    if (BX_HD_THIS channels[channel].irq)
-      DEV_pic_lower_irq(BX_HD_THIS channels[channel].irq);
-  }
-}
-
-
-#define GOTO_RETURN_VALUE  if(io_len==4){\
-                             goto return_value32;\
-                             }\
-                           else if(io_len==2){\
-                             value16=(Bit16u)value32;\
-                             goto return_value16;\
-                             }\
-                           else{\
-                             value8=(Bit8u)value32;\
-                             goto return_value8;\
-                             }
-                           
-
-  // static IO port read callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-  Bit32u
-bx_hard_drive_c::read_handler(void *this_ptr, Bit32u address, unsigned io_len)
-{
-#if !BX_USE_HD_SMF
-  bx_hard_drive_c *class_ptr = (bx_hard_drive_c *) this_ptr;
-
-  return( class_ptr->read(address, io_len) );
-}
-
-
-  Bit32u
-bx_hard_drive_c::read(Bit32u address, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif  // !BX_USE_HD_SMF
-  Bit8u value8;
-  Bit16u value16;
-  Bit32u value32;
-
-  Bit8u  channel = BX_MAX_ATA_CHANNEL;
-  Bit32u port = 0xff; // undefined
-
-  for (channel=0; channel<BX_MAX_ATA_CHANNEL; channel++) {
-    if ((address & 0xfff8) == BX_HD_THIS channels[channel].ioaddr1) {
-      port = address - BX_HD_THIS channels[channel].ioaddr1;
-      break;
-      }
-    else if ((address & 0xfff8) == BX_HD_THIS channels[channel].ioaddr2) {
-      port = address - BX_HD_THIS channels[channel].ioaddr2 + 0x10;
-      break;
-      }
-    }
-
-  if (channel == BX_MAX_ATA_CHANNEL) {
-    if ((address < 0x03f6) || (address > 0x03f7)) {
-      BX_PANIC(("read: unable to find ATA channel, ioport=0x%04x", address));
-    } else {
-      channel = 0;
-      port = address - 0x03e0;
-    }
-  }
-
-#if BX_PDC20230C_VLBIDE_SUPPORT
-// pdc20230c is only available for first ata channel
-if (channel == 0) {
-
-  // Detect the switch to programming mode
-  if (!BX_HD_THIS pdc20230c.prog_mode) {
-    switch (port) {
-      case 0x02:
-        if ((BX_HD_THIS pdc20230c.prog_count == 0) || (BX_HD_THIS pdc20230c.prog_count > 2)) {
-          BX_HD_THIS pdc20230c.prog_count++;
-        }
-       else {
-          BX_HD_THIS pdc20230c.prog_count=0;
-       }
-       break;
-      case 0x16:
-        if ((BX_HD_THIS pdc20230c.prog_count == 1) || (BX_HD_THIS pdc20230c.prog_count == 2)) {
-         BX_HD_THIS pdc20230c.prog_count++;
-       }
-       else {
-          BX_HD_THIS pdc20230c.prog_count=0;
-       }
-       break;
-      default:
-       BX_HD_THIS pdc20230c.prog_count=0;
-    }
-
-    if (BX_HD_THIS pdc20230c.prog_count == 5) {
-      BX_HD_THIS pdc20230c.prog_mode = 1;
-      BX_SELECTED_CONTROLLER(channel).sector_count &= 0x7f;
-      BX_INFO(("Promise VLB-IDE DC2300: Switching to Programming mode"));
-    }
-  }
-
-  // Returns value when in programming mode
-  if (BX_HD_THIS pdc20230c.prog_mode) {
-    switch (port) {
-      case 0x05:
-       // Leave programming mode
-        BX_HD_THIS pdc20230c.prog_mode = 0;
-        BX_INFO(("Promise VLB-IDE DC2300: Leaving Programming mode"));
-       // Value will be sent be normal code
-        break;
-      case 0x03:
-       // Special programming register
-        value32 = BX_HD_THIS pdc20230c.p1f3_value;
-        GOTO_RETURN_VALUE ;
-        break;
-      case 0x04:
-       // Special programming register
-        value32 = BX_HD_THIS pdc20230c.p1f4_value;
-        GOTO_RETURN_VALUE ;
-        break;
-    }
-  }
-}
-#endif
-
-  switch (port) {
-    case 0x00: // hard disk data (16bit) 0x1f0
-      if (BX_SELECTED_CONTROLLER(channel).status.drq == 0) {
-           BX_ERROR(("IO read(0x%04x) with drq == 0: last command was %02xh",
-                    address, (unsigned) BX_SELECTED_CONTROLLER(channel).current_command));
-            return(0);
-      }
-      BX_DEBUG(("IO read(0x%04x): current command is %02xh",
-            address, (unsigned) BX_SELECTED_CONTROLLER(channel).current_command));
-      switch (BX_SELECTED_CONTROLLER(channel).current_command) {
-        case 0x20: // READ SECTORS, with retries
-        case 0x21: // READ SECTORS, without retries
-          if (BX_SELECTED_CONTROLLER(channel).buffer_index >= 512)
-            BX_PANIC(("IO read(0x%04x): buffer_index >= 512", address));
-
-#if BX_SupportRepeatSpeedups
-          if (DEV_bulk_io_quantum_requested()) {
-            unsigned transferLen, quantumsMax;
-
-            quantumsMax =
-              (512 - BX_SELECTED_CONTROLLER(channel).buffer_index) / io_len;
-            if ( quantumsMax == 0)
-              BX_PANIC(("IO read(0x%04x): not enough space for read", address));
-            DEV_bulk_io_quantum_transferred() =
-                DEV_bulk_io_quantum_requested();
-            if (quantumsMax < DEV_bulk_io_quantum_transferred())
-              DEV_bulk_io_quantum_transferred() = quantumsMax;
-            transferLen = io_len * DEV_bulk_io_quantum_transferred();
-            memcpy((Bit8u*) DEV_bulk_io_host_addr(),
-              &BX_SELECTED_CONTROLLER(channel).buffer[BX_SELECTED_CONTROLLER(channel).buffer_index], 
-              transferLen);
-            DEV_bulk_io_host_addr() += transferLen;
-            BX_SELECTED_CONTROLLER(channel).buffer_index += transferLen;
-            value32 = 0; // Value returned not important;
-            }
-          else
-#endif
-            {
-            value32 = 0L;
-            switch(io_len){
-              case 4:
-                value32 |= (BX_SELECTED_CONTROLLER(channel).buffer[BX_SELECTED_CONTROLLER(channel).buffer_index+3] << 24);
-                value32 |= (BX_SELECTED_CONTROLLER(channel).buffer[BX_SELECTED_CONTROLLER(channel).buffer_index+2] << 16);
-              case 2:
-                value32 |= (BX_SELECTED_CONTROLLER(channel).buffer[BX_SELECTED_CONTROLLER(channel).buffer_index+1] << 8);
-                value32 |=  BX_SELECTED_CONTROLLER(channel).buffer[BX_SELECTED_CONTROLLER(channel).buffer_index];
-              }
-            BX_SELECTED_CONTROLLER(channel).buffer_index += io_len;
-            }
-
-          // if buffer completely read
-          if (BX_SELECTED_CONTROLLER(channel).buffer_index >= 512) {
-            // update sector count, sector number, cylinder,
-            // drive, head, status
-            // if there are more sectors, read next one in...
-            //
-            BX_SELECTED_CONTROLLER(channel).buffer_index = 0;
-
-           increment_address(channel);
-
-            BX_SELECTED_CONTROLLER(channel).status.busy = 0;
-            BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
-            BX_SELECTED_CONTROLLER(channel).status.write_fault = 0;
-            if (bx_options.OnewHardDriveSupport->get ())
-              BX_SELECTED_CONTROLLER(channel).status.seek_complete = 1;
-            else
-              BX_SELECTED_CONTROLLER(channel).status.seek_complete = 0;
-            BX_SELECTED_CONTROLLER(channel).status.corrected_data = 0;
-            BX_SELECTED_CONTROLLER(channel).status.err = 0;
-
-            if (BX_SELECTED_CONTROLLER(channel).sector_count==0) {
-              BX_SELECTED_CONTROLLER(channel).status.drq = 0;
-              }
-            else { /* read next one into controller buffer */
-              off_t logical_sector;
-              off_t ret;
-
-              BX_SELECTED_CONTROLLER(channel).status.drq = 1;
-              BX_SELECTED_CONTROLLER(channel).status.seek_complete = 1;
-
-#if TEST_READ_BEYOND_END==1
-             BX_SELECTED_CONTROLLER(channel).cylinder_no += 100000;
-#endif
-             if (!calculate_logical_address(channel, &logical_sector)) {
-               BX_ERROR(("multi-sector read reached invalid sector %lu, aborting", (unsigned long)logical_sector));
-               command_aborted (channel, BX_SELECTED_CONTROLLER(channel).current_command);
-               GOTO_RETURN_VALUE ;
-             }
-             ret = BX_SELECTED_DRIVE(channel).hard_drive->lseek(logical_sector * 512, SEEK_SET);
-              if (ret < 0) {
-                BX_ERROR(("could not lseek() hard drive image file"));
-               command_aborted (channel, BX_SELECTED_CONTROLLER(channel).current_command);
-               GOTO_RETURN_VALUE ;
-             }
-             ret = BX_SELECTED_DRIVE(channel).hard_drive->read((bx_ptr_t) BX_SELECTED_CONTROLLER(channel).buffer, 512);
-              if (ret < 512) {
-                BX_ERROR(("logical sector was %lu", (unsigned long)logical_sector));
-                BX_ERROR(("could not read() hard drive image file at byte %lu", (unsigned long)logical_sector*512));
-               command_aborted (channel, BX_SELECTED_CONTROLLER(channel).current_command);
-               GOTO_RETURN_VALUE ;
-             }
-
-              BX_SELECTED_CONTROLLER(channel).buffer_index = 0;
-             raise_interrupt(channel);
-           }
-         }
-         GOTO_RETURN_VALUE ;
-          break;
-
-        case 0xec:    // IDENTIFY DEVICE
-       case 0xa1:
-          if (bx_options.OnewHardDriveSupport->get ()) {
-            unsigned index;
-
-            BX_SELECTED_CONTROLLER(channel).status.busy = 0;
-            BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
-            BX_SELECTED_CONTROLLER(channel).status.write_fault = 0;
-            BX_SELECTED_CONTROLLER(channel).status.seek_complete = 1;
-            BX_SELECTED_CONTROLLER(channel).status.corrected_data = 0;
-            BX_SELECTED_CONTROLLER(channel).status.err = 0;
-
-            index = BX_SELECTED_CONTROLLER(channel).buffer_index;
-            value32 = BX_SELECTED_CONTROLLER(channel).buffer[index];
-            index++;
-            if (io_len >= 2) {
-              value32 |= (BX_SELECTED_CONTROLLER(channel).buffer[index] << 8);
-              index++;
-              }
-            if (io_len == 4) {
-              value32 |= (BX_SELECTED_CONTROLLER(channel).buffer[index] << 16);
-              value32 |= (BX_SELECTED_CONTROLLER(channel).buffer[index+1] << 24);
-              index += 2;
-              }
-            BX_SELECTED_CONTROLLER(channel).buffer_index = index;
-
-            if (BX_SELECTED_CONTROLLER(channel).buffer_index >= 512) {
-              BX_SELECTED_CONTROLLER(channel).status.drq = 0;
-             if (bx_dbg.disk || (BX_SELECTED_IS_CD(channel) && bx_dbg.cdrom))
-                   BX_INFO(("Read all drive ID Bytes ..."));
-              }
-            GOTO_RETURN_VALUE;
-         }
-          else
-            BX_PANIC(("IO read(0x%04x): current command is %02xh", address,
-              (unsigned) BX_SELECTED_CONTROLLER(channel).current_command));
-
-           case 0xa0: {
-                 unsigned index = BX_SELECTED_CONTROLLER(channel).buffer_index;
-                 unsigned increment = 0;
-
-                 // Load block if necessary
-                 if (index >= 2048) {
-                       if (index > 2048)
-                             BX_PANIC(("index > 2048 : 0x%x",index));
-                       switch (BX_SELECTED_DRIVE(channel).atapi.command) {
-                             case 0x28: // read (10)
-                             case 0xa8: // read (12)
-#ifdef LOWLEVEL_CDROM
-                                   if (!BX_SELECTED_DRIVE(channel).cdrom.ready) {
-                                     BX_PANIC(("Read with CDROM not ready"));
-                                   } 
-                                   BX_SELECTED_DRIVE(channel).cdrom.cd->read_block(BX_SELECTED_CONTROLLER(channel).buffer,
-                                                                       BX_SELECTED_DRIVE(channel).cdrom.next_lba);
-                                   BX_SELECTED_DRIVE(channel).cdrom.next_lba++;
-                                   BX_SELECTED_DRIVE(channel).cdrom.remaining_blocks--;
-
-                                   if (bx_dbg.disk || (BX_SELECTED_IS_CD(channel) && bx_dbg.cdrom))
-                                         if (!BX_SELECTED_DRIVE(channel).cdrom.remaining_blocks)
-                                               BX_INFO(("Last READ block loaded {CDROM}"));
-                                         else
-                                               BX_INFO(("READ block loaded (%d remaining) {CDROM}",
-                                                         BX_SELECTED_DRIVE(channel).cdrom.remaining_blocks));
-
-                                   // one block transfered, start at beginning
-                                   index = 0;
-#else
-                                   BX_PANIC(("Read with no LOWLEVEL_CDROM"));
-#endif
-                                   break;
-
-                             default: // no need to load a new block
-                                   break;
-                       }
-                 }
-
-                 value32 = BX_SELECTED_CONTROLLER(channel).buffer[index+increment];
-                 increment++;
-                 if (io_len >= 2) {
-                       value32 |= (BX_SELECTED_CONTROLLER(channel).buffer[index+increment] << 8);
-                       increment++;
-                 }
-                 if (io_len == 4) {
-                       value32 |= (BX_SELECTED_CONTROLLER(channel).buffer[index+increment] << 16);
-                       value32 |= (BX_SELECTED_CONTROLLER(channel).buffer[index+increment+1] << 24);
-                       increment += 2;
-                 }
-                 BX_SELECTED_CONTROLLER(channel).buffer_index = index + increment;
-                 BX_SELECTED_CONTROLLER(channel).drq_index += increment;
-
-                 if (BX_SELECTED_CONTROLLER(channel).drq_index >= (unsigned)BX_SELECTED_DRIVE(channel).atapi.drq_bytes) {
-                       BX_SELECTED_CONTROLLER(channel).status.drq = 0;
-                       BX_SELECTED_CONTROLLER(channel).drq_index = 0;
-
-                       BX_SELECTED_DRIVE(channel).atapi.total_bytes_remaining -= BX_SELECTED_DRIVE(channel).atapi.drq_bytes;
-
-                       if (BX_SELECTED_DRIVE(channel).atapi.total_bytes_remaining > 0) {
-                             // one or more blocks remaining (works only for single block commands)
-                             if (bx_dbg.disk || (BX_SELECTED_IS_CD(channel) && bx_dbg.cdrom))
-                                   BX_INFO(("PACKET drq bytes read"));
-                             BX_SELECTED_CONTROLLER(channel).interrupt_reason.i_o = 1;
-                             BX_SELECTED_CONTROLLER(channel).status.busy = 0;
-                             BX_SELECTED_CONTROLLER(channel).status.drq = 1;
-                             BX_SELECTED_CONTROLLER(channel).interrupt_reason.c_d = 0;
-
-                             // set new byte count if last block
-                             if (BX_SELECTED_DRIVE(channel).atapi.total_bytes_remaining < BX_SELECTED_CONTROLLER(channel).byte_count) {
-                                   BX_SELECTED_CONTROLLER(channel).byte_count = BX_SELECTED_DRIVE(channel).atapi.total_bytes_remaining;
-                             }
-                             BX_SELECTED_DRIVE(channel).atapi.drq_bytes = BX_SELECTED_CONTROLLER(channel).byte_count;
-
-                             raise_interrupt(channel);
-                       } else {
-                             // all bytes read
-                             if (bx_dbg.disk || (BX_SELECTED_IS_CD(channel) && bx_dbg.cdrom))
-                                   BX_INFO(("PACKET all bytes read"));
-                             BX_SELECTED_CONTROLLER(channel).interrupt_reason.i_o = 1;
-                             BX_SELECTED_CONTROLLER(channel).interrupt_reason.c_d = 1;
-                             BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
-                             BX_SELECTED_CONTROLLER(channel).interrupt_reason.rel = 0;
-                             BX_SELECTED_CONTROLLER(channel).status.busy = 0;
-                             BX_SELECTED_CONTROLLER(channel).status.drq = 0;
-                             BX_SELECTED_CONTROLLER(channel).status.err = 0;
-                             
-                             raise_interrupt(channel);
-                       }
-                 }
-                  GOTO_RETURN_VALUE;
-                 break;
-           }
-
-       // List all the read operations that are defined in the ATA/ATAPI spec
-       // that we don't support.  Commands that are listed here will cause a
-       // BX_ERROR, which is non-fatal, and the command will be aborted.
-       case 0x08: BX_ERROR(("read cmd 0x08 (DEVICE RESET) not supported")); command_aborted(channel, 0x08); break;
-       case 0x10: BX_ERROR(("read cmd 0x10 (RECALIBRATE) not supported")); command_aborted(channel, 0x10); break;
-       case 0x22: BX_ERROR(("read cmd 0x22 (READ LONG) not supported")); command_aborted(channel, 0x22); break;
-       case 0x23: BX_ERROR(("read cmd 0x23 (READ LONG NO RETRY) not supported")); command_aborted(channel, 0x23); break;
-       case 0x24: BX_ERROR(("read cmd 0x24 (READ SECTORS EXT) not supported")); command_aborted(channel, 0x24); break;
-       case 0x25: BX_ERROR(("read cmd 0x25 (READ DMA EXT) not supported")); command_aborted(channel, 0x25); break;
-       case 0x26: BX_ERROR(("read cmd 0x26 (READ DMA QUEUED EXT) not supported")); command_aborted(channel, 0x26); break;
-       case 0x27: BX_ERROR(("read cmd 0x27 (READ NATIVE MAX ADDRESS EXT) not supported")); command_aborted(channel, 0x27); break;
-       case 0x29: BX_ERROR(("read cmd 0x29 (READ MULTIPLE EXT) not supported")); command_aborted(channel, 0x29); break;
-       case 0x2A: BX_ERROR(("read cmd 0x2A (READ STREAM DMA) not supported")); command_aborted(channel, 0x2A); break;
-       case 0x2B: BX_ERROR(("read cmd 0x2B (READ STREAM PIO) not supported")); command_aborted(channel, 0x2B); break;
-       case 0x2F: BX_ERROR(("read cmd 0x2F (READ LOG EXT) not supported")); command_aborted(channel, 0x2F); break;
-       case 0x30: BX_ERROR(("read cmd 0x30 (WRITE SECTORS) not supported")); command_aborted(channel, 0x30); break;
-       case 0x31: BX_ERROR(("read cmd 0x31 (WRITE SECTORS NO RETRY) not supported")); command_aborted(channel, 0x31); break;
-       case 0x32: BX_ERROR(("read cmd 0x32 (WRITE LONG) not supported")); command_aborted(channel, 0x32); break;
-       case 0x33: BX_ERROR(("read cmd 0x33 (WRITE LONG NO RETRY) not supported")); command_aborted(channel, 0x33); break;
-       case 0x34: BX_ERROR(("read cmd 0x34 (WRITE SECTORS EXT) not supported")); command_aborted(channel, 0x34); break;
-       case 0x35: BX_ERROR(("read cmd 0x35 (WRITE DMA EXT) not supported")); command_aborted(channel, 0x35); break;
-       case 0x36: BX_ERROR(("read cmd 0x36 (WRITE DMA QUEUED EXT) not supported")); command_aborted(channel, 0x36); break;
-       case 0x37: BX_ERROR(("read cmd 0x37 (SET MAX ADDRESS EXT) not supported")); command_aborted(channel, 0x37); break;
-       case 0x38: BX_ERROR(("read cmd 0x38 (CFA WRITE SECTORS W/OUT ERASE) not supported")); command_aborted(channel, 0x38); break;
-       case 0x39: BX_ERROR(("read cmd 0x39 (WRITE MULTIPLE EXT) not supported")); command_aborted(channel, 0x39); break;
-       case 0x3A: BX_ERROR(("read cmd 0x3A (WRITE STREAM DMA) not supported")); command_aborted(channel, 0x3A); break;
-       case 0x3B: BX_ERROR(("read cmd 0x3B (WRITE STREAM PIO) not supported")); command_aborted(channel, 0x3B); break;
-       case 0x3F: BX_ERROR(("read cmd 0x3F (WRITE LOG EXT) not supported")); command_aborted(channel, 0x3F); break;
-       case 0x40: BX_ERROR(("read cmd 0x40 (READ VERIFY SECTORS) not supported")); command_aborted(channel, 0x40); break;
-       case 0x41: BX_ERROR(("read cmd 0x41 (READ VERIFY SECTORS NO RETRY) not supported")); command_aborted(channel, 0x41); break;
-       case 0x42: BX_ERROR(("read cmd 0x42 (READ VERIFY SECTORS EXT) not supported")); command_aborted(channel, 0x42); break;
-       case 0x50: BX_ERROR(("read cmd 0x50 (FORMAT TRACK) not supported")); command_aborted(channel, 0x50); break;
-       case 0x51: BX_ERROR(("read cmd 0x51 (CONFIGURE STREAM) not supported")); command_aborted(channel, 0x51); break;
-       case 0x70: BX_ERROR(("read cmd 0x70 (SEEK) not supported")); command_aborted(channel, 0x70); break;
-       case 0x87: BX_ERROR(("read cmd 0x87 (CFA TRANSLATE SECTOR) not supported")); command_aborted(channel, 0x87); break;
-       case 0x90: BX_ERROR(("read cmd 0x90 (EXECUTE DEVICE DIAGNOSTIC) not supported")); command_aborted(channel, 0x90); break;
-       case 0x91: BX_ERROR(("read cmd 0x91 (INITIALIZE DEVICE PARAMETERS) not supported")); command_aborted(channel, 0x91); break;
-       case 0x92: BX_ERROR(("read cmd 0x92 (DOWNLOAD MICROCODE) not supported")); command_aborted(channel, 0x92); break;
-       case 0x94: BX_ERROR(("read cmd 0x94 (STANDBY IMMEDIATE) not supported")); command_aborted(channel, 0x94); break;
-       case 0x95: BX_ERROR(("read cmd 0x95 (IDLE IMMEDIATE) not supported")); command_aborted(channel, 0x95); break;
-       case 0x96: BX_ERROR(("read cmd 0x96 (STANDBY) not supported")); command_aborted(channel, 0x96); break;
-       case 0x97: BX_ERROR(("read cmd 0x97 (IDLE) not supported")); command_aborted(channel, 0x97); break;
-       case 0x98: BX_ERROR(("read cmd 0x98 (CHECK POWER MODE) not supported")); command_aborted(channel, 0x98); break;
-       case 0x99: BX_ERROR(("read cmd 0x99 (SLEEP) not supported")); command_aborted(channel, 0x99); break;
-       case 0xA2: BX_ERROR(("read cmd 0xA2 (SERVICE) not supported")); command_aborted(channel, 0xA2); break;
-       case 0xB0: BX_ERROR(("read cmd 0xB0 (SMART DISABLE OPERATIONS) not supported")); command_aborted(channel, 0xB0); break;
-       case 0xB1: BX_ERROR(("read cmd 0xB1 (DEVICE CONFIGURATION FREEZE LOCK) not supported")); command_aborted(channel, 0xB1); break;
-       case 0xC0: BX_ERROR(("read cmd 0xC0 (CFA ERASE SECTORS) not supported")); command_aborted(channel, 0xC0); break;
-       case 0xC4: BX_ERROR(("read cmd 0xC4 (READ MULTIPLE) not supported")); command_aborted(channel, 0xC4); break;
-       case 0xC5: BX_ERROR(("read cmd 0xC5 (WRITE MULTIPLE) not supported")); command_aborted(channel, 0xC5); break;
-       case 0xC6: BX_ERROR(("read cmd 0xC6 (SET MULTIPLE MODE) not supported")); command_aborted(channel, 0xC6); break;
-       case 0xC7: BX_ERROR(("read cmd 0xC7 (READ DMA QUEUED) not supported")); command_aborted(channel, 0xC7); break;
-       case 0xC8: BX_ERROR(("read cmd 0xC8 (READ DMA) not supported")); command_aborted(channel, 0xC8); break;
-       case 0xC9: BX_ERROR(("read cmd 0xC9 (READ DMA NO RETRY) not supported")); command_aborted(channel, 0xC9); break;
-       case 0xCA: BX_ERROR(("read cmd 0xCA (WRITE DMA) not supported")); command_aborted(channel, 0xCA); break;
-       case 0xCC: BX_ERROR(("read cmd 0xCC (WRITE DMA QUEUED) not supported")); command_aborted(channel, 0xCC); break;
-       case 0xCD: BX_ERROR(("read cmd 0xCD (CFA WRITE MULTIPLE W/OUT ERASE) not supported")); command_aborted(channel, 0xCD); break;
-       case 0xD1: BX_ERROR(("read cmd 0xD1 (CHECK MEDIA CARD TYPE) not supported")); command_aborted(channel, 0xD1); break;
-       case 0xDA: BX_ERROR(("read cmd 0xDA (GET MEDIA STATUS) not supported")); command_aborted(channel, 0xDA); break;
-       case 0xDE: BX_ERROR(("read cmd 0xDE (MEDIA LOCK) not supported")); command_aborted(channel, 0xDE); break;
-       case 0xDF: BX_ERROR(("read cmd 0xDF (MEDIA UNLOCK) not supported")); command_aborted(channel, 0xDF); break;
-       case 0xE0: BX_ERROR(("read cmd 0xE0 (STANDBY IMMEDIATE) not supported")); command_aborted(channel, 0xE0); break;
-       case 0xE1: BX_ERROR(("read cmd 0xE1 (IDLE IMMEDIATE) not supported")); command_aborted(channel, 0xE1); break;
-       case 0xE2: BX_ERROR(("read cmd 0xE2 (STANDBY) not supported")); command_aborted(channel, 0xE2); break;
-       case 0xE3: BX_ERROR(("read cmd 0xE3 (IDLE) not supported")); command_aborted(channel, 0xE3); break;
-       case 0xE4: BX_ERROR(("read cmd 0xE4 (READ BUFFER) not supported")); command_aborted(channel, 0xE4); break;
-       case 0xE5: BX_ERROR(("read cmd 0xE5 (CHECK POWER MODE) not supported")); command_aborted(channel, 0xE5); break;
-       case 0xE6: BX_ERROR(("read cmd 0xE6 (SLEEP) not supported")); command_aborted(channel, 0xE6); break;
-       case 0xE7: BX_ERROR(("read cmd 0xE7 (FLUSH CACHE) not supported")); command_aborted(channel, 0xE7); break;
-       case 0xE8: BX_ERROR(("read cmd 0xE8 (WRITE BUFFER) not supported")); command_aborted(channel, 0xE8); break;
-       case 0xEA: BX_ERROR(("read cmd 0xEA (FLUSH CACHE EXT) not supported")); command_aborted(channel, 0xEA); break;
-       case 0xED: BX_ERROR(("read cmd 0xED (MEDIA EJECT) not supported")); command_aborted(channel, 0xED); break;
-       case 0xEF: BX_ERROR(("read cmd 0xEF (SET FEATURES) not supported")); command_aborted(channel, 0xEF); break;
-       case 0xF1: BX_ERROR(("read cmd 0xF1 (SECURITY SET PASSWORD) not supported")); command_aborted(channel, 0xF1); break;
-       case 0xF2: BX_ERROR(("read cmd 0xF2 (SECURITY UNLOCK) not supported")); command_aborted(channel, 0xF2); break;
-       case 0xF3: BX_ERROR(("read cmd 0xF3 (SECURITY ERASE PREPARE) not supported")); command_aborted(channel, 0xF3); break;
-       case 0xF4: BX_ERROR(("read cmd 0xF4 (SECURITY ERASE UNIT) not supported")); command_aborted(channel, 0xF4); break;
-       case 0xF5: BX_ERROR(("read cmd 0xF5 (SECURITY FREEZE LOCK) not supported")); command_aborted(channel, 0xF5); break;
-       case 0xF6: BX_ERROR(("read cmd 0xF6 (SECURITY DISABLE PASSWORD) not supported")); command_aborted(channel, 0xF6); break;
-       case 0xF8: BX_ERROR(("read cmd 0xF8 (READ NATIVE MAX ADDRESS) not supported")); command_aborted(channel, 0xF8); break;
-       case 0xF9: BX_ERROR(("read cmd 0xF9 (SET MAX ADDRESS) not supported")); command_aborted(channel, 0xF9); break;
-
-        default:
-          BX_PANIC(("IO read(0x%04x): current command is %02xh", address,
-            (unsigned) BX_SELECTED_CONTROLLER(channel).current_command));
-        }
-      break;
-
-    case 0x01: // hard disk error register 0x1f1
-      BX_SELECTED_CONTROLLER(channel).status.err = 0;
-      value8 = (!BX_SELECTED_IS_PRESENT(channel)) ? 0 : BX_SELECTED_CONTROLLER(channel).error_register;
-      goto return_value8;
-      break;
-    case 0x02: // hard disk sector count / interrupt reason 0x1f2
-      value8 = (!BX_SELECTED_IS_PRESENT(channel)) ? 0 : BX_SELECTED_CONTROLLER(channel).sector_count;
-      goto return_value8;
-      break;
-    case 0x03: // sector number 0x1f3
-      value8 = (!BX_SELECTED_IS_PRESENT(channel)) ? 0 : BX_SELECTED_CONTROLLER(channel).sector_no;
-      goto return_value8;
-    case 0x04: // cylinder low 0x1f4  
-               // -- WARNING : On real hardware the controller registers are shared between drives. 
-               // So we must respond even if the select device is not present. Some OS uses this fact 
-               // to detect the disks.... minix2 for example
-      value8 = (!BX_ANY_IS_PRESENT(channel)) ? 0 : (BX_SELECTED_CONTROLLER(channel).cylinder_no & 0x00ff);
-      goto return_value8;
-    case 0x05: // cylinder high 0x1f5
-               // -- WARNING : On real hardware the controller registers are shared between drives. 
-               // So we must respond even if the select device is not present. Some OS uses this fact 
-               // to detect the disks.... minix2 for example
-      value8 = (!BX_ANY_IS_PRESENT(channel)) ? 0 : BX_SELECTED_CONTROLLER(channel).cylinder_no >> 8;
-      goto return_value8;
-
-    case 0x06: // hard disk drive and head register 0x1f6
-      // b7 Extended data field for ECC
-      // b6/b5: Used to be sector size.  00=256,01=512,10=1024,11=128
-      //   Since 512 was always used, bit 6 was taken to mean LBA mode:
-      //     b6 1=LBA mode, 0=CHS mode
-      //     b5 1
-      // b4: DRV
-      // b3..0 HD3..HD0
-      value8 = (1 << 7) |
-               ((BX_SELECTED_CONTROLLER(channel).lba_mode>0) << 6) |
-               (1 << 5) | // 01b = 512 sector size
-               (BX_HD_THIS channels[channel].drive_select << 4) |
-               (BX_SELECTED_CONTROLLER(channel).head_no << 0);
-      goto return_value8;
-      break;
-//BX_CONTROLLER(channel,0).lba_mode
-
-    case 0x07: // Hard Disk Status 0x1f7
-    case 0x16: // Hard Disk Alternate Status 0x3f6
-      if (!BX_ANY_IS_PRESENT(channel)) {
-           // (mch) Just return zero for these registers
-           value8 = 0;
-      } else {
-      value8 = (
-        (BX_SELECTED_CONTROLLER(channel).status.busy << 7) |
-        (BX_SELECTED_CONTROLLER(channel).status.drive_ready << 6) |
-        (BX_SELECTED_CONTROLLER(channel).status.write_fault << 5) |
-        (BX_SELECTED_CONTROLLER(channel).status.seek_complete << 4) |
-        (BX_SELECTED_CONTROLLER(channel).status.drq << 3) |
-        (BX_SELECTED_CONTROLLER(channel).status.corrected_data << 2) |
-        (BX_SELECTED_CONTROLLER(channel).status.index_pulse << 1) |
-        (BX_SELECTED_CONTROLLER(channel).status.err) );
-      BX_SELECTED_CONTROLLER(channel).status.index_pulse_count++;
-      BX_SELECTED_CONTROLLER(channel).status.index_pulse = 0;
-      if (BX_SELECTED_CONTROLLER(channel).status.index_pulse_count >= INDEX_PULSE_CYCLE) {
-        BX_SELECTED_CONTROLLER(channel).status.index_pulse = 1;
-        BX_SELECTED_CONTROLLER(channel).status.index_pulse_count = 0;
-        }
-      }
-      if (port == 0x07) {
-        DEV_pic_lower_irq(BX_HD_THIS channels[channel].irq);
-        }
-      goto return_value8;
-      break;
-
-    case 0x17: // Hard Disk Address Register 0x3f7
-      // Obsolete and unsupported register.  Not driven by hard
-      // disk controller.  Report all 1's.  If floppy controller
-      // is handling this address, it will call this function
-      // set/clear D7 (the only bit it handles), then return
-      // the combined value
-      value8 = 0xff;
-      goto return_value8;
-      break;
-
-    default:
-      BX_PANIC(("hard drive: io read to address %x unsupported",
-        (unsigned) address));
-    }
-
-  BX_PANIC(("hard drive: shouldnt get here!"));
-  return(0);
-
-  return_value32:
-  BX_DEBUG(("32-bit read from %04x = %08x {%s}",
-           (unsigned) address, value32, BX_SELECTED_TYPE_STRING(channel)));
-  return value32;
-
-  return_value16:
-  BX_DEBUG(("16-bit read from %04x = %04x {%s}",
-           (unsigned) address, value16, BX_SELECTED_TYPE_STRING(channel)));
-  return value16;
-
-  return_value8:
-  BX_DEBUG(("8-bit read from %04x = %02x {%s}",
-           (unsigned) address, value8, BX_SELECTED_TYPE_STRING(channel)));
-  return value8;
-}
-
-
-  // static IO port write callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-  void
-bx_hard_drive_c::write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len)
-{
-#if !BX_USE_HD_SMF
-  bx_hard_drive_c *class_ptr = (bx_hard_drive_c *) this_ptr;
-
-  class_ptr->write(address, value, io_len);
-}
-
-  void
-bx_hard_drive_c::write(Bit32u address, Bit32u value, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif  // !BX_USE_HD_SMF
-  off_t logical_sector;
-  off_t ret;
-  bx_bool prev_control_reset;
-
-  Bit8u  channel = BX_MAX_ATA_CHANNEL;
-  Bit32u port = 0xff; // undefined
-
-  for (channel=0; channel<BX_MAX_ATA_CHANNEL; channel++) {
-    if ((address & 0xfff8) == BX_HD_THIS channels[channel].ioaddr1) {
-      port = address - BX_HD_THIS channels[channel].ioaddr1;
-      break;
-      }
-    else if ((address & 0xfff8) == BX_HD_THIS channels[channel].ioaddr2) {
-      port = address - BX_HD_THIS channels[channel].ioaddr2 + 0x10;
-      break;
-      }
-    }
-
-  if (channel == BX_MAX_ATA_CHANNEL) {
-    if (address != 0x03f6) {
-      BX_PANIC(("write: unable to find ATA channel, ioport=0x%04x", address));
-    } else {
-      channel = 0;
-      port = address - 0x03e0;
-    }
-  }
-
-#if BX_PDC20230C_VLBIDE_SUPPORT
-// pdc20230c is only available for first ata channel
-if (channel == 0) {
-  BX_HD_THIS pdc20230c.prog_count = 0;
-
-  if (BX_HD_THIS pdc20230c.prog_mode != 0) {
-    switch (port) {
-      case 0x03:
-       BX_HD_THIS pdc20230c.p1f3_value = value;
-       return;
-        break;
-      case 0x04:
-       BX_HD_THIS pdc20230c.p1f4_value = value;
-       return;
-        break;
-    }
-  }
-}
-#endif
-
-  if (bx_dbg.disk || (BX_SELECTED_IS_CD(channel) && bx_dbg.cdrom)) {
-       switch (io_len) {
-             case 1:
-                   BX_INFO(("8-bit write to %04x = %02x {%s}",
-                             (unsigned) address, (unsigned) value, BX_SELECTED_TYPE_STRING(channel)));
-                   break;
-                   
-             case 2:
-                   BX_INFO(("16-bit write to %04x = %04x {%s}",
-                             (unsigned) address, (unsigned) value, BX_SELECTED_TYPE_STRING(channel)));
-                   break;
-
-             case 4:
-                   BX_INFO(("32-bit write to %04x = %08x {%s}",
-                             (unsigned) address, (unsigned) value, BX_SELECTED_TYPE_STRING(channel)));
-                   break;
-
-             default:
-                   BX_INFO(("unknown-size write to %04x = %08x {%s}",
-                             (unsigned) address, (unsigned) value, BX_SELECTED_TYPE_STRING(channel)));
-                   break;
-       }
-  }
-
-  BX_DEBUG(("IO write to %04x = %02x", (unsigned) address, (unsigned) value));
-
-  switch (port) {
-    case 0x00: // 0x1f0
-      switch (BX_SELECTED_CONTROLLER(channel).current_command) {
-        case 0x30: // WRITE SECTORS
-          if (BX_SELECTED_CONTROLLER(channel).buffer_index >= 512)
-            BX_PANIC(("IO write(0x%04x): buffer_index >= 512", address));
-
-#if BX_SupportRepeatSpeedups
-          if (DEV_bulk_io_quantum_requested()) {
-            unsigned transferLen, quantumsMax;
-
-            quantumsMax =
-              (512 - BX_SELECTED_CONTROLLER(channel).buffer_index) / io_len;
-            if ( quantumsMax == 0)
-              BX_PANIC(("IO write(0x%04x): not enough space for write", address));
-            DEV_bulk_io_quantum_transferred() =
-                DEV_bulk_io_quantum_requested();
-            if (quantumsMax < DEV_bulk_io_quantum_transferred())
-              DEV_bulk_io_quantum_transferred() = quantumsMax;
-            transferLen = io_len * DEV_bulk_io_quantum_transferred();
-            memcpy(
-              &BX_SELECTED_CONTROLLER(channel).buffer[BX_SELECTED_CONTROLLER(channel).buffer_index], 
-              (Bit8u*) DEV_bulk_io_host_addr(),
-              transferLen);
-           DEV_bulk_io_host_addr() += transferLen;
-            BX_SELECTED_CONTROLLER(channel).buffer_index += transferLen;
-            }
-          else
-#endif
-            {
-            switch(io_len){
-              case 4:
-                BX_SELECTED_CONTROLLER(channel).buffer[BX_SELECTED_CONTROLLER(channel).buffer_index+3] = (Bit8u)(value >> 24);
-                BX_SELECTED_CONTROLLER(channel).buffer[BX_SELECTED_CONTROLLER(channel).buffer_index+2] = (Bit8u)(value >> 16);
-              case 2:
-                BX_SELECTED_CONTROLLER(channel).buffer[BX_SELECTED_CONTROLLER(channel).buffer_index+1] = (Bit8u)(value >> 8);
-                BX_SELECTED_CONTROLLER(channel).buffer[BX_SELECTED_CONTROLLER(channel).buffer_index]   = (Bit8u) value;
-              }
-            BX_SELECTED_CONTROLLER(channel).buffer_index += io_len;
-            }
-
-          /* if buffer completely writtten */
-          if (BX_SELECTED_CONTROLLER(channel).buffer_index >= 512) {
-            off_t logical_sector;
-            off_t ret;
-
-#if TEST_WRITE_BEYOND_END==1
-           BX_SELECTED_CONTROLLER(channel).cylinder_no += 100000;
-#endif
-           if (!calculate_logical_address(channel, &logical_sector)) {
-             BX_ERROR(("write reached invalid sector %lu, aborting", (unsigned long)logical_sector));
-             command_aborted (channel, BX_SELECTED_CONTROLLER(channel).current_command);
-             return;
-            }
-#if TEST_WRITE_BEYOND_END==2
-           logical_sector += 100000;
-#endif
-           ret = BX_SELECTED_DRIVE(channel).hard_drive->lseek(logical_sector * 512, SEEK_SET);
-            if (ret < 0) {
-              BX_ERROR(("could not lseek() hard drive image file at byte %lu", (unsigned long)logical_sector * 512));
-             command_aborted (channel, BX_SELECTED_CONTROLLER(channel).current_command);
-             return;
-           }
-           ret = BX_SELECTED_DRIVE(channel).hard_drive->write((bx_ptr_t) BX_SELECTED_CONTROLLER(channel).buffer, 512);
-            if (ret < 512) {
-              BX_ERROR(("could not write() hard drive image file at byte %lu", (unsigned long)logical_sector*512));
-             command_aborted (channel, BX_SELECTED_CONTROLLER(channel).current_command);
-             return;
-           }
-
-            BX_SELECTED_CONTROLLER(channel).buffer_index = 0;
-
-            /* update sector count, sector number, cylinder,
-             * drive, head, status
-             * if there are more sectors, read next one in...
-             */
-
-           increment_address(channel);
-
-            /* When the write is complete, controller clears the DRQ bit and
-             * sets the BSY bit.
-             * If at least one more sector is to be written, controller sets DRQ bit,
-             * clears BSY bit, and issues IRQ 
-             */
-
-            if (BX_SELECTED_CONTROLLER(channel).sector_count!=0) {
-              BX_SELECTED_CONTROLLER(channel).status.busy = 0;
-              BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
-              BX_SELECTED_CONTROLLER(channel).status.drq = 1;
-              BX_SELECTED_CONTROLLER(channel).status.corrected_data = 0;
-              BX_SELECTED_CONTROLLER(channel).status.err = 0;
-              }
-            else { /* no more sectors to write */
-              BX_SELECTED_CONTROLLER(channel).status.busy = 0;
-              BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
-              BX_SELECTED_CONTROLLER(channel).status.drq = 0;
-              BX_SELECTED_CONTROLLER(channel).status.err = 0;
-              BX_SELECTED_CONTROLLER(channel).status.corrected_data = 0;
-              }
-           raise_interrupt(channel);
-            }
-          break;
-
-           case 0xa0: // PACKET
-                 if (BX_SELECTED_CONTROLLER(channel).buffer_index >= PACKET_SIZE)
-                       BX_PANIC(("IO write(0x%04x): buffer_index >= PACKET_SIZE", address));
-                 BX_SELECTED_CONTROLLER(channel).buffer[BX_SELECTED_CONTROLLER(channel).buffer_index] = value;
-                 BX_SELECTED_CONTROLLER(channel).buffer[BX_SELECTED_CONTROLLER(channel).buffer_index+1] = (value >> 8);
-                 BX_SELECTED_CONTROLLER(channel).buffer_index += 2;
-
-                 /* if packet completely writtten */
-                 if (BX_SELECTED_CONTROLLER(channel).buffer_index >= PACKET_SIZE) {
-                       // complete command received
-                       Bit8u atapi_command = BX_SELECTED_CONTROLLER(channel).buffer[0];
-
-                       if (bx_dbg.cdrom)
-                               BX_INFO(("cdrom: ATAPI command 0x%x started", atapi_command));
-
-                       switch (atapi_command) {
-                             case 0x00: // test unit ready
-                                   if (BX_SELECTED_DRIVE(channel).cdrom.ready) {
-                                         atapi_cmd_nop(channel);
-                                   } else {
-                                         atapi_cmd_error(channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
-                                   }
-                                   raise_interrupt(channel);
-                                   break;
-
-                             case 0x03: { // request sense
-                                   int alloc_length = BX_SELECTED_CONTROLLER(channel).buffer[4];
-                                   init_send_atapi_command(channel, atapi_command, 18, alloc_length);
-
-                                   // sense data
-                                   BX_SELECTED_CONTROLLER(channel).buffer[0] = 0x70 | (1 << 7);
-                                   BX_SELECTED_CONTROLLER(channel).buffer[1] = 0;
-                                   BX_SELECTED_CONTROLLER(channel).buffer[2] = BX_SELECTED_DRIVE(channel).sense.sense_key;
-                                   BX_SELECTED_CONTROLLER(channel).buffer[3] = BX_SELECTED_DRIVE(channel).sense.information.arr[0];
-                                   BX_SELECTED_CONTROLLER(channel).buffer[4] = BX_SELECTED_DRIVE(channel).sense.information.arr[1];
-                                   BX_SELECTED_CONTROLLER(channel).buffer[5] = BX_SELECTED_DRIVE(channel).sense.information.arr[2];
-                                   BX_SELECTED_CONTROLLER(channel).buffer[6] = BX_SELECTED_DRIVE(channel).sense.information.arr[3];
-                                   BX_SELECTED_CONTROLLER(channel).buffer[7] = 17-7;
-                                   BX_SELECTED_CONTROLLER(channel).buffer[8] = BX_SELECTED_DRIVE(channel).sense.specific_inf.arr[0];
-                                   BX_SELECTED_CONTROLLER(channel).buffer[9] = BX_SELECTED_DRIVE(channel).sense.specific_inf.arr[1];
-                                   BX_SELECTED_CONTROLLER(channel).buffer[10] = BX_SELECTED_DRIVE(channel).sense.specific_inf.arr[2];
-                                   BX_SELECTED_CONTROLLER(channel).buffer[11] = BX_SELECTED_DRIVE(channel).sense.specific_inf.arr[3];
-                                   BX_SELECTED_CONTROLLER(channel).buffer[12] = BX_SELECTED_DRIVE(channel).sense.asc;
-                                   BX_SELECTED_CONTROLLER(channel).buffer[13] = BX_SELECTED_DRIVE(channel).sense.ascq;
-                                   BX_SELECTED_CONTROLLER(channel).buffer[14] = BX_SELECTED_DRIVE(channel).sense.fruc;
-                                   BX_SELECTED_CONTROLLER(channel).buffer[15] = BX_SELECTED_DRIVE(channel).sense.key_spec.arr[0];
-                                   BX_SELECTED_CONTROLLER(channel).buffer[16] = BX_SELECTED_DRIVE(channel).sense.key_spec.arr[1];
-                                   BX_SELECTED_CONTROLLER(channel).buffer[17] = BX_SELECTED_DRIVE(channel).sense.key_spec.arr[2];
-
-                                   ready_to_send_atapi(channel);
-                             }
-                             break;
-                             
-                             case 0x1b: { // start stop unit
-                                   //bx_bool Immed = (BX_SELECTED_CONTROLLER(channel).buffer[1] >> 0) & 1;
-                                   bx_bool LoEj = (BX_SELECTED_CONTROLLER(channel).buffer[4] >> 1) & 1;
-                                   bx_bool Start = (BX_SELECTED_CONTROLLER(channel).buffer[4] >> 0) & 1;
-
-                                   if (!LoEj && !Start) { // stop the disc
-                                         BX_ERROR(("FIXME: Stop disc not implemented"));
-                                         atapi_cmd_nop(channel);
-                                         raise_interrupt(channel);
-                                   } else if (!LoEj && Start) { // start (spin up) the disc
-#ifdef LOWLEVEL_CDROM
-                                         BX_SELECTED_DRIVE(channel).cdrom.cd->start_cdrom();
-#endif
-                                         BX_ERROR(("FIXME: ATAPI start disc not reading TOC"));
-                                         atapi_cmd_nop(channel);
-                                         raise_interrupt(channel);
-                                   } else if (LoEj && !Start) { // Eject the disc
-                                          atapi_cmd_nop(channel);
-
-                                          if (BX_SELECTED_DRIVE(channel).cdrom.ready) {
-#ifdef LOWLEVEL_CDROM
-                                           BX_SELECTED_DRIVE(channel).cdrom.cd->eject_cdrom();
-#endif
-                                           BX_SELECTED_DRIVE(channel).cdrom.ready = 0;
-                                            bx_options.atadevice[channel][BX_SLAVE_SELECTED(channel)].Ostatus->set(BX_EJECTED);
-                                            bx_gui->update_drive_status_buttons();
-                                          }
-                                          raise_interrupt(channel);
-                                   } else { // Load the disc
-                                         // My guess is that this command only closes the tray, that's a no-op for us
-                                         atapi_cmd_nop(channel);
-                                         raise_interrupt(channel);
-                                   }
-                             }
-                             break;
-
-                             case 0xbd: { // mechanism status
-                                   uint16 alloc_length = read_16bit(BX_SELECTED_CONTROLLER(channel).buffer + 8);
-
-                                   if (alloc_length == 0)
-                                         BX_PANIC(("Zero allocation length to MECHANISM STATUS not impl."));
-
-                                   init_send_atapi_command(channel, atapi_command, 8, alloc_length);
-
-                                   BX_SELECTED_CONTROLLER(channel).buffer[0] = 0; // reserved for non changers
-                                   BX_SELECTED_CONTROLLER(channel).buffer[1] = 0; // reserved for non changers
-
-                                   BX_SELECTED_CONTROLLER(channel).buffer[2] = 0; // Current LBA (TODO!)
-                                   BX_SELECTED_CONTROLLER(channel).buffer[3] = 0; // Current LBA (TODO!)
-                                   BX_SELECTED_CONTROLLER(channel).buffer[4] = 0; // Current LBA (TODO!)
-
-                                   BX_SELECTED_CONTROLLER(channel).buffer[5] = 1; // one slot
-
-                                   BX_SELECTED_CONTROLLER(channel).buffer[6] = 0; // slot table length
-                                   BX_SELECTED_CONTROLLER(channel).buffer[7] = 0; // slot table length
-
-                                   ready_to_send_atapi(channel);
-                             }
-                             break;
-
-                             case 0x5a: { // mode sense
-                                   uint16 alloc_length = read_16bit(BX_SELECTED_CONTROLLER(channel).buffer + 7);
-
-                                   Bit8u PC = BX_SELECTED_CONTROLLER(channel).buffer[2] >> 6;
-                                   Bit8u PageCode = BX_SELECTED_CONTROLLER(channel).buffer[2] & 0x3f;
-
-                                   switch (PC) {
-                                         case 0x0: // current values
-                                               switch (PageCode) {
-                                                     case 0x01: // error recovery
-                                                           init_send_atapi_command(channel, atapi_command, sizeof(error_recovery_t) + 8, alloc_length);
-
-                                                           init_mode_sense_single(channel, &BX_SELECTED_DRIVE(channel).cdrom.current.error_recovery,
-                                                                                  sizeof(error_recovery_t));
-                                                           ready_to_send_atapi(channel);
-                                                           break;
-
-                                                     case 0x2a: // CD-ROM capabilities & mech. status
-                                                             init_send_atapi_command(channel, atapi_command, 28, alloc_length);
-                                                             init_mode_sense_single(channel, &BX_SELECTED_CONTROLLER(channel).buffer[8], 28);
-                                                             BX_SELECTED_CONTROLLER(channel).buffer[8] = 0x2a;
-                                                             BX_SELECTED_CONTROLLER(channel).buffer[9] = 0x12;
-                                                             BX_SELECTED_CONTROLLER(channel).buffer[10] = 0x00;
-                                                             BX_SELECTED_CONTROLLER(channel).buffer[11] = 0x00;
-                                                             // Multisession, Mode 2 Form 2, Mode 2 Form 1
-                                                             BX_SELECTED_CONTROLLER(channel).buffer[12] = 0x70; 
-                                                             BX_SELECTED_CONTROLLER(channel).buffer[13] = (3 << 5);
-                                                             BX_SELECTED_CONTROLLER(channel).buffer[14] = (unsigned char)
-(1 |
-                                                                     (BX_SELECTED_DRIVE(channel).cdrom.locked ? (1 << 1) : 0) |
-                                                                     (1 << 3) |
-                                                                     (1 << 5));
-                                                             BX_SELECTED_CONTROLLER(channel).buffer[15] = 0x00;
-                                                             BX_SELECTED_CONTROLLER(channel).buffer[16] = (706 >> 8) & 0xff;
-                                                             BX_SELECTED_CONTROLLER(channel).buffer[17] = 706 & 0xff;
-                                                             BX_SELECTED_CONTROLLER(channel).buffer[18] = 0;
-                                                             BX_SELECTED_CONTROLLER(channel).buffer[19] = 2;
-                                                             BX_SELECTED_CONTROLLER(channel).buffer[20] = (512 >> 8) & 0xff;
-                                                             BX_SELECTED_CONTROLLER(channel).buffer[21] = 512 & 0xff;
-                                                             BX_SELECTED_CONTROLLER(channel).buffer[22] = (706 >> 8) & 0xff;
-                                                             BX_SELECTED_CONTROLLER(channel).buffer[23] = 706 & 0xff;
-                                                             BX_SELECTED_CONTROLLER(channel).buffer[24] = 0;
-                                                             BX_SELECTED_CONTROLLER(channel).buffer[25] = 0;
-                                                             BX_SELECTED_CONTROLLER(channel).buffer[26] = 0;
-                                                             BX_SELECTED_CONTROLLER(channel).buffer[27] = 0;
-                                                             ready_to_send_atapi(channel);
-                                                             break;
-
-                                                     case 0x0d: // CD-ROM
-                                                     case 0x0e: // CD-ROM audio control
-                                                     case 0x3f: // all
-                                                           BX_ERROR(("cdrom: MODE SENSE (curr), code=%x"
-                                                                     " not implemented yet",
-                                                                    PageCode));
-                                                           atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST,
-                                                                           ASC_INV_FIELD_IN_CMD_PACKET);
-                                                           raise_interrupt(channel);
-                                                           break;
-
-                                                     default:
-                                                           // not implemeted by this device
-                                                           BX_INFO(("cdrom: MODE SENSE PC=%x, PageCode=%x,"
-                                                                     " not implemented by device",
-                                                                     PC, PageCode));
-                                                           atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST,
-                                                                           ASC_INV_FIELD_IN_CMD_PACKET);
-                                                           raise_interrupt(channel);
-                                                           break;
-                                               }
-                                               break;
-
-                                         case 0x1: // changeable values
-                                               switch (PageCode) {
-                                                     case 0x01: // error recovery
-                                                     case 0x0d: // CD-ROM
-                                                     case 0x0e: // CD-ROM audio control
-                                                     case 0x2a: // CD-ROM capabilities & mech. status
-                                                     case 0x3f: // all
-                                                           BX_ERROR(("cdrom: MODE SENSE (chg), code=%x"
-                                                                     " not implemented yet",
-                                                                    PageCode));
-                                                           atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST,
-                                                                           ASC_INV_FIELD_IN_CMD_PACKET);
-                                                           raise_interrupt(channel);
-                                                           break;
-
-                                                     default:
-                                                           // not implemeted by this device
-                                                           BX_INFO(("cdrom: MODE SENSE PC=%x, PageCode=%x,"
-                                                                     " not implemented by device",
-                                                                     PC, PageCode));
-                                                           atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST,
-                                                                           ASC_INV_FIELD_IN_CMD_PACKET);
-                                                           raise_interrupt(channel);
-                                                           break;
-                                               }
-                                               break;
-
-                                         case 0x2: // default values
-                                               switch (PageCode) {
-                                                     case 0x01: // error recovery
-                                                     case 0x0d: // CD-ROM
-                                                     case 0x0e: // CD-ROM audio control
-                                                     case 0x2a: // CD-ROM capabilities & mech. status
-                                                     case 0x3f: // all
-                                                           BX_PANIC(("cdrom: MODE SENSE (dflt), code=%x",
-                                                                    PageCode));
-                                                           break;
-
-                                                     default:
-                                                           // not implemeted by this device
-                                                           BX_INFO(("cdrom: MODE SENSE PC=%x, PageCode=%x,"
-                                                                     " not implemented by device",
-                                                                     PC, PageCode));
-                                                           atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST,
-                                                                           ASC_INV_FIELD_IN_CMD_PACKET);
-                                                           raise_interrupt(channel);
-                                                           break;
-                                               }
-                                               break;
-
-                                         case 0x3: // saved values not implemented
-                                               atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST, ASC_SAVING_PARAMETERS_NOT_SUPPORTED);
-                                               raise_interrupt(channel);
-                                               break;
-
-                                         default:
-                                               BX_PANIC(("Should not get here!"));
-                                               break;
-                                   }
-                             }
-                             break;
-
-                             case 0x12: { // inquiry
-                                   uint8 alloc_length = BX_SELECTED_CONTROLLER(channel).buffer[4];
-
-                                   init_send_atapi_command(channel, atapi_command, 36, alloc_length);
-
-                                   BX_SELECTED_CONTROLLER(channel).buffer[0] = 0x05; // CD-ROM
-                                   BX_SELECTED_CONTROLLER(channel).buffer[1] = 0x80; // Removable
-                                   BX_SELECTED_CONTROLLER(channel).buffer[2] = 0x00; // ISO, ECMA, ANSI version
-                                   BX_SELECTED_CONTROLLER(channel).buffer[3] = 0x21; // ATAPI-2, as specified
-                                   BX_SELECTED_CONTROLLER(channel).buffer[4] = 31; // additional length (total 36)
-                                   BX_SELECTED_CONTROLLER(channel).buffer[5] = 0x00; // reserved
-                                   BX_SELECTED_CONTROLLER(channel).buffer[6] = 0x00; // reserved
-                                   BX_SELECTED_CONTROLLER(channel).buffer[7] = 0x00; // reserved
-
-                                   // Vendor ID
-                                   const char* vendor_id = "VTAB    ";
-                                    int i;
-                                   for (i = 0; i < 8; i++)
-                                         BX_SELECTED_CONTROLLER(channel).buffer[8+i] = vendor_id[i];
-
-                                   // Product ID
-                                   const char* product_id = "Turbo CD-ROM    ";
-                                   for (i = 0; i < 16; i++)
-                                         BX_SELECTED_CONTROLLER(channel).buffer[16+i] = product_id[i];
-
-                                   // Product Revision level
-                                   const char* rev_level = "1.0 ";
-                                   for (i = 0; i < 4; i++)
-                                         BX_SELECTED_CONTROLLER(channel).buffer[32+i] = rev_level[i];
-
-                                   ready_to_send_atapi(channel);
-                             }
-                             break;
-
-                             case 0x25: { // read cd-rom capacity
-                                   // no allocation length???
-                                   init_send_atapi_command(channel, atapi_command, 8, 8);
-
-                                   if (BX_SELECTED_DRIVE(channel).cdrom.ready) {
-                                         uint32 capacity = BX_SELECTED_DRIVE(channel).cdrom.capacity;
-                                         BX_INFO(("Capacity is %d sectors (%d bytes)", capacity, capacity * 2048));
-                                         BX_SELECTED_CONTROLLER(channel).buffer[0] = (capacity >> 24) & 0xff;
-                                         BX_SELECTED_CONTROLLER(channel).buffer[1] = (capacity >> 16) & 0xff;
-                                         BX_SELECTED_CONTROLLER(channel).buffer[2] = (capacity >> 8) & 0xff;
-                                         BX_SELECTED_CONTROLLER(channel).buffer[3] = (capacity >> 0) & 0xff;
-                                         BX_SELECTED_CONTROLLER(channel).buffer[4] = (2048 >> 24) & 0xff;
-                                         BX_SELECTED_CONTROLLER(channel).buffer[5] = (2048 >> 16) & 0xff;
-                                         BX_SELECTED_CONTROLLER(channel).buffer[6] = (2048 >> 8) & 0xff;
-                                         BX_SELECTED_CONTROLLER(channel).buffer[7] = (2048 >> 0) & 0xff;
-                                         ready_to_send_atapi(channel);
-                                   } else {
-                                         atapi_cmd_error(channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
-                                         raise_interrupt(channel);
-                                   }
-                             }
-                             break;
-
-                             case 0xbe: { // read cd
-                                   if (BX_SELECTED_DRIVE(channel).cdrom.ready) {
-                                         BX_ERROR(("Read CD with CD present not implemented"));
-                                         atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET);
-                                         raise_interrupt(channel);
-                                   } else {
-                                         atapi_cmd_error(channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
-                                         raise_interrupt(channel);
-                                   }
-                             }
-                             break;
-
-                             case 0x43: { // read toc
-                                   if (BX_SELECTED_DRIVE(channel).cdrom.ready) {
-#ifdef LOWLEVEL_CDROM
-                                         bool msf = (BX_SELECTED_CONTROLLER(channel).buffer[1] >> 1) & 1;
-                                         uint8 starting_track = BX_SELECTED_CONTROLLER(channel).buffer[6];
-#endif
-                                         uint16 alloc_length = read_16bit(BX_SELECTED_CONTROLLER(channel).buffer + 7);
-
-                                         uint8 format = (BX_SELECTED_CONTROLLER(channel).buffer[9] >> 6);
-                                          int i;
-                                         switch (format) {
-                                               case 0:
-#ifdef LOWLEVEL_CDROM
-                                                     int toc_length;
-                                                     if (!(BX_SELECTED_DRIVE(channel).cdrom.cd->read_toc(BX_SELECTED_CONTROLLER(channel).buffer,
-                                                                                      &toc_length, msf, starting_track))) {
-                                                           atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST,
-                                                                           ASC_INV_FIELD_IN_CMD_PACKET);
-                                                           raise_interrupt(channel);
-                                                     } else {
-                                                           init_send_atapi_command(channel, atapi_command, toc_length, alloc_length);
-                                                           ready_to_send_atapi(channel);
-                                                     }
-#else
-                                                     BX_PANIC(("LOWLEVEL_CDROM not defined"));
-#endif
-                                                     break;
-
-                                               case 1:
-                                                     // multi session stuff. we ignore this and emulate a single session only
-                                                     init_send_atapi_command(channel, atapi_command, 12, alloc_length);
-
-                                                     BX_SELECTED_CONTROLLER(channel).buffer[0] = 0;
-                                                     BX_SELECTED_CONTROLLER(channel).buffer[1] = 0x0a;
-                                                     BX_SELECTED_CONTROLLER(channel).buffer[2] = 1;
-                                                     BX_SELECTED_CONTROLLER(channel).buffer[3] = 1;
-                                                     for (i = 0; i < 8; i++)
-                                                           BX_SELECTED_CONTROLLER(channel).buffer[4+i] = 0;
-
-                                                     ready_to_send_atapi(channel);
-                                                     break;
-
-                                               case 2:
-                                               default:
-                                                     BX_PANIC(("(READ TOC) Format %d not supported", format));
-                                                     break;
-                                         }
-                                   } else {
-                                         atapi_cmd_error(channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
-                                         raise_interrupt(channel);
-                                   }
-                             }
-                             break;
-
-                             case 0x28: // read (10)
-                             case 0xa8: // read (12)
-                                        { 
-
-                                   uint32 transfer_length;
-                                   if (atapi_command == 0x28)
-                                         transfer_length = read_16bit(BX_SELECTED_CONTROLLER(channel).buffer + 7);
-                                   else
-                                         transfer_length = read_32bit(BX_SELECTED_CONTROLLER(channel).buffer + 6);
-
-                                   uint32 lba = read_32bit(BX_SELECTED_CONTROLLER(channel).buffer + 2);
-
-                                   if (!BX_SELECTED_DRIVE(channel).cdrom.ready) {
-                                         atapi_cmd_error(channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
-                                         raise_interrupt(channel);
-                                         break;
-                                   }
-
-                                   if (transfer_length == 0) {
-                                         atapi_cmd_nop(channel);
-                                         raise_interrupt(channel);
-                                         BX_INFO(("READ(%d) with transfer length 0, ok", atapi_command==0x28?10:12));
-                                         break;
-                                   }
-
-                                   if (lba + transfer_length > BX_SELECTED_DRIVE(channel).cdrom.capacity) {
-                                         atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST, ASC_LOGICAL_BLOCK_OOR);
-                                         raise_interrupt(channel);
-                                         break;
-                                   }
-
-                                   BX_DEBUG(("cdrom: READ (%d) LBA=%d LEN=%d", atapi_command==0x28?10:12, lba, transfer_length));
-
-                                   // handle command
-                                   init_send_atapi_command(channel, atapi_command, transfer_length * 2048,
-                                                           transfer_length * 2048, true);
-                                   BX_SELECTED_DRIVE(channel).cdrom.remaining_blocks = transfer_length;
-                                   BX_SELECTED_DRIVE(channel).cdrom.next_lba = lba;
-                                   ready_to_send_atapi(channel);
-                             }
-                             break;
-
-                               case 0x2b: { // seek
-                                       uint32 lba = read_32bit(BX_SELECTED_CONTROLLER(channel).buffer + 2);
-                                       if (!BX_SELECTED_DRIVE(channel).cdrom.ready) {
-                                               atapi_cmd_error(channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
-                                               raise_interrupt(channel);
-                                               break;
-                                       }
-
-                                       if (lba > BX_SELECTED_DRIVE(channel).cdrom.capacity) {
-                                               atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST, ASC_LOGICAL_BLOCK_OOR);
-                                               raise_interrupt(channel);
-                                               break;
-                                       }
-                                       BX_INFO(("cdrom: SEEK (ignored)"));
-                                       atapi_cmd_nop(channel);
-                                       raise_interrupt(channel);
-                               }
-                               break;
-
-                             case 0x1e: { // prevent/allow medium removal
-                                   if (BX_SELECTED_DRIVE(channel).cdrom.ready) {
-                                         BX_SELECTED_DRIVE(channel).cdrom.locked = BX_SELECTED_CONTROLLER(channel).buffer[4] & 1;
-                                         atapi_cmd_nop(channel);
-                                   } else {
-                                         atapi_cmd_error(channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
-                                   }
-                                   raise_interrupt(channel);
-                             }
-                             break;
-
-                             case 0x42: { // read sub-channel
-                                   bool msf = get_packet_field(channel,1, 1, 1);
-                                   bool sub_q = get_packet_field(channel,2, 6, 1);
-                                   uint8 data_format = get_packet_byte(channel,3);
-                                   uint8 track_number = get_packet_byte(channel,6);
-                                   uint16 alloc_length = get_packet_word(channel,7);
-                                    UNUSED(msf);
-                                    UNUSED(data_format);
-                                    UNUSED(track_number);
-
-                                   if (!BX_SELECTED_DRIVE(channel).cdrom.ready) {
-                                         atapi_cmd_error(channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
-                                         raise_interrupt(channel);
-                                   } else {
-                                         BX_SELECTED_CONTROLLER(channel).buffer[0] = 0;
-                                         BX_SELECTED_CONTROLLER(channel).buffer[1] = 0; // audio not supported
-                                         BX_SELECTED_CONTROLLER(channel).buffer[2] = 0;
-                                         BX_SELECTED_CONTROLLER(channel).buffer[3] = 0;
-
-                                         int ret_len = 4; // header size
-
-                                         if (sub_q) { // !sub_q == header only
-                                               BX_ERROR(("Read sub-channel with SubQ not implemented"));
-                                               atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST,
-                                                               ASC_INV_FIELD_IN_CMD_PACKET);
-                                           raise_interrupt(channel);
-                                         }
-
-                                         init_send_atapi_command(channel, atapi_command, ret_len, alloc_length);
-                                         ready_to_send_atapi(channel);
-                                   }
-                             }
-                             break;
-
-                             case 0x51: { // read disc info
-                                // no-op to keep the Linux CD-ROM driver happy
-                               atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET);
-                               raise_interrupt(channel);
-                             }
-                             break;
-
-                             case 0x55: // mode select
-                             case 0xa6: // load/unload cd
-                             case 0x4b: // pause/resume
-                             case 0x45: // play audio
-                             case 0x47: // play audio msf
-                             case 0xbc: // play cd
-                             case 0xb9: // read cd msf
-                             case 0x44: // read header
-                             case 0xba: // scan
-                             case 0xbb: // set cd speed
-                             case 0x4e: // stop play/scan
-                             case 0x46: // ???
-                             case 0x4a: // ???
-                               BX_ERROR(("ATAPI command 0x%x not implemented yet",
-                                         atapi_command));
-                               atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET);
-                               raise_interrupt(channel);
-                               break;
-                             default:
-                                   BX_PANIC(("Unknown ATAPI command 0x%x (%d)",
-                                            atapi_command, atapi_command));
-                                    // We'd better signal the error if the user chose to continue
-                                   atapi_cmd_error(channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET);
-                                   raise_interrupt(channel);
-                                   break;
-                       }
-                 }
-
-                 break;
-
-        default:
-          BX_PANIC(("IO write(0x%04x): current command is %02xh", address,
-            (unsigned) BX_SELECTED_CONTROLLER(channel).current_command));
-        }
-      break;
-
-    case 0x01: // hard disk write precompensation 0x1f1
-         WRITE_FEATURES(channel,value);
-         if (bx_dbg.disk || (BX_SELECTED_IS_CD(channel) && bx_dbg.cdrom)) {
-               if (value == 0xff)
-                     BX_INFO(("no precompensation {%s}", BX_SELECTED_TYPE_STRING(channel)));
-               else
-                     BX_INFO(("precompensation value %02x {%s}", (unsigned) value, BX_SELECTED_TYPE_STRING(channel)));
-         }
-      break;
-
-    case 0x02: // hard disk sector count 0x1f2
-         WRITE_SECTOR_COUNT(channel,value);
-         if (bx_dbg.disk || (BX_SELECTED_IS_CD(channel) && bx_dbg.cdrom))
-               BX_INFO(("sector count = %u {%s}", (unsigned) value, BX_SELECTED_TYPE_STRING(channel)));
-         break;
-
-    case 0x03: // hard disk sector number 0x1f3
-         WRITE_SECTOR_NUMBER(channel,value);
-         if (bx_dbg.disk || (BX_SELECTED_IS_CD(channel) && bx_dbg.cdrom))
-               BX_INFO(("sector number = %u {%s}", (unsigned) value, BX_SELECTED_TYPE_STRING(channel)));
-      break;
-
-    case 0x04: // hard disk cylinder low 0x1f4
-         WRITE_CYLINDER_LOW(channel,value);
-         if (bx_dbg.disk || (BX_SELECTED_IS_CD(channel) && bx_dbg.cdrom))
-               BX_INFO(("cylinder low = %02xh {%s}", (unsigned) value, BX_SELECTED_TYPE_STRING(channel)));
-         break;
-
-    case 0x05: // hard disk cylinder high 0x1f5
-         WRITE_CYLINDER_HIGH(channel,value);
-         if (bx_dbg.disk || (BX_SELECTED_IS_CD(channel) && bx_dbg.cdrom))
-               BX_INFO(("cylinder high = %02xh {%s}", (unsigned) value, BX_SELECTED_TYPE_STRING(channel)));
-         break;
-
-    case 0x06: // hard disk drive and head register 0x1f6
-      // b7 Extended data field for ECC
-      // b6/b5: Used to be sector size.  00=256,01=512,10=1024,11=128
-      //   Since 512 was always used, bit 6 was taken to mean LBA mode:
-      //     b6 1=LBA mode, 0=CHS mode
-      //     b5 1
-      // b4: DRV
-      // b3..0 HD3..HD0
-      {
-      if ( (value & 0xa0) != 0xa0 ) // 1x1xxxxx
-        BX_INFO(("IO write 0x%04x (%02x): not 1x1xxxxxb", address, (unsigned) value));
-      Bit32u drvsel = BX_HD_THIS channels[channel].drive_select = (value >> 4) & 0x01;
-      WRITE_HEAD_NO(channel,value & 0xf);
-      if (BX_SELECTED_CONTROLLER(channel).lba_mode == 0 && ((value >> 6) & 1) == 1)
-        BX_DEBUG(("enabling LBA mode"));
-      WRITE_LBA_MODE(channel,(value >> 6) & 1);
-      if (!BX_SELECTED_IS_PRESENT(channel)) {
-        BX_ERROR (("device set to %d which does not exist",drvsel));
-        BX_SELECTED_CONTROLLER(channel).error_register = 0x04; // aborted
-        BX_SELECTED_CONTROLLER(channel).status.err = 1;
-        }
-      break;
-      }
-
-    case 0x07: // hard disk command 0x1f7
-         // (mch) Writes to the command register with drive_select != 0
-         // are ignored if no secondary device is present
-      if ((BX_SLAVE_SELECTED(channel)) && (!BX_SLAVE_IS_PRESENT(channel)))
-           break;
-      // Writes to the command register clear the IRQ
-      DEV_pic_lower_irq(BX_HD_THIS channels[channel].irq);
-
-      if (BX_SELECTED_CONTROLLER(channel).status.busy)
-        BX_PANIC(("hard disk: command sent, controller BUSY"));
-      if ( (value & 0xf0) == 0x10 )
-        value = 0x10;
-      switch (value) {
-
-        case 0x10: // CALIBRATE DRIVE
-         if (!BX_SELECTED_IS_HD(channel))
-               BX_PANIC(("calibrate drive issued to non-disk"));
-          if (!BX_SELECTED_IS_PRESENT(channel)) {
-            BX_SELECTED_CONTROLLER(channel).error_register = 0x02; // Track 0 not found
-            BX_SELECTED_CONTROLLER(channel).status.busy = 0;
-            BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
-            BX_SELECTED_CONTROLLER(channel).status.seek_complete = 0;
-            BX_SELECTED_CONTROLLER(channel).status.drq = 0;
-            BX_SELECTED_CONTROLLER(channel).status.err = 1;
-           raise_interrupt(channel);
-            BX_INFO(("calibrate drive: disk ata%d-%d not present", channel, BX_SLAVE_SELECTED(channel)));
-            break;
-            }
-
-          /* move head to cylinder 0, issue IRQ */
-          BX_SELECTED_CONTROLLER(channel).error_register = 0;
-          BX_SELECTED_CONTROLLER(channel).cylinder_no = 0;
-          BX_SELECTED_CONTROLLER(channel).status.busy = 0;
-          BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
-          BX_SELECTED_CONTROLLER(channel).status.seek_complete = 1;
-          BX_SELECTED_CONTROLLER(channel).status.drq = 0;
-          BX_SELECTED_CONTROLLER(channel).status.err = 0;
-         raise_interrupt(channel);
-          break;
-
-        case 0x20: // READ MULTIPLE SECTORS, with retries
-        case 0x21: // READ MULTIPLE SECTORS, without retries
-          /* update sector_no, always points to current sector
-           * after each sector is read to buffer, DRQ bit set and issue IRQ 
-           * if interrupt handler transfers all data words into main memory,
-           * and more sectors to read, then set BSY bit again, clear DRQ and
-           * read next sector into buffer
-           * sector count of 0 means 256 sectors
-           */
-
-         if (!BX_SELECTED_IS_HD(channel)) {
-               BX_ERROR(("read multiple issued to non-disk"));
-               command_aborted(channel, value);
-               break;
-         }
-
-          BX_SELECTED_CONTROLLER(channel).current_command = value;
-
-         // Lose98 accesses 0/0/0 in CHS mode
-         if (!BX_SELECTED_CONTROLLER(channel).lba_mode &&
-             !BX_SELECTED_CONTROLLER(channel).head_no &&
-             !BX_SELECTED_CONTROLLER(channel).cylinder_no &&
-             !BX_SELECTED_CONTROLLER(channel).sector_no) {
-               BX_INFO(("Read from 0/0/0, aborting command"));
-               command_aborted(channel, value);
-               break;
-         }
-
-#if TEST_READ_BEYOND_END==2
-         BX_SELECTED_CONTROLLER(channel).cylinder_no += 100000;
-#endif
-         if (!calculate_logical_address(channel, &logical_sector)) {
-           BX_ERROR(("initial read from sector %lu out of bounds, aborting", (unsigned long)logical_sector));
-           command_aborted(channel, value);
-           break;
-         }
-#if TEST_READ_BEYOND_END==3
-         logical_sector += 100000;
-#endif
-         ret=BX_SELECTED_DRIVE(channel).hard_drive->lseek(logical_sector * 512, SEEK_SET);
-          if (ret < 0) {
-            BX_ERROR (("could not lseek() hard drive image file, aborting"));
-           command_aborted(channel, value);
-           break;
-         }
-         ret = BX_SELECTED_DRIVE(channel).hard_drive->read((bx_ptr_t) BX_SELECTED_CONTROLLER(channel).buffer, 512);
-          if (ret < 512) {
-            BX_ERROR(("logical sector was %lu", (unsigned long)logical_sector));
-            BX_ERROR(("could not read() hard drive image file at byte %lu", (unsigned long)logical_sector*512));
-           command_aborted(channel, value);
-           break;
-         }
-
-          BX_SELECTED_CONTROLLER(channel).error_register = 0;
-          BX_SELECTED_CONTROLLER(channel).status.busy  = 0;
-          BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
-          BX_SELECTED_CONTROLLER(channel).status.seek_complete = 1;
-          BX_SELECTED_CONTROLLER(channel).status.drq   = 1;
-          BX_SELECTED_CONTROLLER(channel).status.corrected_data = 0;
-          BX_SELECTED_CONTROLLER(channel).status.err   = 0;
-          BX_SELECTED_CONTROLLER(channel).buffer_index = 0;
-         raise_interrupt(channel);
-          break;
-
-        case 0x30: /* WRITE SECTORS, with retries */
-          /* update sector_no, always points to current sector
-           * after each sector is read to buffer, DRQ bit set and issue IRQ 
-           * if interrupt handler transfers all data words into main memory,
-           * and more sectors to read, then set BSY bit again, clear DRQ and
-           * read next sector into buffer
-           * sector count of 0 means 256 sectors
-           */
-
-         if (!BX_SELECTED_IS_HD(channel))
-               BX_PANIC(("write multiple issued to non-disk"));
-
-          if (BX_SELECTED_CONTROLLER(channel).status.busy) {
-            BX_PANIC(("write command: BSY bit set"));
-            }
-          BX_SELECTED_CONTROLLER(channel).current_command = value;
-
-          // implicit seek done :^)
-          BX_SELECTED_CONTROLLER(channel).error_register = 0;
-          BX_SELECTED_CONTROLLER(channel).status.busy = 0;
-          // BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
-          BX_SELECTED_CONTROLLER(channel).status.seek_complete = 1;
-          BX_SELECTED_CONTROLLER(channel).status.drq = 1;
-          BX_SELECTED_CONTROLLER(channel).status.err   = 0;
-          BX_SELECTED_CONTROLLER(channel).buffer_index = 0;
-          break;
-
-        case 0x90: // EXECUTE DEVICE DIAGNOSTIC
-          if (BX_SELECTED_CONTROLLER(channel).status.busy) {
-            BX_PANIC(("diagnostic command: BSY bit set"));
-            }
-         if (!BX_SELECTED_IS_HD(channel))
-               BX_PANIC(("drive diagnostics issued to non-disk"));
-          BX_SELECTED_CONTROLLER(channel).error_register = 0x81; // Drive 1 failed, no error on drive 0
-          // BX_SELECTED_CONTROLLER(channel).status.busy = 0; // not needed
-          BX_SELECTED_CONTROLLER(channel).status.drq = 0;
-          BX_SELECTED_CONTROLLER(channel).status.err = 0;
-          break;
-
-        case 0x91: // INITIALIZE DRIVE PARAMETERS
-          if (BX_SELECTED_CONTROLLER(channel).status.busy) {
-            BX_PANIC(("init drive parameters command: BSY bit set"));
-            }
-         if (!BX_SELECTED_IS_HD(channel))
-               BX_PANIC(("initialize drive parameters issued to non-disk"));
-          // sets logical geometry of specified drive
-          BX_DEBUG(("init drive params: sec=%u, drive sel=%u, head=%u",
-            (unsigned) BX_SELECTED_CONTROLLER(channel).sector_count,
-            (unsigned) BX_HD_THIS channels[channel].drive_select,
-            (unsigned) BX_SELECTED_CONTROLLER(channel).head_no));
-          if (!BX_SELECTED_IS_PRESENT(channel)) {
-            BX_PANIC(("init drive params: disk ata%d-%d not present", channel, BX_SLAVE_SELECTED(channel)));
-            //BX_SELECTED_CONTROLLER(channel).error_register = 0x12;
-            BX_SELECTED_CONTROLLER(channel).status.busy = 0;
-            BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
-            BX_SELECTED_CONTROLLER(channel).status.drq = 0;
-            BX_SELECTED_CONTROLLER(channel).status.err = 0;
-           raise_interrupt(channel);
-            break;
-         }
-          if (BX_SELECTED_CONTROLLER(channel).sector_count != BX_SELECTED_DRIVE(channel).hard_drive->sectors)
-            BX_PANIC(("init drive params: sector count doesnt match %d!=%d", BX_SELECTED_CONTROLLER(channel).sector_count, BX_SELECTED_DRIVE(channel).hard_drive->sectors));
-          if ( BX_SELECTED_CONTROLLER(channel).head_no != (BX_SELECTED_DRIVE(channel).hard_drive->heads-1) )
-            BX_PANIC(("init drive params: head number doesn't match %d != %d",BX_SELECTED_CONTROLLER(channel).head_no, BX_SELECTED_DRIVE(channel).hard_drive->heads-1));
-          BX_SELECTED_CONTROLLER(channel).status.busy = 0;
-          BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
-          BX_SELECTED_CONTROLLER(channel).status.drq = 0;
-          BX_SELECTED_CONTROLLER(channel).status.err = 0;
-         raise_interrupt(channel);
-          break;
-
-        case 0xec: // IDENTIFY DEVICE
-          if (bx_options.OnewHardDriveSupport->get ()) {
-           if (bx_dbg.disk || (BX_SELECTED_IS_CD(channel) && bx_dbg.cdrom))
-                 BX_INFO(("Drive ID Command issued : 0xec "));
-
-            if (!BX_SELECTED_IS_PRESENT(channel)) {
-              BX_INFO(("disk ata%d-%d not present, aborting",channel,BX_SLAVE_SELECTED(channel)));
-              command_aborted(channel, value);
-              break;
-              }
-           if (BX_SELECTED_IS_CD(channel)) {
-                 BX_SELECTED_CONTROLLER(channel).head_no        = 0;
-                 BX_SELECTED_CONTROLLER(channel).sector_count   = 1;
-                 BX_SELECTED_CONTROLLER(channel).sector_no      = 1;
-                 BX_SELECTED_CONTROLLER(channel).cylinder_no    = 0xeb14;
-                 command_aborted(channel, 0xec);
-           } else {
-                 BX_SELECTED_CONTROLLER(channel).current_command = value;
-                 BX_SELECTED_CONTROLLER(channel).error_register = 0;
-
-                 // See ATA/ATAPI-4, 8.12
-                 BX_SELECTED_CONTROLLER(channel).status.busy  = 0;
-                 BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
-                 BX_SELECTED_CONTROLLER(channel).status.write_fault = 0;
-                 BX_SELECTED_CONTROLLER(channel).status.drq   = 1;
-                 BX_SELECTED_CONTROLLER(channel).status.err   = 0;
-
-                 BX_SELECTED_CONTROLLER(channel).status.seek_complete = 1;
-                 BX_SELECTED_CONTROLLER(channel).status.corrected_data = 0;
-
-                 BX_SELECTED_CONTROLLER(channel).buffer_index = 0;
-                 raise_interrupt(channel);
-                 identify_drive(channel);
-           }
-         }
-          else {
-           BX_INFO(("sent IDENTIFY DEVICE (0xec) to old hard drive"));
-            command_aborted(channel, value);
-         }
-          break;
-
-        case 0xef: // SET FEATURES
-         switch(BX_SELECTED_CONTROLLER(channel).features) {
-           case 0x02: // Enable and
-           case 0x82: //  Disable write cache.
-           case 0xAA: // Enable and
-           case 0x55: //  Disable look-ahead cache.
-           case 0xCC: // Enable and
-           case 0x66: //  Disable reverting to power-on default
-             BX_INFO(("SET FEATURES subcommand 0x%02x not supported by disk.", (unsigned) BX_SELECTED_CONTROLLER(channel).features));
-             command_aborted(channel, value);
-           break;
-
-           default:
-             BX_PANIC(("SET FEATURES with unknown subcommand: 0x%02x", (unsigned) BX_SELECTED_CONTROLLER(channel).features ));
-              // We'd better signal the error if the user chose to continue
-             command_aborted(channel, value);
-         }
-         break;
-
-        case 0x40: // READ VERIFY SECTORS
-          if (bx_options.OnewHardDriveSupport->get ()) {
-           if (!BX_SELECTED_IS_HD(channel))
-               BX_PANIC(("read verify issued to non-disk"));
-            BX_INFO(("Verify Command : 0x40 ! "));
-            BX_SELECTED_CONTROLLER(channel).status.busy = 0;
-            BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
-            BX_SELECTED_CONTROLLER(channel).status.drq = 0;
-            BX_SELECTED_CONTROLLER(channel).status.err = 0;
-           raise_interrupt(channel);
-            }
-          else {
-           BX_INFO(("sent READ VERIFY SECTORS (0x40) to old hard drive"));
-            command_aborted(channel, value);
-         }
-          break;
-
-       case 0xc6: // SET MULTIPLE MODE (mch)
-             if (BX_SELECTED_CONTROLLER(channel).sector_count != 128 &&
-                 BX_SELECTED_CONTROLLER(channel).sector_count != 64 &&
-                 BX_SELECTED_CONTROLLER(channel).sector_count != 32 &&
-                 BX_SELECTED_CONTROLLER(channel).sector_count != 16 &&
-                 BX_SELECTED_CONTROLLER(channel).sector_count != 8 &&
-                 BX_SELECTED_CONTROLLER(channel).sector_count != 4 &&
-                 BX_SELECTED_CONTROLLER(channel).sector_count != 2)
-                   command_aborted(channel, value);
-
-             if (!BX_SELECTED_IS_HD(channel))
-               BX_PANIC(("set multiple mode issued to non-disk"));
-
-             BX_SELECTED_CONTROLLER(channel).sectors_per_block = BX_SELECTED_CONTROLLER(channel).sector_count;
-             BX_SELECTED_CONTROLLER(channel).status.busy = 0;
-             BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
-             BX_SELECTED_CONTROLLER(channel).status.write_fault = 0;
-             BX_SELECTED_CONTROLLER(channel).status.drq = 0;
-             BX_SELECTED_CONTROLLER(channel).status.err = 0;
-             break;
-
-        // ATAPI commands
-        case 0xa1: // IDENTIFY PACKET DEVICE
-             if (BX_SELECTED_IS_CD(channel)) {
-                   BX_SELECTED_CONTROLLER(channel).current_command = value;
-                   BX_SELECTED_CONTROLLER(channel).error_register = 0;
-
-                   BX_SELECTED_CONTROLLER(channel).status.busy = 0;
-                   BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
-                   BX_SELECTED_CONTROLLER(channel).status.write_fault = 0;
-                   BX_SELECTED_CONTROLLER(channel).status.drq   = 1;
-                   BX_SELECTED_CONTROLLER(channel).status.err   = 0;
-
-                   BX_SELECTED_CONTROLLER(channel).status.seek_complete = 1;
-                   BX_SELECTED_CONTROLLER(channel).status.corrected_data = 0;
-
-                   BX_SELECTED_CONTROLLER(channel).buffer_index = 0;
-                   raise_interrupt(channel);
-                   identify_ATAPI_drive(channel);
-             } else {
-                   command_aborted(channel, 0xa1);
-             }
-             break;
-
-        case 0x08: // DEVICE RESET (atapi)
-             if (BX_SELECTED_IS_CD(channel)) {
-                   BX_SELECTED_CONTROLLER(channel).status.busy = 1;
-                   BX_SELECTED_CONTROLLER(channel).error_register &= ~(1 << 7);
-
-                   // device signature
-                   BX_SELECTED_CONTROLLER(channel).head_no        = 0;
-                   BX_SELECTED_CONTROLLER(channel).sector_count   = 1;
-                   BX_SELECTED_CONTROLLER(channel).sector_no      = 1;
-                   BX_SELECTED_CONTROLLER(channel).cylinder_no    = 0xeb14;
-
-                   BX_SELECTED_CONTROLLER(channel).status.write_fault = 0;
-                   BX_SELECTED_CONTROLLER(channel).status.drq = 0;
-                   BX_SELECTED_CONTROLLER(channel).status.corrected_data = 0;
-                   BX_SELECTED_CONTROLLER(channel).status.err = 0;
-
-                   BX_SELECTED_CONTROLLER(channel).status.busy = 0;
-
-             } else {
-               BX_DEBUG(("ATAPI Device Reset on non-cd device"));
-               command_aborted(channel, 0x08);
-             }
-             break;
-
-        case 0xa0: // SEND PACKET (atapi)
-             if (BX_SELECTED_IS_CD(channel)) {
-                   // PACKET
-                   if (BX_SELECTED_CONTROLLER(channel).features & (1 << 0))
-                         BX_PANIC(("PACKET-DMA not supported"));
-                   if (BX_SELECTED_CONTROLLER(channel).features & (1 << 1))
-                         BX_PANIC(("PACKET-overlapped not supported"));
-
-                   // We're already ready!
-                   BX_SELECTED_CONTROLLER(channel).sector_count = 1;
-                   BX_SELECTED_CONTROLLER(channel).status.busy = 0;
-                   BX_SELECTED_CONTROLLER(channel).status.write_fault = 0;
-                   // serv bit??
-                   BX_SELECTED_CONTROLLER(channel).status.drq = 1;
-                   BX_SELECTED_CONTROLLER(channel).status.err = 0;
-
-                   // NOTE: no interrupt here
-                   BX_SELECTED_CONTROLLER(channel).current_command = value;
-                   BX_SELECTED_CONTROLLER(channel).buffer_index = 0;
-             } else {
-               command_aborted (channel, 0xa0);
-             }
-             break;
-
-        case 0xa2: // SERVICE (atapi), optional
-             if (BX_SELECTED_IS_CD(channel)) {
-                   BX_PANIC(("ATAPI SERVICE not implemented"));
-             } else {
-               command_aborted (channel, 0xa2);
-             }
-             break;
-
-        // power management
-       case 0xe5: // CHECK POWER MODE
-         BX_SELECTED_CONTROLLER(channel).status.busy = 0;
-         BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
-         BX_SELECTED_CONTROLLER(channel).status.write_fault = 0;
-         BX_SELECTED_CONTROLLER(channel).status.drq = 0;
-         BX_SELECTED_CONTROLLER(channel).status.err = 0;
-         BX_SELECTED_CONTROLLER(channel).sector_count = 0xff; // Active or Idle mode
-         raise_interrupt(channel);
-         break;
-
-       case 0x70:  // SEEK (cgs)
-         if (BX_SELECTED_IS_HD(channel)) {
-           BX_DEBUG(("write cmd 0x70 (SEEK) executing"));
-            if (!calculate_logical_address(channel, &logical_sector)) {
-             BX_ERROR(("initial seek to sector %lu out of bounds, aborting", (unsigned long)logical_sector));
-              command_aborted(channel, value);
-             break;
-           }
-            BX_SELECTED_CONTROLLER(channel).error_register = 0;
-            BX_SELECTED_CONTROLLER(channel).status.busy  = 0;
-            BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
-            BX_SELECTED_CONTROLLER(channel).status.seek_complete = 1;
-            BX_SELECTED_CONTROLLER(channel).status.drq   = 0;
-            BX_SELECTED_CONTROLLER(channel).status.corrected_data = 0;
-            BX_SELECTED_CONTROLLER(channel).status.err   = 0;
-            BX_SELECTED_CONTROLLER(channel).buffer_index = 0;
-           BX_DEBUG(("s[0].controller.control.disable_irq = %02x", (BX_HD_THIS channels[channel].drives[0]).controller.control.disable_irq));
-           BX_DEBUG(("s[1].controller.control.disable_irq = %02x", (BX_HD_THIS channels[channel].drives[1]).controller.control.disable_irq));
-           BX_DEBUG(("SEEK completed.  error_register = %02x", BX_SELECTED_CONTROLLER(channel).error_register));
-           raise_interrupt(channel);
-           BX_DEBUG(("SEEK interrupt completed"));
-          } else {
-           BX_ERROR(("write cmd 0x70 (SEEK) not supported for non-disk"));
-           command_aborted(channel, 0x70); 
-         }
-          break;
-
-
-
-       // List all the write operations that are defined in the ATA/ATAPI spec
-       // that we don't support.  Commands that are listed here will cause a
-       // BX_ERROR, which is non-fatal, and the command will be aborted.
-       case 0x22: BX_ERROR(("write cmd 0x22 (READ LONG) not supported")); command_aborted(channel, 0x22); break;
-       case 0x23: BX_ERROR(("write cmd 0x23 (READ LONG NO RETRY) not supported")); command_aborted(channel, 0x23); break;
-       case 0x24: BX_ERROR(("write cmd 0x24 (READ SECTORS EXT) not supported"));command_aborted(channel, 0x24); break;
-       case 0x25: BX_ERROR(("write cmd 0x25 (READ DMA EXT) not supported"));command_aborted(channel, 0x25); break;
-       case 0x26: BX_ERROR(("write cmd 0x26 (READ DMA QUEUED EXT) not supported"));command_aborted(channel, 0x26); break;
-       case 0x27: BX_ERROR(("write cmd 0x27 (READ NATIVE MAX ADDRESS EXT) not supported"));command_aborted(channel, 0x27); break;
-       case 0x29: BX_ERROR(("write cmd 0x29 (READ MULTIPLE EXT) not supported"));command_aborted(channel, 0x29); break;
-       case 0x2A: BX_ERROR(("write cmd 0x2A (READ STREAM DMA) not supported"));command_aborted(channel, 0x2A); break;
-       case 0x2B: BX_ERROR(("write cmd 0x2B (READ STREAM PIO) not supported"));command_aborted(channel, 0x2B); break;
-       case 0x2F: BX_ERROR(("write cmd 0x2F (READ LOG EXT) not supported"));command_aborted(channel, 0x2F); break;
-       case 0x31: BX_ERROR(("write cmd 0x31 (WRITE SECTORS NO RETRY) not supported")); command_aborted(channel, 0x31); break;
-       case 0x32: BX_ERROR(("write cmd 0x32 (WRITE LONG) not supported")); command_aborted(channel, 0x32); break;
-       case 0x33: BX_ERROR(("write cmd 0x33 (WRITE LONG NO RETRY) not supported")); command_aborted(channel, 0x33); break;
-       case 0x34: BX_ERROR(("write cmd 0x34 (WRITE SECTORS EXT) not supported"));command_aborted(channel, 0x34); break;
-       case 0x35: BX_ERROR(("write cmd 0x35 (WRITE DMA EXT) not supported"));command_aborted(channel, 0x35); break;
-       case 0x36: BX_ERROR(("write cmd 0x36 (WRITE DMA QUEUED EXT) not supported"));command_aborted(channel, 0x36); break;
-       case 0x37: BX_ERROR(("write cmd 0x37 (SET MAX ADDRESS EXT) not supported"));command_aborted(channel, 0x37); break;
-       case 0x38: BX_ERROR(("write cmd 0x38 (CFA WRITE SECTORS W/OUT ERASE) not supported"));command_aborted(channel, 0x38); break;
-       case 0x39: BX_ERROR(("write cmd 0x39 (WRITE MULTIPLE EXT) not supported"));command_aborted(channel, 0x39); break;
-       case 0x3A: BX_ERROR(("write cmd 0x3A (WRITE STREAM DMA) not supported"));command_aborted(channel, 0x3A); break;
-       case 0x3B: BX_ERROR(("write cmd 0x3B (WRITE STREAM PIO) not supported"));command_aborted(channel, 0x3B); break;
-       case 0x3F: BX_ERROR(("write cmd 0x3F (WRITE LOG EXT) not supported"));command_aborted(channel, 0x3F); break;
-       case 0x41: BX_ERROR(("write cmd 0x41 (READ VERIFY SECTORS NO RETRY) not supported")); command_aborted(channel, 0x41); break;
-       case 0x42: BX_ERROR(("write cmd 0x42 (READ VERIFY SECTORS EXT) not supported"));command_aborted(channel, 0x42); break;
-       case 0x50: BX_ERROR(("write cmd 0x50 (FORMAT TRACK) not supported")); command_aborted(channel, 0x50); break;
-       case 0x51: BX_ERROR(("write cmd 0x51 (CONFIGURE STREAM) not supported"));command_aborted(channel, 0x51); break;
-       case 0x87: BX_ERROR(("write cmd 0x87 (CFA TRANSLATE SECTOR) not supported"));command_aborted(channel, 0x87); break;
-       case 0x92: BX_ERROR(("write cmd 0x92 (DOWNLOAD MICROCODE) not supported"));command_aborted(channel, 0x92); break;
-       case 0x94: BX_ERROR(("write cmd 0x94 (STANDBY IMMEDIATE) not supported")); command_aborted(channel, 0x94); break;
-       case 0x95: BX_ERROR(("write cmd 0x95 (IDLE IMMEDIATE) not supported")); command_aborted(channel, 0x95); break;
-       case 0x96: BX_ERROR(("write cmd 0x96 (STANDBY) not supported")); command_aborted(channel, 0x96); break;
-       case 0x97: BX_ERROR(("write cmd 0x97 (IDLE) not supported")); command_aborted(channel, 0x97); break;
-       case 0x98: BX_ERROR(("write cmd 0x98 (CHECK POWER MODE) not supported")); command_aborted(channel, 0x98); break;
-       case 0x99: BX_ERROR(("write cmd 0x99 (SLEEP) not supported")); command_aborted(channel, 0x99); break;
-       case 0xB0: BX_ERROR(("write cmd 0xB0 (SMART commands) not supported"));command_aborted(channel, 0xB0); break;
-       case 0xB1: BX_ERROR(("write cmd 0xB1 (DEVICE CONFIGURATION commands) not supported"));command_aborted(channel, 0xB1); break;
-       case 0xC0: BX_ERROR(("write cmd 0xC0 (CFA ERASE SECTORS) not supported"));command_aborted(channel, 0xC0); break;
-       case 0xC4: BX_ERROR(("write cmd 0xC4 (READ MULTIPLE) not supported"));command_aborted(channel, 0xC4); break;
-       case 0xC5: BX_ERROR(("write cmd 0xC5 (WRITE MULTIPLE) not supported"));command_aborted(channel, 0xC5); break;
-       case 0xC7: BX_ERROR(("write cmd 0xC7 (READ DMA QUEUED) not supported"));command_aborted(channel, 0xC7); break;
-       case 0xC8: BX_ERROR(("write cmd 0xC8 (READ DMA) not supported"));command_aborted(channel, 0xC8); break;
-       case 0xC9: BX_ERROR(("write cmd 0xC9 (READ DMA NO RETRY) not supported")); command_aborted(channel, 0xC9); break;
-       case 0xCA: BX_ERROR(("write cmd 0xCA (WRITE DMA) not supported"));command_aborted(channel, 0xCA); break;
-       case 0xCC: BX_ERROR(("write cmd 0xCC (WRITE DMA QUEUED) not supported"));command_aborted(channel, 0xCC); break;
-       case 0xCD: BX_ERROR(("write cmd 0xCD (CFA WRITE MULTIPLE W/OUT ERASE) not supported"));command_aborted(channel, 0xCD); break;
-       case 0xD1: BX_ERROR(("write cmd 0xD1 (CHECK MEDIA CARD TYPE) not supported"));command_aborted(channel, 0xD1); break;
-       case 0xDA: BX_ERROR(("write cmd 0xDA (GET MEDIA STATUS) not supported"));command_aborted(channel, 0xDA); break;
-       case 0xDE: BX_ERROR(("write cmd 0xDE (MEDIA LOCK) not supported"));command_aborted(channel, 0xDE); break;
-       case 0xDF: BX_ERROR(("write cmd 0xDF (MEDIA UNLOCK) not supported"));command_aborted(channel, 0xDF); break;
-       case 0xE0: BX_ERROR(("write cmd 0xE0 (STANDBY IMMEDIATE) not supported"));command_aborted(channel, 0xE0); break;
-       case 0xE1: BX_ERROR(("write cmd 0xE1 (IDLE IMMEDIATE) not supported"));command_aborted(channel, 0xE1); break;
-       case 0xE2: BX_ERROR(("write cmd 0xE2 (STANDBY) not supported"));command_aborted(channel, 0xE2); break;
-       case 0xE3: BX_ERROR(("write cmd 0xE3 (IDLE) not supported"));command_aborted(channel, 0xE3); break;
-       case 0xE4: BX_ERROR(("write cmd 0xE4 (READ BUFFER) not supported"));command_aborted(channel, 0xE4); break;
-       case 0xE6: BX_ERROR(("write cmd 0xE6 (SLEEP) not supported"));command_aborted(channel, 0xE6); break;
-        case 0xE7: BX_ERROR(("write cmd 0xE7 (FLUSH CACHE) not supported"));command_aborted(channel, 0xE7); break;
-       case 0xE8: BX_ERROR(("write cmd 0xE8 (WRITE BUFFER) not supported"));command_aborted(channel, 0xE8); break;
-       case 0xEA: BX_ERROR(("write cmd 0xEA (FLUSH CACHE EXT) not supported"));command_aborted(channel, 0xEA); break;
-       case 0xED: BX_ERROR(("write cmd 0xED (MEDIA EJECT) not supported"));command_aborted(channel, 0xED); break;
-       case 0xF1: BX_ERROR(("write cmd 0xF1 (SECURITY SET PASSWORD) not supported"));command_aborted(channel, 0xF1); break;
-       case 0xF2: BX_ERROR(("write cmd 0xF2 (SECURITY UNLOCK) not supported"));command_aborted(channel, 0xF2); break;
-       case 0xF3: BX_ERROR(("write cmd 0xF3 (SECURITY ERASE PREPARE) not supported"));command_aborted(channel, 0xF3); break;
-       case 0xF4: BX_ERROR(("write cmd 0xF4 (SECURITY ERASE UNIT) not supported"));command_aborted(channel, 0xF4); break;
-       case 0xF5: BX_ERROR(("write cmd 0xF5 (SECURITY FREEZE LOCK) not supported"));command_aborted(channel, 0xF5); break;
-       case 0xF6: BX_ERROR(("write cmd 0xF6 (SECURITY DISABLE PASSWORD) not supported"));command_aborted(channel, 0xF6); break;
-       case 0xF8: BX_ERROR(("write cmd 0xF8 (READ NATIVE MAX ADDRESS) not supported"));command_aborted(channel, 0xF8); break;
-       case 0xF9: BX_ERROR(("write cmd 0xF9 (SET MAX ADDRESS) not supported"));command_aborted(channel, 0xF9); break;
-
-       default:
-          BX_PANIC(("IO write(0x%04x): command 0x%02x", address, (unsigned) value));
-         // if user foolishly decides to continue, abort the command
-         // so that the software knows the drive didn't understand it.
-          command_aborted(channel, value);
-        }
-      break;
-
-    case 0x16: // hard disk adapter control 0x3f6
-         // (mch) Even if device 1 was selected, a write to this register
-         // goes to device 0 (if device 1 is absent)
-               
-         prev_control_reset = BX_SELECTED_CONTROLLER(channel).control.reset;
-         BX_HD_THIS channels[channel].drives[0].controller.control.reset         = value & 0x04;
-         BX_HD_THIS channels[channel].drives[1].controller.control.reset         = value & 0x04;
-         // CGS: was: BX_SELECTED_CONTROLLER(channel).control.disable_irq    = value & 0x02;
-         BX_HD_THIS channels[channel].drives[0].controller.control.disable_irq = value & 0x02;
-         BX_HD_THIS channels[channel].drives[1].controller.control.disable_irq = value & 0x02;
-
-      BX_DEBUG(( "adpater control reg: reset controller = %d",
-        (unsigned) (BX_SELECTED_CONTROLLER(channel).control.reset) ? 1 : 0 ));
-      BX_DEBUG(( "adpater control reg: disable_irq(X) = %d",
-        (unsigned) (BX_SELECTED_CONTROLLER(channel).control.disable_irq) ? 1 : 0 ));
-
-         if (!prev_control_reset && BX_SELECTED_CONTROLLER(channel).control.reset) {
-               // transition from 0 to 1 causes all drives to reset
-               BX_DEBUG(("hard drive: RESET"));
-
-               // (mch) Set BSY, drive not ready
-               for (int id = 0; id < 2; id++) {
-                     BX_CONTROLLER(channel,id).status.busy           = 1;
-                     BX_CONTROLLER(channel,id).status.drive_ready    = 0;
-                     BX_CONTROLLER(channel,id).reset_in_progress     = 1;
-
-                     BX_CONTROLLER(channel,id).status.write_fault    = 0;
-                     BX_CONTROLLER(channel,id).status.seek_complete  = 1;
-                     BX_CONTROLLER(channel,id).status.drq            = 0;
-                     BX_CONTROLLER(channel,id).status.corrected_data = 0;
-                     BX_CONTROLLER(channel,id).status.err            = 0;
-
-                     BX_CONTROLLER(channel,id).error_register = 0x01; // diagnostic code: no error
-
-                     BX_CONTROLLER(channel,id).current_command = 0x00;
-                     BX_CONTROLLER(channel,id).buffer_index = 0;
-
-                     BX_CONTROLLER(channel,id).sectors_per_block = 0x80;
-                     BX_CONTROLLER(channel,id).lba_mode          = 0;
-
-                     BX_CONTROLLER(channel,id).control.disable_irq = 0;
-                     DEV_pic_lower_irq(BX_HD_THIS channels[channel].irq);
-               }
-         } else if (BX_SELECTED_CONTROLLER(channel).reset_in_progress &&
-                    !BX_SELECTED_CONTROLLER(channel).control.reset) {
-               // Clear BSY and DRDY
-               BX_DEBUG(("Reset complete {%s}", BX_SELECTED_TYPE_STRING(channel)));
-               for (int id = 0; id < 2; id++) {
-                     BX_CONTROLLER(channel,id).status.busy           = 0;
-                     BX_CONTROLLER(channel,id).status.drive_ready    = 1;
-                     BX_CONTROLLER(channel,id).reset_in_progress     = 0;
-
-                     // Device signature
-                     if (BX_DRIVE_IS_HD(channel,id)) {
-                           BX_CONTROLLER(channel,id).head_no        = 0;
-                           BX_CONTROLLER(channel,id).sector_count   = 1;
-                           BX_CONTROLLER(channel,id).sector_no      = 1;
-                           BX_CONTROLLER(channel,id).cylinder_no    = 0;
-                     } else {
-                           BX_CONTROLLER(channel,id).head_no        = 0;
-                           BX_CONTROLLER(channel,id).sector_count   = 1;
-                           BX_CONTROLLER(channel,id).sector_no      = 1;
-                           BX_CONTROLLER(channel,id).cylinder_no    = 0xeb14;
-                     }
-               }
-         }
-           BX_DEBUG(("s[0].controller.control.disable_irq = %02x", (BX_HD_THIS channels[channel].drives[0]).controller.control.disable_irq));
-           BX_DEBUG(("s[1].controller.control.disable_irq = %02x", (BX_HD_THIS channels[channel].drives[1]).controller.control.disable_irq));
-         break;
-
-    default:
-      BX_PANIC(("hard drive: io write to address %x = %02x",
-        (unsigned) address, (unsigned) value));
-    }
-}
-
-  void
-bx_hard_drive_c::close_harddrive(void)
-{
-  for (Bit8u channel=0; channel<BX_MAX_ATA_CHANNEL; channel++) {
-    if(BX_HD_THIS channels[channel].drives[0].hard_drive != NULL)
-      BX_HD_THIS channels[channel].drives[0].hard_drive->close();
-    if(BX_HD_THIS channels[channel].drives[1].hard_drive != NULL)
-      BX_HD_THIS channels[channel].drives[1].hard_drive->close();
-  }
-}
-
-
-  bx_bool BX_CPP_AttrRegparmN(2)
-bx_hard_drive_c::calculate_logical_address(Bit8u channel, off_t *sector)
-{
-      off_t logical_sector;
-
-      if (BX_SELECTED_CONTROLLER(channel).lba_mode) {
-            //bx_printf ("disk: calculate: %d %d %d\n", ((Bit32u)BX_SELECTED_CONTROLLER(channel).head_no), ((Bit32u)BX_SELECTED_CONTROLLER(channel).cylinder_no), (Bit32u)BX_SELECTED_CONTROLLER(channel).sector_no);
-           logical_sector = ((Bit32u)BX_SELECTED_CONTROLLER(channel).head_no) << 24 |
-                 ((Bit32u)BX_SELECTED_CONTROLLER(channel).cylinder_no) << 8 |
-                 (Bit32u)BX_SELECTED_CONTROLLER(channel).sector_no;
-            //bx_printf ("disk: result: %u\n", logical_sector);
-      } else
-           logical_sector = (BX_SELECTED_CONTROLLER(channel).cylinder_no * BX_SELECTED_DRIVE(channel).hard_drive->heads *
-                             BX_SELECTED_DRIVE(channel).hard_drive->sectors) +
-                 (BX_SELECTED_CONTROLLER(channel).head_no * BX_SELECTED_DRIVE(channel).hard_drive->sectors) +
-                 (BX_SELECTED_CONTROLLER(channel).sector_no - 1);
-
-      Bit32u sector_count= 
-          (Bit32u)BX_SELECTED_DRIVE(channel).hard_drive->cylinders * 
-           (Bit32u)BX_SELECTED_DRIVE(channel).hard_drive->heads * 
-           (Bit32u)BX_SELECTED_DRIVE(channel).hard_drive->sectors;
-
-      if (logical_sector >= sector_count) {
-            BX_ERROR (("calc_log_addr: out of bounds (%d/%d)", (Bit32u)logical_sector, sector_count));
-           return false;
-      }
-      *sector = logical_sector;
-      return true;
-}
-
-  void BX_CPP_AttrRegparmN(1)
-bx_hard_drive_c::increment_address(Bit8u channel)
-{
-      BX_SELECTED_CONTROLLER(channel).sector_count--;
-
-      if (BX_SELECTED_CONTROLLER(channel).lba_mode) {
-           off_t current_address;
-           calculate_logical_address(channel, &current_address);
-           current_address++;
-           BX_SELECTED_CONTROLLER(channel).head_no = (Bit8u)((current_address >> 24) & 0xf);
-           BX_SELECTED_CONTROLLER(channel).cylinder_no = (Bit16u)((current_address >> 8) & 0xffff);
-           BX_SELECTED_CONTROLLER(channel).sector_no = (Bit8u)((current_address) & 0xff);
-      } else {
-            BX_SELECTED_CONTROLLER(channel).sector_no++;
-            if (BX_SELECTED_CONTROLLER(channel).sector_no > BX_SELECTED_DRIVE(channel).hard_drive->sectors) {
-                 BX_SELECTED_CONTROLLER(channel).sector_no = 1;
-                 BX_SELECTED_CONTROLLER(channel).head_no++;
-                 if (BX_SELECTED_CONTROLLER(channel).head_no >= BX_SELECTED_DRIVE(channel).hard_drive->heads) {
-                       BX_SELECTED_CONTROLLER(channel).head_no = 0;
-                       BX_SELECTED_CONTROLLER(channel).cylinder_no++;
-                       if (BX_SELECTED_CONTROLLER(channel).cylinder_no >= BX_SELECTED_DRIVE(channel).hard_drive->cylinders)
-                             BX_SELECTED_CONTROLLER(channel).cylinder_no = BX_SELECTED_DRIVE(channel).hard_drive->cylinders - 1;
-                 }
-           }
-      }
-}
-
-  void
-bx_hard_drive_c::identify_ATAPI_drive(Bit8u channel)
-{
-  unsigned i;
-
-  BX_SELECTED_DRIVE(channel).id_drive[0] = (2 << 14) | (5 << 8) | (1 << 7) | (2 << 5) | (0 << 0); // Removable CDROM, 50us response, 12 byte packets
-
-  for (i = 1; i <= 9; i++)
-       BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
-
-  const char* serial_number = " VT00001\0\0\0\0\0\0\0\0\0\0\0\0";
-  for (i = 0; i < 10; i++) {
-       BX_SELECTED_DRIVE(channel).id_drive[10+i] = (serial_number[i*2] << 8) |
-             serial_number[i*2 + 1];
-  }
-
-  for (i = 20; i <= 22; i++)
-       BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
-
-  const char* firmware = "ALPHA1  ";
-  for (i = 0; i < strlen(firmware)/2; i++) {
-       BX_SELECTED_DRIVE(channel).id_drive[23+i] = (firmware[i*2] << 8) |
-             firmware[i*2 + 1];
-  }
-  BX_ASSERT((23+i) == 27);
-  
-  for (i = 0; i < strlen((char *) BX_SELECTED_MODEL(channel))/2; i++) {
-       BX_SELECTED_DRIVE(channel).id_drive[27+i] = (BX_SELECTED_MODEL(channel)[i*2] << 8) |
-             BX_SELECTED_MODEL(channel)[i*2 + 1];
-  }
-  BX_ASSERT((27+i) == 47);
-
-  BX_SELECTED_DRIVE(channel).id_drive[47] = 0;
-  BX_SELECTED_DRIVE(channel).id_drive[48] = 1; // 32 bits access
-
-  BX_SELECTED_DRIVE(channel).id_drive[49] = (1 << 9); // LBA supported
-
-  BX_SELECTED_DRIVE(channel).id_drive[50] = 0;
-  BX_SELECTED_DRIVE(channel).id_drive[51] = 0;
-  BX_SELECTED_DRIVE(channel).id_drive[52] = 0;
-
-  BX_SELECTED_DRIVE(channel).id_drive[53] = 3; // words 64-70, 54-58 valid
-
-  for (i = 54; i <= 62; i++)
-       BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
-
-  // copied from CFA540A
-  BX_SELECTED_DRIVE(channel).id_drive[63] = 0x0103; // variable (DMA stuff)
-  BX_SELECTED_DRIVE(channel).id_drive[64] = 0x0001; // PIO
-  BX_SELECTED_DRIVE(channel).id_drive[65] = 0x00b4;
-  BX_SELECTED_DRIVE(channel).id_drive[66] = 0x00b4;
-  BX_SELECTED_DRIVE(channel).id_drive[67] = 0x012c;
-  BX_SELECTED_DRIVE(channel).id_drive[68] = 0x00b4;
-
-  BX_SELECTED_DRIVE(channel).id_drive[69] = 0;
-  BX_SELECTED_DRIVE(channel).id_drive[70] = 0;
-  BX_SELECTED_DRIVE(channel).id_drive[71] = 30; // faked
-  BX_SELECTED_DRIVE(channel).id_drive[72] = 30; // faked
-  BX_SELECTED_DRIVE(channel).id_drive[73] = 0;
-  BX_SELECTED_DRIVE(channel).id_drive[74] = 0;
-
-  BX_SELECTED_DRIVE(channel).id_drive[75] = 0;
-
-  for (i = 76; i <= 79; i++)
-       BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
-
-  BX_SELECTED_DRIVE(channel).id_drive[80] = 0x1e; // supports up to ATA/ATAPI-4
-  BX_SELECTED_DRIVE(channel).id_drive[81] = 0;
-  BX_SELECTED_DRIVE(channel).id_drive[82] = 0;
-  BX_SELECTED_DRIVE(channel).id_drive[83] = 0;
-  BX_SELECTED_DRIVE(channel).id_drive[84] = 0;
-  BX_SELECTED_DRIVE(channel).id_drive[85] = 0;
-  BX_SELECTED_DRIVE(channel).id_drive[86] = 0;
-  BX_SELECTED_DRIVE(channel).id_drive[87] = 0;
-  BX_SELECTED_DRIVE(channel).id_drive[88] = 0;
-
-  for (i = 89; i <= 126; i++)
-       BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
-
-  BX_SELECTED_DRIVE(channel).id_drive[127] = 0;
-  BX_SELECTED_DRIVE(channel).id_drive[128] = 0;
-
-  for (i = 129; i <= 159; i++)
-       BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
-
-  for (i = 160; i <= 255; i++)
-       BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
-
-  // now convert the id_drive array (native 256 word format) to
-  // the controller buffer (512 bytes)
-  Bit16u temp16;
-  for (i = 0; i <= 255; i++) {
-       temp16 = BX_SELECTED_DRIVE(channel).id_drive[i];
-       BX_SELECTED_CONTROLLER(channel).buffer[i*2] = temp16 & 0x00ff;
-       BX_SELECTED_CONTROLLER(channel).buffer[i*2+1] = temp16 >> 8;
-  }
-}
-
-  void
-bx_hard_drive_c::identify_drive(Bit8u channel)
-{
-  unsigned i;
-  Bit32u temp32;
-  Bit16u temp16;
-
-#if defined(CONNER_CFA540A)
-  BX_SELECTED_DRIVE(channel).id_drive[0] = 0x0c5a;
-  BX_SELECTED_DRIVE(channel).id_drive[1] = 0x0418;
-  BX_SELECTED_DRIVE(channel).id_drive[2] = 0;
-  BX_SELECTED_DRIVE(channel).id_drive[3] = BX_SELECTED_DRIVE(channel).hard_drive->heads;
-  BX_SELECTED_DRIVE(channel).id_drive[4] = 0x9fb7;
-  BX_SELECTED_DRIVE(channel).id_drive[5] = 0x0289;
-  BX_SELECTED_DRIVE(channel).id_drive[6] = BX_SELECTED_DRIVE(channel).hard_drive->sectors;
-  BX_SELECTED_DRIVE(channel).id_drive[7] = 0x0030;
-  BX_SELECTED_DRIVE(channel).id_drive[8] = 0x000a;
-  BX_SELECTED_DRIVE(channel).id_drive[9] = 0x0000;
-
-  char* serial_number = " CA00GSQ\0\0\0\0\0\0\0\0\0\0\0\0";
-  for (i = 0; i < 10; i++) {
-       BX_SELECTED_DRIVE(channel).id_drive[10+i] = (serial_number[i*2] << 8) |
-             serial_number[i*2 + 1];
-  }
-
-  BX_SELECTED_DRIVE(channel).id_drive[20] = 3;
-  BX_SELECTED_DRIVE(channel).id_drive[21] = 512; // 512 Sectors = 256kB cache
-  BX_SELECTED_DRIVE(channel).id_drive[22] = 4;
-
-  char* firmware = "8FT054  ";
-  for (i = 0; i < strlen(firmware)/2; i++) {
-       BX_SELECTED_DRIVE(channel).id_drive[23+i] = (firmware[i*2] << 8) |
-             firmware[i*2 + 1];
-  }
-  BX_ASSERT((23+i) == 27);
-
-  char* model = "Conner Peripherals 540MB - CFA540A      ";
-  for (i = 0; i < strlen(model)/2; i++) {
-       BX_SELECTED_DRIVE(channel).id_drive[27+i] = (model[i*2] << 8) |
-             model[i*2 + 1];
-  }
-  BX_ASSERT((27+i) == 47);
-
-  BX_SELECTED_DRIVE(channel).id_drive[47] = 0x8080; // multiple mode identification
-  BX_SELECTED_DRIVE(channel).id_drive[48] = 0;
-  BX_SELECTED_DRIVE(channel).id_drive[49] = 0x0f01;
-
-  BX_SELECTED_DRIVE(channel).id_drive[50] = 0;
-
-  BX_SELECTED_DRIVE(channel).id_drive[51] = 0;
-  BX_SELECTED_DRIVE(channel).id_drive[52] = 0x0002;
-  BX_SELECTED_DRIVE(channel).id_drive[53] = 0x0003;
-  BX_SELECTED_DRIVE(channel).id_drive[54] = 0x0418;
-
-  BX_SELECTED_DRIVE(channel).id_drive[55] = BX_SELECTED_DRIVE(channel).hard_drive->heads;
-  BX_SELECTED_DRIVE(channel).id_drive[56] = BX_SELECTED_DRIVE(channel).hard_drive->sectors;
-
-  BX_SELECTED_DRIVE(channel).id_drive[57] = 0x1e80;
-  BX_SELECTED_DRIVE(channel).id_drive[58] = 0x0010;
-  BX_SELECTED_DRIVE(channel).id_drive[59] = 0x0100 | BX_SELECTED_CONTROLLER(channel).sectors_per_block;
-  BX_SELECTED_DRIVE(channel).id_drive[60] = 0x20e0;
-  BX_SELECTED_DRIVE(channel).id_drive[61] = 0x0010;
-
-  BX_SELECTED_DRIVE(channel).id_drive[62] = 0;
-
-  BX_SELECTED_DRIVE(channel).id_drive[63] = 0x0103; // variable (DMA stuff)
-  BX_SELECTED_DRIVE(channel).id_drive[64] = 0x0001; // PIO
-  BX_SELECTED_DRIVE(channel).id_drive[65] = 0x00b4;
-  BX_SELECTED_DRIVE(channel).id_drive[66] = 0x00b4;
-  BX_SELECTED_DRIVE(channel).id_drive[67] = 0x012c;
-  BX_SELECTED_DRIVE(channel).id_drive[68] = 0x00b4;
-
-  for (i = 69; i <= 79; i++)
-       BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
-
-  BX_SELECTED_DRIVE(channel).id_drive[80] = 0;
-
-  BX_SELECTED_DRIVE(channel).id_drive[81] = 0;
-
-  BX_SELECTED_DRIVE(channel).id_drive[82] = 0;
-  BX_SELECTED_DRIVE(channel).id_drive[83] = 0;
-  BX_SELECTED_DRIVE(channel).id_drive[84] = 0;
-  BX_SELECTED_DRIVE(channel).id_drive[85] = 0;
-  BX_SELECTED_DRIVE(channel).id_drive[86] = 0;
-  BX_SELECTED_DRIVE(channel).id_drive[87] = 0;
-
-  for (i = 88; i <= 127; i++)
-       BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
-
-  BX_SELECTED_DRIVE(channel).id_drive[128] = 0x0418;
-  BX_SELECTED_DRIVE(channel).id_drive[129] = 0x103f;
-  BX_SELECTED_DRIVE(channel).id_drive[130] = 0x0418;
-  BX_SELECTED_DRIVE(channel).id_drive[131] = 0x103f;
-  BX_SELECTED_DRIVE(channel).id_drive[132] = 0x0004;
-  BX_SELECTED_DRIVE(channel).id_drive[133] = 0xffff;
-  BX_SELECTED_DRIVE(channel).id_drive[134] = 0;
-  BX_SELECTED_DRIVE(channel).id_drive[135] = 0x5050;
-
-  for (i = 136; i <= 144; i++)
-       BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
-
-  BX_SELECTED_DRIVE(channel).id_drive[145] = 0x302e;
-  BX_SELECTED_DRIVE(channel).id_drive[146] = 0x3245;
-  BX_SELECTED_DRIVE(channel).id_drive[147] = 0x2020;
-  BX_SELECTED_DRIVE(channel).id_drive[148] = 0x2020;
-
-  for (i = 149; i <= 255; i++)
-       BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
-
-#else
-
-  // Identify Drive command return values definition
-  //
-  // This code is rehashed from some that was donated.
-  // I'm using ANSI X3.221-1994, AT Attachment Interface for Disk Drives
-  // and X3T10 2008D Working Draft for ATA-3
-
-
-  // Word 0: general config bit-significant info
-  //   Note: bits 1-5 and 8-14 are now "Vendor specific (obsolete)"
-  //   bit 15: 0=ATA device
-  //           1=ATAPI device
-  //   bit 14: 1=format speed tolerance gap required
-  //   bit 13: 1=track offset option available
-  //   bit 12: 1=data strobe offset option available
-  //   bit 11: 1=rotational speed tolerance is > 0,5% (typo?)
-  //   bit 10: 1=disk transfer rate > 10Mbs
-  //   bit  9: 1=disk transfer rate > 5Mbs but <= 10Mbs
-  //   bit  8: 1=disk transfer rate <= 5Mbs
-  //   bit  7: 1=removable cartridge drive
-  //   bit  6: 1=fixed drive
-  //   bit  5: 1=spindle motor control option implemented
-  //   bit  4: 1=head switch time > 15 usec
-  //   bit  3: 1=not MFM encoded
-  //   bit  2: 1=soft sectored
-  //   bit  1: 1=hard sectored
-  //   bit  0: 0=reserved
-  BX_SELECTED_DRIVE(channel).id_drive[0] = 0x0040;
-
-  // Word 1: number of user-addressable cylinders in
-  //   default translation mode.  If the value in words 60-61
-  //   exceed 16,515,072, this word shall contain 16,383.
-  BX_SELECTED_DRIVE(channel).id_drive[1] = BX_SELECTED_DRIVE(channel).hard_drive->cylinders;
-
-  // Word 2: reserved
-  BX_SELECTED_DRIVE(channel).id_drive[2] = 0;
-
-  // Word 3: number of user-addressable heads in default
-  //   translation mode
-  BX_SELECTED_DRIVE(channel).id_drive[3] = BX_SELECTED_DRIVE(channel).hard_drive->heads;
-
-  // Word 4: # unformatted bytes per translated track in default xlate mode
-  // Word 5: # unformatted bytes per sector in default xlated mode
-  // Word 6: # user-addressable sectors per track in default xlate mode
-  // Note: words 4,5 are now "Vendor specific (obsolete)"
-  BX_SELECTED_DRIVE(channel).id_drive[4] = (512 * BX_SELECTED_DRIVE(channel).hard_drive->sectors);
-  BX_SELECTED_DRIVE(channel).id_drive[5] = 512;
-  BX_SELECTED_DRIVE(channel).id_drive[6] = BX_SELECTED_DRIVE(channel).hard_drive->sectors;
-
-  // Word 7-9: Vendor specific
-  for (i=7; i<=9; i++)
-    BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
-
-  // Word 10-19: Serial number (20 ASCII characters, 0000h=not specified)
-  // This field is right justified and padded with spaces (20h).
-  for (i=10; i<=19; i++)
-    BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
-
-  // Word 20: buffer type
-  //          0000h = not specified
-  //          0001h = single ported single sector buffer which is
-  //                  not capable of simulataneous data xfers to/from
-  //                  the host and the disk.
-  //          0002h = dual ported multi-sector buffer capable of
-  //                  simulatenous data xfers to/from the host and disk.
-  //          0003h = dual ported mutli-sector buffer capable of
-  //                  simulatenous data xfers with a read caching
-  //                  capability.
-  //          0004h-ffffh = reserved
-  BX_SELECTED_DRIVE(channel).id_drive[20] = 3;
-
-  // Word 21: buffer size in 512 byte increments, 0000h = not specified
-  BX_SELECTED_DRIVE(channel).id_drive[21] = 512; // 512 Sectors = 256kB cache
-
-  // Word 22: # of ECC bytes available on read/write long cmds
-  //          0000h = not specified
-  BX_SELECTED_DRIVE(channel).id_drive[22] = 4;
-
-  // Word 23..26: Firmware revision (8 ascii chars, 0000h=not specified)
-  // This field is left justified and padded with spaces (20h)
-  for (i=23; i<=26; i++)
-    BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
-
-  // Word 27..46: Model number (40 ascii chars, 0000h=not specified)
-  // This field is left justified and padded with spaces (20h)
-//  for (i=27; i<=46; i++)
-//    BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
-  for (i=0; i<20; i++) {
-    BX_SELECTED_DRIVE(channel).id_drive[27+i] = (BX_SELECTED_MODEL(channel)[i*2] << 8) |
-                                  BX_SELECTED_MODEL(channel)[i*2 + 1];
-    }
-
-  // Word 47: 15-8 Vendor unique
-  //           7-0 00h= read/write multiple commands not implemented
-  //               xxh= maximum # of sectors that can be transferred
-  //                    per interrupt on read and write multiple commands
-  BX_SELECTED_DRIVE(channel).id_drive[47] = max_multiple_sectors;
-
-  // Word 48: 0000h = cannot perform dword IO
-  //          0001h = can    perform dword IO
-  BX_SELECTED_DRIVE(channel).id_drive[48] = 1;
-
-  // Word 49: Capabilities
-  //   15-10: 0 = reserved
-  //       9: 1 = LBA supported
-  //       8: 1 = DMA supported
-  //     7-0: Vendor unique
-  BX_SELECTED_DRIVE(channel).id_drive[49] = 1<<9;
-
-  // Word 50: Reserved
-  BX_SELECTED_DRIVE(channel).id_drive[50] = 0;
-
-  // Word 51: 15-8 PIO data transfer cycle timing mode
-  //           7-0 Vendor unique
-  BX_SELECTED_DRIVE(channel).id_drive[51] = 0x200;
-
-  // Word 52: 15-8 DMA data transfer cycle timing mode
-  //           7-0 Vendor unique
-  BX_SELECTED_DRIVE(channel).id_drive[52] = 0x200;
-
-  // Word 53: 15-1 Reserved
-  //             0 1=the fields reported in words 54-58 are valid
-  //               0=the fields reported in words 54-58 may be valid
-  BX_SELECTED_DRIVE(channel).id_drive[53] = 0;
-
-  // Word 54: # of user-addressable cylinders in curr xlate mode
-  // Word 55: # of user-addressable heads in curr xlate mode
-  // Word 56: # of user-addressable sectors/track in curr xlate mode
-  BX_SELECTED_DRIVE(channel).id_drive[54] = BX_SELECTED_DRIVE(channel).hard_drive->cylinders;
-  BX_SELECTED_DRIVE(channel).id_drive[55] = BX_SELECTED_DRIVE(channel).hard_drive->heads;
-  BX_SELECTED_DRIVE(channel).id_drive[56] = BX_SELECTED_DRIVE(channel).hard_drive->sectors;
-
-  // Word 57-58: Current capacity in sectors
-  // Excludes all sectors used for device specific purposes.
-  temp32 = 
-    BX_SELECTED_DRIVE(channel).hard_drive->cylinders *
-    BX_SELECTED_DRIVE(channel).hard_drive->heads *
-    BX_SELECTED_DRIVE(channel).hard_drive->sectors;
-  BX_SELECTED_DRIVE(channel).id_drive[57] = (temp32 & 0xffff); // LSW
-  BX_SELECTED_DRIVE(channel).id_drive[58] = (temp32 >> 16);    // MSW
-
-  // Word 59: 15-9 Reserved
-  //             8 1=multiple sector setting is valid
-  //           7-0 current setting for number of sectors that can be
-  //               transferred per interrupt on R/W multiple commands
-  BX_SELECTED_DRIVE(channel).id_drive[59] = 0x0000 | curr_multiple_sectors;
-
-  // Word 60-61:
-  // If drive supports LBA Mode, these words reflect total # of user
-  // addressable sectors.  This value does not depend on the current
-  // drive geometry.  If the drive does not support LBA mode, these
-  // words shall be set to 0.
-  Bit32u num_sects = BX_SELECTED_DRIVE(channel).hard_drive->cylinders * BX_SELECTED_DRIVE(channel).hard_drive->heads * BX_SELECTED_DRIVE(channel).hard_drive->sectors;
-  BX_SELECTED_DRIVE(channel).id_drive[60] = num_sects & 0xffff; // LSW
-  BX_SELECTED_DRIVE(channel).id_drive[61] = num_sects >> 16; // MSW
-
-  // Word 62: 15-8 single word DMA transfer mode active
-  //           7-0 single word DMA transfer modes supported
-  // The low order byte identifies by bit, all the Modes which are
-  // supported e.g., if Mode 0 is supported bit 0 is set.
-  // The high order byte contains a single bit set to indiciate
-  // which mode is active.
-  BX_SELECTED_DRIVE(channel).id_drive[62] = 0x0;
-
-  // Word 63: 15-8 multiword DMA transfer mode active
-  //           7-0 multiword DMA transfer modes supported
-  // The low order byte identifies by bit, all the Modes which are
-  // supported e.g., if Mode 0 is supported bit 0 is set.
-  // The high order byte contains a single bit set to indiciate
-  // which mode is active.
-  BX_SELECTED_DRIVE(channel).id_drive[63] = 0x0;
-
-  // Word 64-79 Reserved
-  for (i=64; i<=79; i++)
-    BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
-
-  // Word 80: 15-5 reserved
-  //             4 supports ATA/ATAPI-4
-  //             3 supports ATA-3
-  //             2 supports ATA-2
-  //             1 supports ATA-1
-  //             0 reserved
-  BX_SELECTED_DRIVE(channel).id_drive[80] = (1 << 2) | (1 << 1);
-
-  // Word 81: Minor version number
-  BX_SELECTED_DRIVE(channel).id_drive[81] = 0;
-
-  // Word 82: 15 obsolete
-  //          14 NOP command supported
-  //          13 READ BUFFER command supported
-  //          12 WRITE BUFFER command supported
-  //          11 obsolete
-  //          10 Host protected area feature set supported
-  //           9 DEVICE RESET command supported
-  //           8 SERVICE interrupt supported
-  //           7 release interrupt supported
-  //           6 look-ahead supported
-  //           5 write cache supported
-  //           4 supports PACKET command feature set
-  //           3 supports power management feature set
-  //           2 supports removable media feature set
-  //           1 supports securite mode feature set
-  //           0 support SMART feature set
-  BX_SELECTED_DRIVE(channel).id_drive[82] = 1 << 14;
-  BX_SELECTED_DRIVE(channel).id_drive[83] = 1 << 14;
-  BX_SELECTED_DRIVE(channel).id_drive[84] = 1 << 14;
-  BX_SELECTED_DRIVE(channel).id_drive[85] = 1 << 14;
-  BX_SELECTED_DRIVE(channel).id_drive[86] = 0;
-  BX_SELECTED_DRIVE(channel).id_drive[87] = 1 << 14;
-
-  for (i=88; i<=127; i++)
-    BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
-
-  // Word 128-159 Vendor unique
-  for (i=128; i<=159; i++)
-    BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
-
-  // Word 160-255 Reserved
-  for (i=160; i<=255; i++)
-    BX_SELECTED_DRIVE(channel).id_drive[i] = 0;
-
-#endif
-
-  BX_DEBUG(("Drive ID Info. initialized : %04d {%s}", 512, BX_SELECTED_TYPE_STRING(channel)));
-
-  // now convert the id_drive array (native 256 word format) to
-  // the controller buffer (512 bytes)
-  for (i=0; i<=255; i++) {
-    temp16 = BX_SELECTED_DRIVE(channel).id_drive[i];
-    BX_SELECTED_CONTROLLER(channel).buffer[i*2] = temp16 & 0x00ff;
-    BX_SELECTED_CONTROLLER(channel).buffer[i*2+1] = temp16 >> 8;
-    }
-}
-
-  void BX_CPP_AttrRegparmN(3)
-bx_hard_drive_c::init_send_atapi_command(Bit8u channel, Bit8u command, int req_length, int alloc_length, bool lazy)
-{
-      // BX_SELECTED_CONTROLLER(channel).byte_count is a union of BX_SELECTED_CONTROLLER(channel).cylinder_no;
-      // lazy is used to force a data read in the buffer at the next read.
-
-      if (BX_SELECTED_CONTROLLER(channel).byte_count == 0xffff)
-        BX_SELECTED_CONTROLLER(channel).byte_count = 0xfffe;
-
-      if ((BX_SELECTED_CONTROLLER(channel).byte_count & 1)
-          && !(alloc_length <= BX_SELECTED_CONTROLLER(channel).byte_count)) {
-        BX_INFO(("Odd byte count (0x%04x) to ATAPI command 0x%02x, using 0x%04x", 
-               BX_SELECTED_CONTROLLER(channel).byte_count, command, BX_SELECTED_CONTROLLER(channel).byte_count - 1));
-        BX_SELECTED_CONTROLLER(channel).byte_count -= 1;
-      }
-
-      if (BX_SELECTED_CONTROLLER(channel).byte_count == 0)
-           BX_PANIC(("ATAPI command with zero byte count"));
-
-      if (alloc_length < 0)
-           BX_PANIC(("Allocation length < 0"));
-      if (alloc_length == 0)
-           alloc_length = BX_SELECTED_CONTROLLER(channel).byte_count;
-
-      BX_SELECTED_CONTROLLER(channel).interrupt_reason.i_o = 1;
-      BX_SELECTED_CONTROLLER(channel).interrupt_reason.c_d = 0;
-      BX_SELECTED_CONTROLLER(channel).status.busy = 0;
-      BX_SELECTED_CONTROLLER(channel).status.drq = 1;
-      BX_SELECTED_CONTROLLER(channel).status.err = 0;
-
-      // no bytes transfered yet
-      if (lazy)
-           BX_SELECTED_CONTROLLER(channel).buffer_index = 2048;
-      else
-           BX_SELECTED_CONTROLLER(channel).buffer_index = 0;
-      BX_SELECTED_CONTROLLER(channel).drq_index = 0;
-
-      if (BX_SELECTED_CONTROLLER(channel).byte_count > req_length)
-           BX_SELECTED_CONTROLLER(channel).byte_count = req_length;
-
-      if (BX_SELECTED_CONTROLLER(channel).byte_count > alloc_length)
-           BX_SELECTED_CONTROLLER(channel).byte_count = alloc_length;
-
-      BX_SELECTED_DRIVE(channel).atapi.command = command;
-      BX_SELECTED_DRIVE(channel).atapi.drq_bytes = BX_SELECTED_CONTROLLER(channel).byte_count;
-      BX_SELECTED_DRIVE(channel).atapi.total_bytes_remaining = (req_length < alloc_length) ? req_length : alloc_length;
-
-      // if (lazy) {
-           // // bias drq_bytes and total_bytes_remaining
-           // BX_SELECTED_DRIVE(channel).atapi.drq_bytes += 2048;
-           // BX_SELECTED_DRIVE(channel).atapi.total_bytes_remaining += 2048;
-      // }
-}
-
-void
-bx_hard_drive_c::atapi_cmd_error(Bit8u channel, sense_t sense_key, asc_t asc)
-{
-      BX_ERROR(("atapi_cmd_error channel=%02x key=%02x asc=%02x", channel, sense_key, asc));
-
-      BX_SELECTED_CONTROLLER(channel).error_register = sense_key << 4;
-      BX_SELECTED_CONTROLLER(channel).interrupt_reason.i_o = 1;
-      BX_SELECTED_CONTROLLER(channel).interrupt_reason.c_d = 1;
-      BX_SELECTED_CONTROLLER(channel).interrupt_reason.rel = 0;
-      BX_SELECTED_CONTROLLER(channel).status.busy = 0;
-      BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
-      BX_SELECTED_CONTROLLER(channel).status.write_fault = 0;
-      BX_SELECTED_CONTROLLER(channel).status.drq = 0;
-      BX_SELECTED_CONTROLLER(channel).status.err = 1;
-
-      BX_SELECTED_DRIVE(channel).sense.sense_key = sense_key;
-      BX_SELECTED_DRIVE(channel).sense.asc = asc;
-      BX_SELECTED_DRIVE(channel).sense.ascq = 0;
-}
-
-void BX_CPP_AttrRegparmN(1)
-bx_hard_drive_c::atapi_cmd_nop(Bit8u channel)
-{
-      BX_SELECTED_CONTROLLER(channel).interrupt_reason.i_o = 1;
-      BX_SELECTED_CONTROLLER(channel).interrupt_reason.c_d = 1;
-      BX_SELECTED_CONTROLLER(channel).interrupt_reason.rel = 0;
-      BX_SELECTED_CONTROLLER(channel).status.busy = 0;
-      BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
-      BX_SELECTED_CONTROLLER(channel).status.drq = 0;
-      BX_SELECTED_CONTROLLER(channel).status.err = 0;
-}
-
-void
-bx_hard_drive_c::init_mode_sense_single(Bit8u channel, const void* src, int size)
-{
-      // Header
-      BX_SELECTED_CONTROLLER(channel).buffer[0] = (size+6) >> 8;
-      BX_SELECTED_CONTROLLER(channel).buffer[1] = (size+6) & 0xff;
-      BX_SELECTED_CONTROLLER(channel).buffer[2] = 0x70; // no media present
-      BX_SELECTED_CONTROLLER(channel).buffer[3] = 0; // reserved
-      BX_SELECTED_CONTROLLER(channel).buffer[4] = 0; // reserved
-      BX_SELECTED_CONTROLLER(channel).buffer[5] = 0; // reserved
-      BX_SELECTED_CONTROLLER(channel).buffer[6] = 0; // reserved
-      BX_SELECTED_CONTROLLER(channel).buffer[7] = 0; // reserved
-
-      // Data
-      memcpy(BX_SELECTED_CONTROLLER(channel).buffer + 8, src, size);
-}
-
-  void BX_CPP_AttrRegparmN(1)
-bx_hard_drive_c::ready_to_send_atapi(Bit8u channel)
-{
-      raise_interrupt(channel);
-}
-
-void BX_CPP_AttrRegparmN(1)
-bx_hard_drive_c::raise_interrupt(Bit8u channel)
-{
-       BX_DEBUG(("raise_interrupt called, disable_irq = %02x", BX_SELECTED_CONTROLLER(channel).control.disable_irq));
-       if (!BX_SELECTED_CONTROLLER(channel).control.disable_irq) { BX_DEBUG(("raising interrupt")); } else { BX_DEBUG(("Not raising interrupt")); }
-      if (!BX_SELECTED_CONTROLLER(channel).control.disable_irq) {
-          Bit32u irq = BX_HD_THIS channels[channel].irq; 
-          BX_DEBUG(("Raising interrupt %d {%s}", irq, BX_SELECTED_TYPE_STRING(channel)));
-          DEV_pic_raise_irq(irq);
-      } else {
-          if (bx_dbg.disk || (BX_SELECTED_IS_CD(channel) && bx_dbg.cdrom))
-              BX_INFO(("Interrupt masked {%s}", BX_SELECTED_TYPE_STRING(channel)));
-      }
-}
-
-  void
-bx_hard_drive_c::command_aborted(Bit8u channel, unsigned value)
-{
-  BX_DEBUG(("aborting on command 0x%02x {%s}", value, BX_SELECTED_TYPE_STRING(channel)));
-  BX_SELECTED_CONTROLLER(channel).current_command = 0;
-  BX_SELECTED_CONTROLLER(channel).status.busy = 0;
-  BX_SELECTED_CONTROLLER(channel).status.drive_ready = 1;
-  BX_SELECTED_CONTROLLER(channel).status.err = 1;
-  BX_SELECTED_CONTROLLER(channel).error_register = 0x04; // command ABORTED
-  BX_SELECTED_CONTROLLER(channel).status.drq = 0;
-  BX_SELECTED_CONTROLLER(channel).status.seek_complete = 0;
-  BX_SELECTED_CONTROLLER(channel).status.corrected_data = 0;
-  BX_SELECTED_CONTROLLER(channel).buffer_index = 0;
-  raise_interrupt(channel);
-}
-
-  Bit32u
-bx_hard_drive_c::get_device_handle(Bit8u channel, Bit8u device)
-{
-  BX_DEBUG(("get_device_handle %d %d",channel, device));
-  if ((channel < BX_MAX_ATA_CHANNEL) && (device < 2)) {
-    return ((channel*2) + device);
-    }
-  
-  return BX_MAX_ATA_CHANNEL*2;
-}
-
-  Bit32u
-bx_hard_drive_c::get_first_cd_handle(void)
-{
-  for (Bit8u channel=0; channel<BX_MAX_ATA_CHANNEL; channel++) {
-    if (BX_DRIVE_IS_CD(channel,0)) return (channel*2);
-    if (BX_DRIVE_IS_CD(channel,1)) return ((channel*2) + 1);
-    }
-  return BX_MAX_ATA_CHANNEL*2;
-}
-
-  unsigned
-bx_hard_drive_c::get_cd_media_status(Bit32u handle)
-{
-  if ( handle >= BX_MAX_ATA_CHANNEL*2 ) return 0;
-
-  Bit8u channel = handle / 2;
-  Bit8u device  = handle % 2;
-  return( BX_HD_THIS channels[channel].drives[device].cdrom.ready );
-}
-
-  unsigned
-bx_hard_drive_c::set_cd_media_status(Bit32u handle, unsigned status)
-{
-  BX_DEBUG (("set_cd_media_status handle=%d status=%d", handle, status));
-  if ( handle >= BX_MAX_ATA_CHANNEL*2 ) return 0;
-
-  Bit8u channel = handle / 2;
-  Bit8u device  = handle % 2;
-
-  // if setting to the current value, nothing to do
-  if (status == BX_HD_THIS channels[channel].drives[device].cdrom.ready)
-    return(status);
-  // return 0 if no cdromd is present
-  if (!BX_DRIVE_IS_CD(channel,device))
-    return(0);
-
-  if (status == 0) {
-    // eject cdrom if not locked by guest OS
-    if (BX_HD_THIS channels[channel].drives[device].cdrom.locked) return(1);
-    else {
-#ifdef LOWLEVEL_CDROM
-      BX_HD_THIS channels[channel].drives[device].cdrom.cd->eject_cdrom();
-#endif
-      BX_HD_THIS channels[channel].drives[device].cdrom.ready = 0;
-      bx_options.atadevice[channel][device].Ostatus->set(BX_EJECTED);
-      }
-    }
-  else {
-    // insert cdrom
-#ifdef LOWLEVEL_CDROM
-    if (BX_HD_THIS channels[channel].drives[device].cdrom.cd->insert_cdrom(bx_options.atadevice[channel][device].Opath->getptr())) {
-      BX_INFO(( "Media present in CD-ROM drive"));
-      BX_HD_THIS channels[channel].drives[device].cdrom.ready = 1;
-      BX_HD_THIS channels[channel].drives[device].cdrom.capacity = BX_HD_THIS channels[channel].drives[device].cdrom.cd->capacity();
-      bx_options.atadevice[channel][device].Ostatus->set(BX_INSERTED);
-      BX_SELECTED_DRIVE(channel).sense.sense_key = SENSE_UNIT_ATTENTION;
-      BX_SELECTED_DRIVE(channel).sense.asc = 0;
-      BX_SELECTED_DRIVE(channel).sense.ascq = 0;
-      raise_interrupt(channel);
-      }
-    else {                 
-#endif
-      BX_INFO(( "Could not locate CD-ROM, continuing with media not present"));
-      BX_HD_THIS channels[channel].drives[device].cdrom.ready = 0;
-      bx_options.atadevice[channel][device].Ostatus->set(BX_EJECTED);
-#ifdef LOWLEVEL_CDROM
-      }
-#endif
-    }
-  return( BX_HD_THIS channels[channel].drives[device].cdrom.ready );
-}
-
-
-/*** default_image_t function definitions ***/
-
-int default_image_t::open (const char* pathname)
-{
-      return open(pathname, O_RDWR);
-}
-
-int default_image_t::open (const char* pathname, int flags)
-{
-      fd = ::open(pathname, flags
-#ifdef O_BINARY
-                 | O_BINARY
-#endif
-           );
-
-      if (fd < 0) {
-           return fd;
-      }
-
-      /* look at size of image file to calculate disk geometry */
-      struct stat stat_buf;
-      int ret = fstat(fd, &stat_buf);
-      if (ret) {
-           BX_PANIC(("fstat() returns error!"));
-      }
-
-      return fd;
-}
-
-void default_image_t::close ()
-{
-      if (fd > -1) {
-           ::close(fd);
-      }
-}
-
-off_t default_image_t::lseek (off_t offset, int whence)
-{
-      return ::lseek(fd, offset, whence);
-}
-
-ssize_t default_image_t::read (void* buf, size_t count)
-{
-      return ::read(fd, (char*) buf, count);
-}
-
-ssize_t default_image_t::write (const void* buf, size_t count)
-{
-      return ::write(fd, (char*) buf, count);
-}
-
-char increment_string (char *str, int diff)
-{
-  // find the last character of the string, and increment it.
-  char *p = str;
-  while (*p != 0) p++;
-  BX_ASSERT (p>str);  // choke on zero length strings
-  p--;  // point to last character of the string
-  (*p) += diff;  // increment to next/previous ascii code.
-  BX_DEBUG(("increment string returning '%s'", str));
- return (*p);
-}
-
-/*** concat_image_t function definitions ***/
-
-concat_image_t::concat_image_t ()
-{
-  fd = -1;
-}
-
-void concat_image_t::increment_string (char *str)
-{
- ::increment_string(str, +1);
-}
-
-int concat_image_t::open (const char* pathname0)
-{
-  char *pathname = strdup (pathname0);
-  BX_DEBUG(("concat_image_t.open"));
-  off_t start_offset = 0;
-  for (int i=0; i<BX_CONCAT_MAX_IMAGES; i++) {
-    fd_table[i] = ::open(pathname, O_RDWR
-#ifdef O_BINARY
-               | O_BINARY
-#endif
-         );
-    if (fd_table[i] < 0) {
-      // open failed.
-      // if no FD was opened successfully, return -1 (fail).
-      if (i==0) return -1;
-      // otherwise, it only means that all images in the series have 
-      // been opened.  Record the number of fds opened successfully.
-      maxfd = i; 
-      break;
-    }
-    BX_DEBUG(("concat_image: open image %s, fd[%d] = %d", pathname, i, fd_table[i]));
-    /* look at size of image file to calculate disk geometry */
-    struct stat stat_buf;
-    int ret = fstat(fd_table[i], &stat_buf);
-    if (ret) {
-         BX_PANIC(("fstat() returns error!"));
-    }
-#ifdef S_ISBLK
-    if (S_ISBLK(stat_buf.st_mode)) {
-      BX_PANIC(("block devices should REALLY NOT be used with --enable-split-hd. "
-                "Please reconfigure with --disable-split-hd"));
-    }
-#endif
-    if ((stat_buf.st_size % 512) != 0) {
-      BX_PANIC(("size of disk image must be multiple of 512 bytes"));
-    }
-    length_table[i] = stat_buf.st_size;
-    start_offset_table[i] = start_offset;
-    start_offset += stat_buf.st_size;
-    increment_string (pathname);
-  }
-  // start up with first image selected
-  index = 0;
-  fd = fd_table[0];
-  thismin = 0;
-  thismax = length_table[0]-1;
-  seek_was_last_op = 0;
-  return 0; // success.
-}
-
-void concat_image_t::close ()
-{
-  BX_DEBUG(("concat_image_t.close"));
-  if (fd > -1) {
-    ::close(fd);
-  }
-}
-
-off_t concat_image_t::lseek (off_t offset, int whence)
-{
-  if ((offset % 512) != 0) 
-    BX_PANIC( ("lseek HD with offset not multiple of 512"));
-  BX_DEBUG(("concat_image_t.lseek(%d)", whence));
-  // is this offset in this disk image?
-  if (offset < thismin) {
-    // no, look at previous images
-    for (int i=index-1; i>=0; i--) {
-      if (offset >= start_offset_table[i]) {
-       index = i;
-       fd = fd_table[i];
-       thismin = start_offset_table[i];
-       thismax = thismin + length_table[i] - 1;
-       BX_DEBUG(("concat_image_t.lseek to earlier image, index=%d", index));
-       break;
-      }
-    }
-  } else if (offset > thismax) {
-    // no, look at later images
-    for (int i=index+1; i<maxfd; i++) {
-      if (offset < start_offset_table[i] + length_table[i]) {
-       index = i;
-       fd = fd_table[i];
-       thismin = start_offset_table[i];
-       thismax = thismin + length_table[i] - 1;
-       BX_DEBUG(("concat_image_t.lseek to earlier image, index=%d", index));
-       break;
-      }
-    }
-  }
-  // now offset should be within the current image.
-  offset -= start_offset_table[index];
-  if (offset < 0 || offset >= length_table[index]) {
-    BX_PANIC(("concat_image_t.lseek to byte %ld failed", (long)offset));
-    return -1;
-  }
-
-  seek_was_last_op = 1;
-  return ::lseek(fd, offset, whence);
-}
-
-ssize_t concat_image_t::read (void* buf, size_t count)
-{
-  if (bx_dbg.disk)
-    BX_DEBUG(("concat_image_t.read %ld bytes", (long)count));
-  // notice if anyone does sequential read or write without seek in between.
-  // This can be supported pretty easily, but needs additional checks for
-  // end of a partial image.
-  if (!seek_was_last_op)
-    BX_PANIC( ("no seek before read"));
-  return ::read(fd, (char*) buf, count);
-}
-
-ssize_t concat_image_t::write (const void* buf, size_t count)
-{
-  BX_DEBUG(("concat_image_t.write %ld bytes", (long)count));
-  // notice if anyone does sequential read or write without seek in between.
-  // This can be supported pretty easily, but needs additional checks for
-  // end of a partial image.
-  if (!seek_was_last_op)
-    BX_PANIC( ("no seek before write"));
-  return ::write(fd, (char*) buf, count);
-}
-
-/*** sparse_image_t function definitions ***/
-sparse_image_t::sparse_image_t ()
-{
-  fd = -1;
-  pathname = NULL;
-#ifdef _POSIX_MAPPED_FILES
- mmap_header = NULL;
-#endif
- pagetable = NULL;
-}
-
-
-/*
-void showpagetable(uint32 * pagetable, size_t numpages)
-{
- printf("Non null pages: ");
- for (int i = 0; i < numpages; i++)
- {
-   if (pagetable[i] != 0xffffffff)
-   {
-     printf("%d ", i);
-   }
- }
- printf("\n");
-}
-*/
-
-
-void sparse_image_t::read_header()
-{
- BX_ASSERT(sizeof(header) == SPARSE_HEADER_SIZE);
-
- int ret = ::read(fd, &header, sizeof(header));
-
- if (-1 == ret)
- {
-     panic(strerror(errno));
- }
-
- if (sizeof(header) != ret)
- {
-   panic("could not read entire header");
- }
-
- if (dtoh32(header.magic) != SPARSE_HEADER_MAGIC)
- {
-   panic("failed header magic check");
- }
-
- if (dtoh32(header.version) != 1)
- {
-   panic("unknown version in header");
- }
-
- pagesize = dtoh32(header.pagesize);
- uint32 numpages = dtoh32(header.numpages);
-
- total_size = pagesize;
- total_size *= numpages;
-
- pagesize_shift = 0;
- while ((pagesize >> pagesize_shift) > 1) pagesize_shift++;
-
- if ((uint32)(1 << pagesize_shift) != pagesize)
- {
-   panic("failed block size header check");
- }
-
- pagesize_mask = pagesize - 1;
-
- size_t  preamble_size = (sizeof(uint32) * numpages) + sizeof(header);
- data_start = 0;
- while (data_start < preamble_size) data_start += pagesize;
-
- bool did_mmap = false;
-
-#ifdef _POSIX_MAPPED_FILES
-// Try to memory map from the beginning of the file (0 is trivially a page multiple)
- void * mmap_header = mmap(NULL, preamble_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
- if (mmap_header == MAP_FAILED)
- {
-   BX_INFO(("failed to mmap sparse disk file - using conventional file access"));
-   mmap_header = NULL;
- }
- else
- {
-   mmap_length = preamble_size;
-   did_mmap = true;
-   pagetable = ((uint32 *) (((uint8 *) mmap_header) + sizeof(header)));
-
-//   system_pagesize = getpagesize();
-   system_pagesize_mask = getpagesize() - 1;
- }
-#endif
-
- if (!did_mmap)
- {
-   pagetable = new uint32[numpages];
-
-   if (pagetable == NULL)
-   {
-     panic("could not allocate memory for sparse disk block table");
-   }
-
-   ret = ::read(fd, pagetable, sizeof(uint32) * numpages);
-
-   if (-1 == ret)
-   {
-       panic(strerror(errno));
-   }
-
-   if ((int)(sizeof(uint32) * numpages) != ret)
-   {
-     panic("could not read entire block table");
-   }
- }
-}
-
-int sparse_image_t::open (const char* pathname0)
-{
- pathname = strdup(pathname0);
- BX_DEBUG(("sparse_image_t.open"));
-
- fd = ::open(pathname, O_RDWR
-#ifdef O_BINARY
-   | O_BINARY
-#endif
-   );
-
- if (fd < 0)
- {
-   // open failed.
-   return -1;
- }
- BX_DEBUG(("sparse_image: open image %s", pathname));
-
- read_header();
-
- struct stat stat_buf;
- if (0 != fstat(fd, &stat_buf)) panic(("fstat() returns error!"));
-
- underlying_filesize = stat_buf.st_size;
-
- if ((underlying_filesize % pagesize) != 0)
-   panic("size of sparse disk image is not multiple of page size");
-
- underlying_current_filepos = 0;
- if (-1 == ::lseek(fd, 0, SEEK_SET))
-   panic("error while seeking to start of file");
-
- lseek(0, SEEK_SET);
-
- //showpagetable(pagetable, header.numpages);
-
- char * parentpathname = strdup(pathname);
- char lastchar = ::increment_string(parentpathname, -1);
-
- if ((lastchar >= '0') && (lastchar <= '9'))
- {
-   struct stat stat_buf;
-   if (0 == stat(parentpathname, &stat_buf))
-   {
-     parent_image = new sparse_image_t();
-     int ret = parent_image->open(parentpathname);
-     if (ret != 0) return ret;
-     if (    (parent_image->pagesize != pagesize)
-         ||  (parent_image->total_size != total_size))
-     {
-       panic("child drive image does not have same page count/page size configuration");
-     }
-   }
- }
-
- if (parentpathname != NULL) free(parentpathname);
-
- return 0; // success.
-}
-
-void sparse_image_t::close ()
-{
-  BX_DEBUG(("concat_image_t.close"));
-  if (pathname != NULL)
-  {
-   free(pathname);
- }
-#ifdef _POSIX_MAPPED_FILES
- if (mmap_header != NULL)
- {
-   int ret = munmap(mmap_header, mmap_length);
-   if (ret != 0)
-     BX_INFO(("failed to un-memory map sparse disk file"));
- }
- pagetable = NULL; // We didn't malloc it
-#endif
-  if (fd > -1) {
-    ::close(fd);
-  }
- if (pagetable != NULL)
- {
-   delete [] pagetable;
- }
- if (parent_image != NULL)
- {
-   delete parent_image;
- }
-}
-
-off_t sparse_image_t::lseek (off_t offset, int whence)
-{
- //showpagetable(pagetable, header.numpages);
-
- if ((offset % 512) != 0)
-    BX_PANIC( ("lseek HD with offset not multiple of 512"));
- if (whence != SEEK_SET)
-   BX_PANIC( ("lseek HD with whence not SEEK_SET"));
-
- BX_DEBUG(("sparse_image_t.lseek(%d)", whence));
-
- if (offset > total_size)
- {
-   BX_PANIC(("sparse_image_t.lseek to byte %ld failed", (long)offset));
-    return -1;
-  }
-
- //printf("Seeking to position %ld\n", (long) offset);
-
- set_virtual_page(offset >> pagesize_shift);
- position_page_offset = offset & pagesize_mask;
-
- return 0;
-}
-
-inline off_t sparse_image_t::get_physical_offset()
-{
- off_t physical_offset = data_start;
- physical_offset += (position_physical_page << pagesize_shift);
- physical_offset += position_page_offset;
-
- return physical_offset;
-}
-
-inline void sparse_image_t::set_virtual_page(uint32 new_virtual_page)
-{
- position_virtual_page = new_virtual_page;
-
- position_physical_page = dtoh32(pagetable[position_virtual_page]);
-}
-
-ssize_t sparse_image_t::read_page_fragment(uint32 read_virtual_page, uint32 read_page_offset, size_t read_size, void * buf)
-{
- if (read_virtual_page != position_virtual_page)
- {
-   set_virtual_page(read_virtual_page);
- }
-
- position_page_offset = read_page_offset;
-
- if (position_physical_page == SPARSE_PAGE_NOT_ALLOCATED)
- {
-   if (parent_image != NULL)
-   {
-     return parent_image->read_page_fragment(read_virtual_page, read_page_offset, read_size, buf);
-   }
-   else
-   {
-     memset(buf, 0, read_size);
-   }
- }
- else
- {
-   off_t physical_offset = get_physical_offset();
-
-   if (physical_offset != underlying_current_filepos)
-   {
-     int ret = ::lseek(fd, physical_offset, SEEK_SET);
-     // underlying_current_filepos update deferred
-     if (ret == -1)
-       panic(strerror(errno));
-   }
-
-   //printf("Reading %s at position %ld size %d\n", pathname, (long) physical_offset, (long) read_size);
-   ssize_t readret = ::read(fd, buf, read_size);
-
-   if (readret == -1)
-   {
-     panic(strerror(errno));
-   }
-
-   if ((size_t)readret != read_size)
-   {
-     panic("could not read block contents from file");
-   }
-
-   underlying_current_filepos = physical_offset + read_size;
- }
-
- return read_size;
-}
-
-ssize_t sparse_image_t::read(void* buf, size_t count)
-{
- //showpagetable(pagetable, header.numpages);
- ssize_t total_read = 0;
-
- if (bx_dbg.disk)
-    BX_DEBUG(("sparse_image_t.read %ld bytes", (long)count));
-
- while (count != 0)
- {
-   size_t can_read = pagesize - position_page_offset;
-   if (count < can_read) can_read = count;
-
-   BX_ASSERT (can_read != 0);
-
-   size_t  was_read = read_page_fragment(position_virtual_page, position_page_offset, can_read, buf);
-
-   BX_ASSERT(was_read == can_read);
-
-   total_read += can_read;
-
-   position_page_offset += can_read;
-   if (position_page_offset == pagesize)
-   {
-     position_page_offset = 0;
-     set_virtual_page(position_virtual_page + 1);
-   }
-
-   BX_ASSERT(position_page_offset < pagesize);
-
-   buf = (((uint8 *) buf) + can_read);
-   count -= can_read;
- }
-
- return total_read;
-}
-
-void sparse_image_t::panic(const char * message)
-{
- char buffer[1024];
- if (message == NULL)
- {
-   snprintf(buffer, sizeof(buffer), "error with sparse disk image %s", pathname);
- }
- else
- {
-   snprintf(buffer, sizeof(buffer), "error with sparse disk image %s - %s", pathname, message);
- }
- BX_PANIC((buffer));
-}
-
-ssize_t sparse_image_t::write (const void* buf, size_t count)
-{
- //showpagetable(pagetable, header.numpages);
-
- ssize_t total_written = 0;
-
- uint32  update_pagetable_start = position_virtual_page;
- uint32  update_pagetable_count = 0;
-
- if (bx_dbg.disk)
-    BX_DEBUG(("sparse_image_t.write %ld bytes", (long)count));
-
- while (count != 0)
- {
-   size_t can_write = pagesize - position_page_offset;
-   if (count < can_write) can_write = count;
-
-   BX_ASSERT (can_write != 0);
-
-   if (position_physical_page == SPARSE_PAGE_NOT_ALLOCATED)
-   {
-     // We just add on another page at the end of the file
-     // Reclamation, compaction etc should currently be done off-line
-
-     size_t  data_size = underlying_filesize - data_start;
-     BX_ASSERT((data_size % pagesize) == 0);
-
-
-     uint32  data_size_pages = data_size / pagesize;
-     uint32  next_data_page = data_size_pages;
-
-     pagetable[position_virtual_page] = htod32(next_data_page);
-     position_physical_page = next_data_page;
-
-     off_t page_file_start = data_start + (position_physical_page << pagesize_shift);
-
-     if (parent_image != NULL)
-     {
-       // If we have a parent, we must merge our portion with the parent
-       void * writebuffer = NULL;
-
-       if (can_write == pagesize)
-       {
-         writebuffer = (void *) buf;
-       }
-       else
-       {
-         writebuffer = malloc(pagesize);
-         if (writebuffer == NULL)
-           panic("Cannot allocate sufficient memory for page-merge in write");
-
-         // Read entire page - could optimize, but simple for now
-         parent_image->read_page_fragment(position_virtual_page, 0, pagesize, writebuffer);
-
-         void * dest_start = ((uint8 *) writebuffer) + position_page_offset;
-         memcpy(dest_start, buf, can_write);
-       }
-
-       int ret;
-       ret = ::lseek(fd, page_file_start, SEEK_SET);
-       // underlying_current_filepos update deferred
-       if (-1 == ret) panic(strerror(errno));
-
-       ret = ::write(fd, writebuffer, pagesize);
-
-       if (-1 == ret) panic(strerror(errno));
-
-       if (pagesize != (uint32)ret) panic("failed to write entire merged page to disk");
-
-       if (can_write != pagesize)
-       {
-         free(writebuffer);
-       }
-     }
-     else
-     {
-       // We need to write a zero page because read has been returning zeroes
-       // We seek as close to the page end as possible, and then write a little
-       // This produces a sparse file which has blanks
-       // Also very quick, even when pagesize is massive
-       int ret;
-       ret = ::lseek(fd, page_file_start + pagesize - 4, SEEK_SET);
-       // underlying_current_filepos update deferred
-       if (-1 == ret) panic(strerror(errno));
-
-       uint32  zero = 0;
-       ret = ::write(fd, &zero, 4);
-
-       if (-1 == ret) panic(strerror(errno));
-
-       if (4 != ret) panic("failed to write entire blank page to disk");
-     }
-
-     update_pagetable_count = (position_virtual_page - update_pagetable_start) + 1;
-     underlying_filesize = underlying_current_filepos = page_file_start + pagesize;
-   }
-
-   BX_ASSERT(position_physical_page != SPARSE_PAGE_NOT_ALLOCATED);
-
-   off_t physical_offset = get_physical_offset();
-
-   if (physical_offset != underlying_current_filepos)
-   {
-     int ret = ::lseek(fd, physical_offset, SEEK_SET);
-     // underlying_current_filepos update deferred
-     if (ret == -1)
-       panic(strerror(errno));
-   }
-
-   //printf("Writing at position %ld size %d\n", (long) physical_offset, can_write);
-   ssize_t writeret = ::write(fd, buf, can_write);
-
-   if (writeret == -1)
-   {
-     panic(strerror(errno));
-   }
-
-   if ((size_t)writeret != can_write)
-   {
-     panic("could not write block contents to file");
-   }
-
-   underlying_current_filepos = physical_offset + can_write;
-
-   total_written += can_write;
-
-   position_page_offset += can_write;
-   if (position_page_offset == pagesize)
-   {
-     position_page_offset = 0;
-     set_virtual_page(position_virtual_page + 1);
-   }
-
-   BX_ASSERT(position_page_offset < pagesize);
-
-   buf = (((uint8 *) buf) + can_write);
-   count -= can_write;
- }
-
- if (update_pagetable_count != 0)
- {
-   bool done = false;
-   off_t pagetable_write_from = sizeof(header) + (sizeof(uint32) * update_pagetable_start);
-   size_t  write_bytecount = update_pagetable_count * sizeof(uint32);
-
-#ifdef _POSIX_MAPPED_FILES
-   if (mmap_header != NULL)
-   {
-     // Sync from the beginning of the page
-     size_t system_page_offset = pagetable_write_from & system_pagesize_mask;
-     void * start = ((uint8 *) mmap_header + pagetable_write_from - system_page_offset);
-
-     int ret = msync(start, system_page_offset + write_bytecount, MS_ASYNC);
-
-     if (ret != 0)
-       panic(strerror(errno));
-
-     done = true;
-   }
-#endif
-
-   if (!done)
-   {
-     int ret = ::lseek(fd, pagetable_write_from, SEEK_SET);
-     // underlying_current_filepos update deferred
-     if (ret == -1) panic(strerror(errno));
-
-     //printf("Writing header at position %ld size %ld\n", (long) pagetable_write_from, (long) write_bytecount);
-     ret = ::write(fd, &pagetable[update_pagetable_start], write_bytecount);
-     if (ret == -1) panic(strerror(errno));
-     if ((size_t)ret != write_bytecount) panic("could not write entire updated block header");
-
-     underlying_current_filepos = pagetable_write_from + write_bytecount;
-   }
- }
-
- return total_written;
-}
-
-#if DLL_HD_SUPPORT
-/*** dll_image_t function definitions ***/
-
-/*
-function vdisk_open(path:PChar;numclusters,clustersize:integer):integer;
-procedure vdisk_read(vunit:integer;blk:integer;var buf:TBlock);
-procedure vdisk_write(vunit:integer;blk:integer;var buf:TBlock);
-procedure vdisk_close(vunit:integer);
-*/
-
-HINSTANCE hlib_vdisk = 0;
-
-int (*vdisk_open)  (const char *path,int numclusters,int clustersize);
-void (*vdisk_read)   (int vunit,int blk,void *buf);
-void (*vdisk_write)  (int vunit,int blk,const void *buf);
-void (*vdisk_close) (int vunit);
-
-int dll_image_t::open (const char* pathname)
-{
-    if (hlib_vdisk == 0) {
-      hlib_vdisk = LoadLibrary("vdisk.dll");
-      if (hlib_vdisk != 0) {
-        vdisk_read = (void (*)(int,int,void*))        GetProcAddress(hlib_vdisk,"vdisk_read");
-        vdisk_write = (void (*)(int,int,const void*)) GetProcAddress(hlib_vdisk,"vdisk_write");
-        vdisk_open = (int (*)(const char *,int,int))  GetProcAddress(hlib_vdisk,"vdisk_open");
-        vdisk_close = (void (*)(int))                 GetProcAddress(hlib_vdisk,"vdisk_close");
-      }
-    }
-    if (hlib_vdisk != 0) {
-      vunit = vdisk_open(pathname,0x10000,64);
-      vblk = 0;
-    } else {
-      vunit = -2;
-    }
-    return vunit;
-}
-
-void dll_image_t::close ()
-{
-   if (vunit >= 0 && hlib_vdisk != 0) {
-     vdisk_close(vunit);
-   }
-}
-
-off_t dll_image_t::lseek (off_t offset, int whence)
-{
-      vblk = offset >> 9;
-      return 0;
-}
-
-ssize_t dll_image_t::read (void* buf, size_t count)
-{
-      if (vunit >= 0 && hlib_vdisk != 0) {
-         vdisk_read(vunit,vblk,buf);
-         return count;
-      } else {
-         return -1;
-      }
-}
-
-ssize_t dll_image_t::write (const void* buf, size_t count)
-{
-      if (vunit >= 0 && hlib_vdisk != 0) {
-        vdisk_write(vunit,vblk,buf);
-        return count;
-      } else {
-         return -1;
-      }
-}
-#endif // DLL_HD_SUPPORT
-
-error_recovery_t::error_recovery_t ()
-{
-      if (sizeof(error_recovery_t) != 8) {
-           BX_PANIC(("error_recovery_t has size != 8"));
-      }
-
-      data[0] = 0x01;
-      data[1] = 0x06;
-      data[2] = 0x00;
-      data[3] = 0x05; // Try to recover 5 times
-      data[4] = 0x00;
-      data[5] = 0x00;
-      data[6] = 0x00;
-      data[7] = 0x00;
-}
-
-uint16  BX_CPP_AttrRegparmN(1) 
-read_16bit(const uint8* buf)
-{
-      return (buf[0] << 8) | buf[1];
-}
-
-uint32  BX_CPP_AttrRegparmN(1)
-read_32bit(const uint8* buf)
-{
-      return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
-}
-
-// redolog implementation
-redolog_t::redolog_t ()
-{
-        fd = -1;
-        catalog = NULL;
-        bitmap = NULL;
-        extent_index = (Bit32u)0;
-        extent_offset = (Bit32u)0;
-        extent_next = (Bit32u)0;
-}
-
-void
-redolog_t::print_header()
-{
-        BX_INFO(("redolog : Standard Header : magic='%s', type='%s', subtype='%s', version = %d.%d",
-                header.standard.magic, header.standard.type, header.standard.subtype,
-                dtoh32(header.standard.version)/0x10000,
-                dtoh32(header.standard.version)%0x10000));
-        BX_INFO(("redolog : Specific Header : #entries=%d, bitmap size=%d, exent size = %d disk size = %lld",
-                dtoh32(header.specific.catalog),
-                dtoh32(header.specific.bitmap),
-                dtoh32(header.specific.extent),
-                dtoh64(header.specific.disk)));
-}
-
-int 
-redolog_t::make_header (const char* type, Bit64u size)
-{
-        Bit32u entries, extent_size, bitmap_size;
-        Bit64u maxsize;
-        Bit32u flip=0;
-
-        // Set standard header values
-        strcpy((char*)header.standard.magic, STANDARD_HEADER_MAGIC);
-        strcpy((char*)header.standard.type, REDOLOG_TYPE);
-        strcpy((char*)header.standard.subtype, type);
-        header.standard.version = htod32(STANDARD_HEADER_VERSION);
-        header.standard.header = htod32(STANDARD_HEADER_SIZE);
-
-        entries = 512;
-        bitmap_size = 1;
-
-        // Compute #entries and extent size values
-        do {
-                extent_size = 8 * bitmap_size * 512;
-
-                header.specific.catalog = htod32(entries);
-                header.specific.bitmap = htod32(bitmap_size);
-                header.specific.extent = htod32(extent_size);
-                
-                maxsize = (Bit64u)entries * (Bit64u)extent_size;
-
-                flip++;
-
-                if(flip&0x01) bitmap_size *= 2;
-                else entries *= 2;
-        } while (maxsize < size);
-
-        header.specific.disk = htod64(size);
-        
-        print_header();
-
-        catalog = (Bit32u*)malloc(dtoh32(header.specific.catalog) * sizeof(Bit32u));
-        bitmap = (Bit8u*)malloc(dtoh32(header.specific.bitmap));
-
-        if ((catalog == NULL) || (bitmap==NULL))
-                BX_PANIC(("redolog : could not malloc catalog or bitmap"));
-
-        for (Bit32u i=0; i<dtoh32(header.specific.catalog); i++)
-                catalog[i] = htod32(REDOLOG_PAGE_NOT_ALLOCATED);
-
-        bitmap_blocs = 1 + (dtoh32(header.specific.bitmap) - 1) / 512;
-        extent_blocs = 1 + (dtoh32(header.specific.extent) - 1) / 512;
-
-        BX_DEBUG(("redolog : each bitmap is %d blocs", bitmap_blocs));
-        BX_DEBUG(("redolog : each extent is %d blocs", extent_blocs));
-
-        return 0;
-}
-
-int 
-redolog_t::create (const char* filename, const char* type, Bit64u size)
-{
-        int filedes;
-
-        BX_INFO(("redolog : creating redolog %s", filename));
-
-        filedes = ::open(filename, O_RDWR | O_CREAT | O_TRUNC
-#ifdef O_BINARY
-            | O_BINARY
-#endif
-              , S_IWUSR | S_IRUSR | S_IRGRP | S_IWGRP);
-
-        return create(filedes, type, size);
-}
-
-int 
-redolog_t::create (int filedes, const char* type, Bit64u size)
-{
-        fd = filedes;
-
-        if (fd < 0)
-        {
-                // open failed.
-                return -1;
-        }
-
-        if (make_header(type, size) < 0)
-        {
-                return -1;
-        }
-
-        // Write header
-        ::write(fd, &header, dtoh32(header.standard.header));
-
-        // Write catalog
-        // FIXME could mmap
-        ::write(fd, catalog, dtoh32(header.specific.catalog) * sizeof (Bit32u));
-
-        return 0;
-}
-
-int 
-redolog_t::open (const char* filename, const char *type, Bit64u size)
-{
-        int res;
-
-        fd = ::open(filename, O_RDWR
-#ifdef O_BINARY
-            | O_BINARY
-#endif
-              );
-        if (fd < 0)
-        {
-                BX_INFO(("redolog : could not open image %s", filename));
-                // open failed.
-                return -1;
-        }
-        BX_INFO(("redolog : open image %s", filename));
-      
-        res = ::read(fd, &header, sizeof(header));
-        if (res != STANDARD_HEADER_SIZE)
-        {
-               BX_PANIC(("redolog : could not read header")); 
-               return -1;
-        }
-
-        print_header();
-
-        if (strcmp((char*)header.standard.magic, STANDARD_HEADER_MAGIC) != 0)
-        {
-               BX_PANIC(("redolog : Bad header magic")); 
-               return -1;
-        }
-
-        if (strcmp((char*)header.standard.type, REDOLOG_TYPE) != 0)
-        {
-               BX_PANIC(("redolog : Bad header type")); 
-               return -1;
-        }
-        if (strcmp((char*)header.standard.subtype, type) != 0)
-        {
-               BX_PANIC(("redolog : Bad header subtype")); 
-               return -1;
-        }
-
-        if (dtoh32(header.standard.version) != STANDARD_HEADER_VERSION)
-        {
-               BX_PANIC(("redolog : Bad header version")); 
-               return -1;
-        }
-
-        catalog = (Bit32u*)malloc(dtoh32(header.specific.catalog) * sizeof(Bit32u));
-        
-        // FIXME could mmap
-        ::lseek(fd,dtoh32(header.standard.header),SEEK_SET);
-        res = ::read(fd, catalog, dtoh32(header.specific.catalog) * sizeof(Bit32u)) ;
-
-        if (res !=  (ssize_t)(dtoh32(header.specific.catalog) * sizeof(Bit32u)))
-        {
-               BX_PANIC(("redolog : could not read catalog %d=%d",res, dtoh32(header.specific.catalog))); 
-               return -1;
-        }
-
-        // check last used extent
-        extent_next = 0;
-        for (Bit32u i=0; i < dtoh32(header.specific.catalog); i++)
-        {
-                if (dtoh32(catalog[i]) != REDOLOG_PAGE_NOT_ALLOCATED)
-                {
-                        if (dtoh32(catalog[i]) >= extent_next)
-                                extent_next = dtoh32(catalog[i]) + 1;
-                }
-        }
-        BX_INFO(("redolog : next extent will be at index %d",extent_next));
-      
-        // memory used for storing bitmaps
-        bitmap = (Bit8u *)malloc(dtoh32(header.specific.bitmap));
-
-        bitmap_blocs = 1 + (dtoh32(header.specific.bitmap) - 1) / 512;
-        extent_blocs = 1 + (dtoh32(header.specific.extent) - 1) / 512;
-
-        BX_DEBUG(("redolog : each bitmap is %d blocs", bitmap_blocs));
-        BX_DEBUG(("redolog : each extent is %d blocs", extent_blocs));
-
-        return 0;
-}
-
-void 
-redolog_t::close ()
-{
-        if (fd >= 0)
-                ::close(fd);
-
-        if (catalog != NULL)
-                free(catalog);
-
-        if (bitmap != NULL)
-                free(bitmap);
-}
-
-off_t
-redolog_t::lseek (off_t offset, int whence)
-{
-        if ((offset % 512) != 0) {
-                BX_PANIC( ("redolog : lseek HD with offset not multiple of 512"));
-                return -1;
-        }
-        if (whence != SEEK_SET) {
-                BX_PANIC( ("redolog : lseek HD with whence not SEEK_SET"));
-                return -1;
-        }
-        if (offset > (off_t)dtoh64(header.specific.disk))
-        {
-                BX_PANIC(("redolog : lseek to byte %ld failed", (long)offset));
-                return -1;
-        }
-
-        extent_index = offset / dtoh32(header.specific.extent);
-        extent_offset = (offset % dtoh32(header.specific.extent)) / 512;
-
-        BX_DEBUG(("redolog : lseeking extent index %d, offset %d",extent_index, extent_offset));
-
-        return offset;
-}
-
-ssize_t
-redolog_t::read (void* buf, size_t count)
-{
-        off_t bloc_offset, bitmap_offset;
-
-        if (count != 512)
-                BX_PANIC( ("redolog : read HD with count not 512"));
-
-        BX_DEBUG(("redolog : reading index %d, mapping to %d", extent_index, dtoh32(catalog[extent_index])));
-
-        if (dtoh32(catalog[extent_index]) == REDOLOG_PAGE_NOT_ALLOCATED)
-        {
-                // page not allocated
-                return 0;
-        }
-
-        bitmap_offset  = (off_t)STANDARD_HEADER_SIZE + (dtoh32(header.specific.catalog) * sizeof(Bit32u));
-        bitmap_offset += (off_t)512 * dtoh32(catalog[extent_index]) * (extent_blocs + bitmap_blocs); 
-        bloc_offset    = bitmap_offset + ((off_t)512 * (bitmap_blocs + extent_offset));
-
-        BX_DEBUG(("redolog : bitmap offset is %x", (Bit32u)bitmap_offset));
-        BX_DEBUG(("redolog : bloc offset is %x", (Bit32u)bloc_offset));
-
-
-        // FIXME if same extent_index as before we can skip bitmap read
-
-        ::lseek(fd, bitmap_offset, SEEK_SET);
-
-        if (::read(fd, bitmap,  dtoh32(header.specific.bitmap)) != (ssize_t)dtoh32(header.specific.bitmap))
-        {
-                BX_PANIC(("redolog : failed to read bitmap for extent %d", extent_index));
-                return 0;
-        }
-
-        if ( ((bitmap[extent_offset/8] >> (extent_offset%8)) & 0x01) == 0x00 )
-        {
-                BX_DEBUG(("read not in redolog"));
-
-                // bitmap says bloc not in reloglog
-                return 0;
-        }
-        
-        ::lseek(fd, bloc_offset, SEEK_SET);
-
-        return (::read(fd, buf, count));
-}
-
-ssize_t
-redolog_t::write (const void* buf, size_t count)
-{
-        Bit32u i;
-        off_t bloc_offset, bitmap_offset, catalog_offset;
-        ssize_t written;
-        bx_bool update_catalog = 0;
-
-        if (count != 512)
-                BX_PANIC( ("redolog : write HD with count not 512"));
-
-        BX_DEBUG(("redolog : writing index %d, mapping to %d", extent_index, dtoh32(catalog[extent_index])));
-        if (dtoh32(catalog[extent_index]) == REDOLOG_PAGE_NOT_ALLOCATED)
-        {
-                if(extent_next >= dtoh32(header.specific.catalog))
-                {
-                        BX_PANIC(("redolog : can't allocate new extent... catalog is full"));
-                        return 0;
-                }
-
-                BX_DEBUG(("redolog : allocating new extent at %d", extent_next));
-
-                // Extent not allocated, allocate new
-                catalog[extent_index] = htod32(extent_next);
-                
-                extent_next += 1;
-
-                char *zerobuffer = (char*)malloc(512);
-                memset(zerobuffer, 0, 512);
-
-                // Write bitmap
-                bitmap_offset  = (off_t)STANDARD_HEADER_SIZE + (dtoh32(header.specific.catalog) * sizeof(Bit32u));
-                bitmap_offset += (off_t)512 * dtoh32(catalog[extent_index]) * (extent_blocs + bitmap_blocs); 
-                ::lseek(fd, bitmap_offset, SEEK_SET);
-                for(i=0; i<bitmap_blocs; i++)
-                {
-                        ::write(fd, zerobuffer, 512);
-                }
-                // Write extent
-                for(i=0; i<extent_blocs; i++)
-                {
-                        ::write(fd, zerobuffer, 512);
-                }
-
-                free(zerobuffer);
-
-                update_catalog = 1;
-        }
-
-        bitmap_offset  = (off_t)STANDARD_HEADER_SIZE + (dtoh32(header.specific.catalog) * sizeof(Bit32u));
-        bitmap_offset += (off_t)512 * dtoh32(catalog[extent_index]) * (extent_blocs + bitmap_blocs); 
-        bloc_offset    = bitmap_offset + ((off_t)512 * (bitmap_blocs + extent_offset));
-
-        BX_DEBUG(("redolog : bitmap offset is %x", (Bit32u)bitmap_offset));
-        BX_DEBUG(("redolog : bloc offset is %x", (Bit32u)bloc_offset));
-
-        // Write bloc
-        ::lseek(fd, bloc_offset, SEEK_SET);
-        written = ::write(fd, buf, count);
-
-        // Write bitmap
-        // FIXME if same extent_index as before we can skip bitmap read
-        ::lseek(fd, bitmap_offset, SEEK_SET);
-        if (::read(fd, bitmap,  dtoh32(header.specific.bitmap)) != (ssize_t)dtoh32(header.specific.bitmap))
-        {
-                BX_PANIC(("redolog : failed to read bitmap for extent %d", extent_index));
-                return 0;
-        }
-
-        // If bloc does not belong to extent yet
-        if ( ((bitmap[extent_offset/8] >> (extent_offset%8)) & 0x01) == 0x00 )
-        {
-                bitmap[extent_offset/8] |= 1 << (extent_offset%8);
-                ::lseek(fd, bitmap_offset, SEEK_SET);
-                ::write(fd, bitmap,  dtoh32(header.specific.bitmap));
-        }
-
-        // Write catalog
-        if (update_catalog)
-        {
-                // FIXME if mmap
-                catalog_offset  = (off_t)STANDARD_HEADER_SIZE + (extent_index * sizeof(Bit32u));
-
-                BX_DEBUG(("redolog : writing catalog at offset %x", (Bit32u)catalog_offset));
-
-                ::lseek(fd, catalog_offset, SEEK_SET);
-                ::write(fd, &catalog[extent_index], sizeof(Bit32u));
-        }
-
-        return written;
-}
-
-
-/*** growing_image_t function definitions ***/
-
-growing_image_t::growing_image_t(Bit64u _size)
-{
-        redolog = new redolog_t();
-        size = _size;
-}
-
-int growing_image_t::open (const char* pathname)
-{
-        int filedes = redolog->open(pathname,REDOLOG_SUBTYPE_GROWING,size);
-        BX_INFO(("'growing' disk opened, growing file is '%s'", pathname));
-        return filedes;
-}
-
-void growing_image_t::close ()
-{
-        redolog->close();
-}
-
-off_t growing_image_t::lseek (off_t offset, int whence)
-{
-      return redolog->lseek(offset, whence);
-}
-
-ssize_t growing_image_t::read (void* buf, size_t count)
-{
-      memset(buf, 0, count);
-      redolog->read((char*) buf, count);
-      return count;
-}
-
-ssize_t growing_image_t::write (const void* buf, size_t count)
-{
-      return redolog->write((char*) buf, count);
-}
-
-
-/*** undoable_image_t function definitions ***/
-
-undoable_image_t::undoable_image_t(Bit64u _size, const char* _redolog_name)
-{
-        redolog = new redolog_t();
-        ro_disk = new default_image_t();
-        size = _size;
-        redolog_name = NULL;
-        if (_redolog_name != NULL) {
-          if (strcmp(_redolog_name,"") != 0) {
-            redolog_name = strdup(_redolog_name);
-          }
-        }
-}
-
-int undoable_image_t::open (const char* pathname)
-{
-        char *logname=NULL;
-
-        if (ro_disk->open(pathname, O_RDONLY)<0)
-                return -1;
-
-        // if redolog name was set 
-        if ( redolog_name != NULL) {
-                if ( strcmp(redolog_name, "") != 0 ) {
-                        logname = (char*)malloc(strlen(redolog_name) + 1);
-                        strcpy (logname, redolog_name);
-                }
-        }
-
-        // Otherwise we make up the redolog filename from the pathname
-        if ( logname == NULL) {
-                logname = (char*)malloc(strlen(pathname) + UNDOABLE_REDOLOG_EXTENSION_LENGTH + 1);
-                sprintf (logname, "%s%s", pathname, UNDOABLE_REDOLOG_EXTENSION);
-        }
-
-        if (redolog->open(logname,REDOLOG_SUBTYPE_UNDOABLE,size) < 0)
-        {
-                if (redolog->create(logname, REDOLOG_SUBTYPE_UNDOABLE, size) < 0)
-                {
-                        BX_PANIC(("Can't open or create redolog '%s'",logname));
-                        return -1;
-                }
-        }
-
-        BX_INFO(("'undoable' disk opened: ro-file is '%s', redolog is '%s'", pathname, logname));
-        free(logname);
-
-        return 0;
-}
-
-void undoable_image_t::close ()
-{
-        redolog->close();
-        ro_disk->close();
-
-        if (redolog_name!=NULL)
-          free(redolog_name);
-}
-
-off_t undoable_image_t::lseek (off_t offset, int whence)
-{
-      redolog->lseek(offset, whence);
-      return ro_disk->lseek(offset, whence);
-}
-
-ssize_t undoable_image_t::read (void* buf, size_t count)
-{
-      // This should be fixed if count != 512
-      if ((size_t)redolog->read((char*) buf, count) != count)
-              return ro_disk->read((char*) buf, count);
-      else 
-              return count;
-}
-
-ssize_t undoable_image_t::write (const void* buf, size_t count)
-{
-      return redolog->write((char*) buf, count);
-}
-
-
-/*** volatile_image_t function definitions ***/
-
-volatile_image_t::volatile_image_t(Bit64u _size, const char* _redolog_name)
-{
-        redolog = new redolog_t();
-        ro_disk = new default_image_t();
-        size = _size;
-        redolog_temp = NULL;
-        redolog_name = NULL;
-        if (_redolog_name != NULL) {
-          if (strcmp(_redolog_name,"") != 0) {
-            redolog_name = strdup(_redolog_name);
-          }
-        }
-}
-
-int volatile_image_t::open (const char* pathname)
-{
-        int filedes;
-        const char *logname=NULL;
-
-        if (ro_disk->open(pathname, O_RDONLY)<0)
-                return -1;
-
-        // if redolog name was set 
-        if ( redolog_name != NULL) {
-                if ( strcmp(redolog_name, "") != 0 ) {
-                        logname = redolog_name;
-                }
-        }
-
-        // otherwise use pathname as template
-        if (logname == NULL) {
-                logname = pathname;
-        }
-
-        redolog_temp = (char*)malloc(strlen(logname) + VOLATILE_REDOLOG_EXTENSION_LENGTH + 1);
-        sprintf (redolog_temp, "%s%s", logname, VOLATILE_REDOLOG_EXTENSION);
-
-        filedes = mkstemp (redolog_temp);
-
-        if (filedes < 0)
-        {
-                BX_PANIC(("Can't create volatile redolog '%s'", redolog_temp));
-                return -1;
-        }
-        if (redolog->create(filedes, REDOLOG_SUBTYPE_VOLATILE, size) < 0)
-        {
-                BX_PANIC(("Can't create volatile redolog '%s'", redolog_temp));
-                return -1;
-        }
-        
-#if (!defined(WIN32)) && !BX_WITH_MACOS
-        // on unix it is legal to delete an open file
-        unlink(redolog_temp);
-#endif
-
-        BX_INFO(("'volatile' disk opened: ro-file is '%s', redolog is '%s'", pathname, redolog_temp));
-
-        return 0;
-}
-
-void volatile_image_t::close ()
-{
-        redolog->close();
-        ro_disk->close();
-
-#if defined(WIN32) || BX_WITH_MACOS
-        // on non-unix we have to wait till the file is closed to delete it
-        unlink(redolog_temp);
-#endif
-        if (redolog_temp!=NULL)
-          free(redolog_temp);
-
-        if (redolog_name!=NULL)
-          free(redolog_name);
-}
-
-off_t volatile_image_t::lseek (off_t offset, int whence)
-{
-      redolog->lseek(offset, whence);
-      return ro_disk->lseek(offset, whence);
-}
-
-ssize_t volatile_image_t::read (void* buf, size_t count)
-{
-      // This should be fixed if count != 512
-      if ((size_t)redolog->read((char*) buf, count) != count)
-              return ro_disk->read((char*) buf, count);
-      else 
-              return count;
-}
-
-ssize_t volatile_image_t::write (const void* buf, size_t count)
-{
-      return redolog->write((char*) buf, count);
-}
-
-#if BX_COMPRESSED_HD_SUPPORT
-
-/*** z_ro_image_t function definitions ***/
-
-z_ro_image_t::z_ro_image_t()
-{
-        offset = (off_t)0;
-}
-
-int z_ro_image_t::open (const char* pathname)
-{
-        fd = ::open(pathname, O_RDONLY
-#ifdef O_BINARY
-                 | O_BINARY
-#endif
-           );
-
-        if(fd < 0)
-        {
-              BX_PANIC(("Could not open '%s' file", pathname));
-              return fd;
-        }
-
-        gzfile = gzdopen(fd, "rb");
-}
-
-void z_ro_image_t::close ()
-{
-        if (fd > -1) {
-            gzclose(gzfile);
-           // ::close(fd);
-        }
-}
-
-off_t z_ro_image_t::lseek (off_t _offset, int whence)
-{
-        // Only SEEK_SET supported
-        if (whence != SEEK_SET)
-        {
-              BX_PANIC(("lseek on compressed images : only SEEK_SET supported"));
-        }
-
-        // Seeking is expensive on compressed files, so we do it
-        // only when necessary, at the latest moment
-        offset = _offset;
-
-        return offset;
-}
-
-ssize_t z_ro_image_t::read (void* buf, size_t count)
-{
-      gzseek(gzfile, offset, SEEK_SET);
-      return gzread(gzfile, buf, count);
-}
-
-ssize_t z_ro_image_t::write (const void* buf, size_t count)
-{
-      BX_PANIC(("z_ro_image: write not supported"));
-      return 0;
-}
-
-
-/*** z_undoable_image_t function definitions ***/
-
-z_undoable_image_t::z_undoable_image_t(Bit64u _size, const char* _redolog_name)
-{
-        redolog = new redolog_t();
-        ro_disk = new z_ro_image_t();
-        size = _size;
-
-        redolog_name = NULL;
-        if (_redolog_name != NULL) {
-          if (strcmp(_redolog_name,"") != 0) {
-            redolog_name = strdup(_redolog_name);
-          }
-        }
-}
-
-int z_undoable_image_t::open (const char* pathname)
-{
-        char *logname=NULL;
-
-        if (ro_disk->open(pathname)<0)
-                return -1;
-
-        // If redolog name was set 
-        if ( redolog_name != NULL) {
-                if ( strcmp(redolog_name, "") != 0) {
-                        logname = (char*)malloc(strlen(redolog_name) + 1);
-                        strcpy (logname, redolog_name);
-                }
-        }
-
-        // Otherwise we make up the redolog filename from the pathname
-        if ( logname == NULL) {
-                logname = (char*)malloc(strlen(pathname) + UNDOABLE_REDOLOG_EXTENSION_LENGTH + 1);
-                sprintf (logname, "%s%s", pathname, UNDOABLE_REDOLOG_EXTENSION);
-        }
-
-        if (redolog->open(logname,REDOLOG_SUBTYPE_UNDOABLE,size) < 0)
-        {
-                if (redolog->create(logname, REDOLOG_SUBTYPE_UNDOABLE, size) < 0)
-                {
-                        BX_PANIC(("Can't open or create redolog '%s'",logname));
-                        return -1;
-                }
-        }
-
-        BX_INFO(("'z-undoable' disk opened, z-ro-file is '%s', redolog is '%s'", pathname, logname));
-        free(logname);
-
-        return 0;
-}
-
-void z_undoable_image_t::close ()
-{
-        redolog->close();
-        ro_disk->close();
-
-        if (redolog_name!=NULL)
-          free(redolog_name);
-}
-
-off_t z_undoable_image_t::lseek (off_t offset, int whence)
-{
-      redolog->lseek(offset, whence);
-      return ro_disk->lseek(offset, whence);
-}
-
-ssize_t z_undoable_image_t::read (void* buf, size_t count)
-{
-      // This should be fixed if count != 512
-      if (redolog->read((char*) buf, count) != count)
-              return ro_disk->read((char*) buf, count);
-      else 
-              return count;
-}
-
-ssize_t z_undoable_image_t::write (const void* buf, size_t count)
-{
-      return redolog->write((char*) buf, count);
-}
-
-
-/*** z_volatile_image_t function definitions ***/
-
-z_volatile_image_t::z_volatile_image_t(Bit64u _size, const char* _redolog_name)
-{
-        redolog = new redolog_t();
-        ro_disk = new z_ro_image_t();
-        size = _size;
-
-        redolog_temp = NULL;
-        redolog_name = NULL;
-        if (_redolog_name != NULL) {
-          if (strcmp(_redolog_name,"") != 0) {
-            redolog_name = strdup(_redolog_name);
-          }
-        }
-}
-
-int z_volatile_image_t::open (const char* pathname)
-{
-        int filedes;
-        const char *logname=NULL;
-
-        if (ro_disk->open(pathname)<0)
-                return -1;
-
-        // if redolog name was set 
-        if ( redolog_name != NULL) {
-                if ( strcmp(redolog_name, "") !=0 ) {
-                        logname = redolog_name;
-                }
-        }
-
-        // otherwise use pathname as template
-        if (logname == NULL) {
-                logname = pathname;
-        }
-
-        redolog_temp = (char*)malloc(strlen(logname) + VOLATILE_REDOLOG_EXTENSION_LENGTH + 1);
-        sprintf (redolog_temp, "%s%s", logname, VOLATILE_REDOLOG_EXTENSION);
-
-        filedes = mkstemp (redolog_temp);
-
-        if (filedes < 0)
-        {
-                BX_PANIC(("Can't create volatile redolog '%s'", redolog_temp));
-                return -1;
-        }
-        if (redolog->create(filedes, REDOLOG_SUBTYPE_VOLATILE, size) < 0)
-        {
-                BX_PANIC(("Can't create volatile redolog '%s'", redolog_temp));
-                return -1;
-        }
-        
-#if (!defined(WIN32)) && !BX_WITH_MACOS
-        // on unix it is legal to delete an open file
-        unlink(redolog_temp);
-#endif
-
-        BX_INFO(("'z-volatile' disk opened: z-ro-file is '%s', redolog is '%s'", pathname, redolog_temp));
-
-        return 0;
-}
-
-void z_volatile_image_t::close ()
-{
-        redolog->close();
-        ro_disk->close();
-
-#if defined(WIN32) || BX_WITH_MACOS
-        // on non-unix we have to wait till the file is closed to delete it
-        unlink(redolog_temp);
-#endif
-
-        if (redolog_temp!=NULL)
-          free(redolog_temp);
-
-        if (redolog_name!=NULL)
-          free(redolog_name);
-}
-
-off_t z_volatile_image_t::lseek (off_t offset, int whence)
-{
-      redolog->lseek(offset, whence);
-      return ro_disk->lseek(offset, whence);
-}
-
-ssize_t z_volatile_image_t::read (void* buf, size_t count)
-{
-      // This should be fixed if count != 512
-      if (redolog->read((char*) buf, count) != count)
-              return ro_disk->read((char*) buf, count);
-      else 
-              return count;
-}
-
-ssize_t z_volatile_image_t::write (const void* buf, size_t count)
-{
-      return redolog->write((char*) buf, count);
-}
-
-
-#endif
diff --git a/tools/ioemu/iodev/harddrv.h b/tools/ioemu/iodev/harddrv.h
deleted file mode 100644 (file)
index 9320e61..0000000
+++ /dev/null
@@ -1,765 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: harddrv.h,v 1.22.2.1 2004/02/06 22:14:36 danielg4 Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-// SPARSE IMAGES HEADER
-#define SPARSE_HEADER_MAGIC  (0x02468ace)
-#define SPARSE_HEADER_VERSION  1
-#define SPARSE_HEADER_SIZE        (256) // Plenty of room for later
-#define SPARSE_PAGE_NOT_ALLOCATED (0xffffffff)
-
- typedef struct
- {
-   uint32  magic;
-   uint32  version;
-   uint32  pagesize;
-   uint32  numpages;
-
-   uint32  padding[60];
- } sparse_header_t;
-
-#define STANDARD_HEADER_MAGIC     "Bochs Virtual HD Image"
-#define STANDARD_HEADER_VERSION   (0x00010000)
-#define STANDARD_HEADER_SIZE      (512)
-
-
- // WARNING : headers are kept in x86 (little) endianness
- typedef struct
- {
-   Bit8u   magic[32];
-   Bit8u   type[16];
-   Bit8u   subtype[16];
-   Bit32u  version;
-   Bit32u  header;
- } standard_header_t;
-
-#define REDOLOG_TYPE "Redolog"
-#define REDOLOG_SUBTYPE_UNDOABLE "Undoable"
-#define REDOLOG_SUBTYPE_VOLATILE "Volatile"
-#define REDOLOG_SUBTYPE_GROWING  "Growing"
-// #define REDOLOG_SUBTYPE_Z_UNDOABLE "z-Undoable"
-// #define REDOLOG_SUBTYPE_Z_VOLATILE "z-Volatile"
-
-#define REDOLOG_PAGE_NOT_ALLOCATED (0xffffffff)
-
-#define UNDOABLE_REDOLOG_EXTENSION ".redolog"
-#define UNDOABLE_REDOLOG_EXTENSION_LENGTH (strlen(UNDOABLE_REDOLOG_EXTENSION))
-#define VOLATILE_REDOLOG_EXTENSION ".XXXXXX"
-#define VOLATILE_REDOLOG_EXTENSION_LENGTH (strlen(VOLATILE_REDOLOG_EXTENSION))
-
- typedef struct
- {
-   // the fields in the header are kept in little endian
-   Bit32u  catalog;    // #entries in the catalog
-   Bit32u  bitmap;     // bitmap size in bytes
-   Bit32u  extent;     // extent size in bytes
-   Bit64u  disk;       // disk size in bytes
- } redolog_specific_header_t;
-
- typedef struct
- {
-   standard_header_t standard;
-   redolog_specific_header_t specific;
-
-   Bit8u padding[STANDARD_HEADER_SIZE - (sizeof (standard_header_t) + sizeof (redolog_specific_header_t))];
- } redolog_header_t;
-
-// htod : convert host to disk (little) endianness
-// dtoh : convert disk (little) to host endianness
-#if defined (BX_LITTLE_ENDIAN)
-#define htod32(val) (val)
-#define dtoh32(val) (val)
-#define htod64(val) (val)
-#define dtoh64(val) (val)
-#else
-#define htod32(val) ( (((val)&0xff000000)>>24) | (((val)&0xff0000)>>8) | (((val)&0xff00)<<8) | (((val)&0xff)<<24) )
-#define dtoh32(val) htod32(val)
-#define htod64(val) ( (((val)&0xff00000000000000LL)>>56) | (((val)&0xff000000000000LL)>>40) | (((val)&0xff0000000000LL)>>24) | (((val)&0xff00000000LL)>>8) | (((val)&0xff000000LL)<<8) | (((val)&0xff0000LL)<<24) | (((val)&0xff00LL)<<40) | (((val)&0xffLL)<<56) )
-#define dtoh64(val) htod64(val)
-#endif
-
-#ifndef INCLUDE_ONLY_HD_HEADERS
-
-typedef enum _sense {
-      SENSE_NONE = 0, SENSE_NOT_READY = 2, SENSE_ILLEGAL_REQUEST = 5,
-      SENSE_UNIT_ATTENTION = 6
-} sense_t;
-
-typedef enum _asc {
-      ASC_INV_FIELD_IN_CMD_PACKET = 0x24,
-      ASC_MEDIUM_NOT_PRESENT = 0x3a,
-      ASC_SAVING_PARAMETERS_NOT_SUPPORTED = 0x39,
-      ASC_LOGICAL_BLOCK_OOR = 0x21
-} asc_t;
-
-class LOWLEVEL_CDROM;
-
-class device_image_t
-{
-  public:
-      // Open a image. Returns non-negative if successful.
-      virtual int open (const char* pathname) = 0;
-
-      // Close the image.
-      virtual void close () = 0;
-
-      // Position ourselves. Return the resulting offset from the
-      // beginning of the file.
-      virtual off_t lseek (off_t offset, int whence) = 0;
-
-      // Read count bytes to the buffer buf. Return the number of
-      // bytes read (count).
-      virtual ssize_t read (void* buf, size_t count) = 0;
-
-      // Write count bytes from buf. Return the number of bytes
-      // written (count).
-      virtual ssize_t write (const void* buf, size_t count) = 0;
-
-      unsigned cylinders;
-      unsigned heads;
-      unsigned sectors;
-};
-
-// FLAT MODE
-class default_image_t : public device_image_t
-{
-  public:
-      // Open a image. Returns non-negative if successful.
-      int open (const char* pathname);
-
-      // Open an image with specific flags. Returns non-negative if successful.
-      int open (const char* pathname, int flags);
-
-      // Close the image.
-      void close ();
-
-      // Position ourselves. Return the resulting offset from the
-      // beginning of the file.
-      off_t lseek (off_t offset, int whence);
-
-      // Read count bytes to the buffer buf. Return the number of
-      // bytes read (count).
-      ssize_t read (void* buf, size_t count);
-
-      // Write count bytes from buf. Return the number of bytes
-      // written (count).
-      ssize_t write (const void* buf, size_t count);
-
-  private:
-      int fd;
-
-};
-
-// CONCAT MODE
-class concat_image_t : public device_image_t
-{
-  public:
-      // Default constructor
-      concat_image_t();
-      
-      // Open a image. Returns non-negative if successful.
-      int open (const char* pathname);
-
-      // Close the image.
-      void close ();
-
-      // Position ourselves. Return the resulting offset from the
-      // beginning of the file.
-      off_t lseek (off_t offset, int whence);
-
-      // Read count bytes to the buffer buf. Return the number of
-      // bytes read (count).
-      ssize_t read (void* buf, size_t count);
-
-      // Write count bytes from buf. Return the number of bytes
-      // written (count).
-      ssize_t write (const void* buf, size_t count);
-
-  private:
-#define BX_CONCAT_MAX_IMAGES 8
-      int fd_table[BX_CONCAT_MAX_IMAGES];
-      off_t start_offset_table[BX_CONCAT_MAX_IMAGES];
-      off_t length_table[BX_CONCAT_MAX_IMAGES];
-      void increment_string (char *str);
-      int maxfd;  // number of entries in tables that are valid
-
-      // notice if anyone does sequential read or write without seek in between.
-      // This can be supported pretty easily, but needs additional checks.
-      // 0=something other than seek was last operation
-      // 1=seek was last operation
-      int seek_was_last_op;
-
-      // the following variables tell which partial image file to use for
-      // the next read and write.
-      int index;  // index into table
-      int fd;     // fd to use for reads and writes
-      off_t thismin, thismax; // byte offset boundary of this image
-};
-
-// SPARSE MODE
-class sparse_image_t : public device_image_t
-{
-
-// Format of a sparse file:
-// 256 byte header, containing details such as page size and number of pages
-// Page indirection table, mapping virtual pages to physical pages within file
-// Physical pages till end of file
-
-  public:
-      // Default constructor
-      sparse_image_t();
-
-      // Open a image. Returns non-negative if successful.
-      int open (const char* pathname);
-
-      // Close the image.
-      void close ();
-
-      // Position ourselves. Return the resulting offset from the
-      // beginning of the file.
-      off_t lseek (off_t offset, int whence);
-
-      // Read count bytes to the buffer buf. Return the number of
-      // bytes read (count).
-      ssize_t read (void* buf, size_t count);
-
-      // Write count bytes from buf. Return the number of bytes
-      // written (count).
-      ssize_t write (const void* buf, size_t count);
-
-  private:
- int fd;
-
-#ifdef _POSIX_MAPPED_FILES
- void *  mmap_header;
- size_t  mmap_length;
- size_t  system_pagesize_mask;
-#endif
- uint32 *  pagetable;
-
- // Header is written to disk in little-endian (x86) format
- // Thus needs to be converted on big-endian systems before read
- // The pagetable is also kept little endian
-
- sparse_header_t header;
-
- uint32  pagesize;
- int     pagesize_shift;
- uint32  pagesize_mask;
-
- off_t   data_start;
- off_t   underlying_filesize;
-
- char *  pathname;
-
- off_t position;
-
- uint32 position_virtual_page;
- uint32 position_physical_page;
- uint32 position_page_offset;
-
- off_t underlying_current_filepos;
-
- off_t total_size;
-
- void panic(const char * message);
- off_t
-#ifndef PARANOID
-       sparse_image_t::
-#endif
-                       get_physical_offset();
- void
-#ifndef PARANOID
-       sparse_image_t::
-#endif
-                       set_virtual_page(uint32 new_virtual_page);
- void read_header();
- ssize_t read_page_fragment(uint32 read_virtual_page, uint32 read_page_offset, size_t read_size, void * buf);
-
- sparse_image_t *  parent_image;
-};
-
-#if EXTERNAL_DISK_SIMULATOR
-#include "external-disk-simulator.h"
-#endif
-
-#if DLL_HD_SUPPORT
-class dll_image_t : public device_image_t
-{
-  public:
-      // Open a image. Returns non-negative if successful.
-      int open (const char* pathname);
-
-      // Close the image.
-      void close ();
-
-      // Position ourselves. Return the resulting offset from the
-      // beginning of the file.
-      off_t lseek (off_t offset, int whence);
-
-      // Read count bytes to the buffer buf. Return the number of
-      // bytes read (count).
-      ssize_t read (void* buf, size_t count);
-
-      // Write count bytes from buf. Return the number of bytes
-      // written (count).
-      ssize_t write (const void* buf, size_t count);
-
-  private:
-      int vunit,vblk;
-
-};
-#endif
-
-// REDOLOG class
-class redolog_t 
-{
-  public:
-      redolog_t();
-      int make_header (const char* type, Bit64u size);
-      int create (const char* filename, const char* type, Bit64u size);
-      int create (int filedes, const char* type, Bit64u size);
-      int open (const char* filename, const char* type, Bit64u size);
-      void close ();
-
-      off_t lseek (off_t offset, int whence);
-      ssize_t read (void* buf, size_t count);
-      ssize_t write (const void* buf, size_t count);
-
-  private:
-      void             print_header();
-      int              fd;
-      redolog_header_t header;     // Header is kept in x86 (little) endianness
-      Bit32u          *catalog;
-      Bit8u           *bitmap;
-      Bit32u           extent_index;
-      Bit32u           extent_offset;
-      Bit32u           extent_next;
-
-      Bit32u           bitmap_blocs;
-      Bit32u           extent_blocs;
-};
-
-// GROWING MODE
-class growing_image_t : public device_image_t
-{
-  public:
-      // Contructor
-      growing_image_t(Bit64u size);
-
-      // Open a image. Returns non-negative if successful.
-      int open (const char* pathname);
-
-      // Close the image.
-      void close ();
-
-      // Position ourselves. Return the resulting offset from the
-      // beginning of the file.
-      off_t lseek (off_t offset, int whence);
-
-      // Read count bytes to the buffer buf. Return the number of
-      // bytes read (count).
-      ssize_t read (void* buf, size_t count);
-
-      // Write count bytes from buf. Return the number of bytes
-      // written (count).
-      ssize_t write (const void* buf, size_t count);
-
-  private:
-      redolog_t *redolog;
-      Bit64u    size;
-};
-
-// UNDOABLE MODE
-class undoable_image_t : public device_image_t
-{
-  public:
-      // Contructor
-      undoable_image_t(Bit64u size, const char* redolog_name);
-
-      // Open a image. Returns non-negative if successful.
-      int open (const char* pathname);
-
-      // Close the image.
-      void close ();
-
-      // Position ourselves. Return the resulting offset from the
-      // beginning of the file.
-      off_t lseek (off_t offset, int whence);
-
-      // Read count bytes to the buffer buf. Return the number of
-      // bytes read (count).
-      ssize_t read (void* buf, size_t count);
-
-      // Write count bytes from buf. Return the number of bytes
-      // written (count).
-      ssize_t write (const void* buf, size_t count);
-
-  private:
-      redolog_t       *redolog;       // Redolog instance
-      default_image_t *ro_disk;       // Read-only flat disk instance
-      Bit64u          size;           
-      char            *redolog_name;  // Redolog name
-};
-
-
-// VOLATILE MODE
-class volatile_image_t : public device_image_t
-{
-  public:
-      // Contructor
-      volatile_image_t(Bit64u size, const char* redolog_name);
-
-      // Open a image. Returns non-negative if successful.
-      int open (const char* pathname);
-
-      // Close the image.
-      void close ();
-
-      // Position ourselves. Return the resulting offset from the
-      // beginning of the file.
-      off_t lseek (off_t offset, int whence);
-
-      // Read count bytes to the buffer buf. Return the number of
-      // bytes read (count).
-      ssize_t read (void* buf, size_t count);
-
-      // Write count bytes from buf. Return the number of bytes
-      // written (count).
-      ssize_t write (const void* buf, size_t count);
-
-  private:
-      redolog_t       *redolog;       // Redolog instance
-      default_image_t *ro_disk;       // Read-only flat disk instance
-      Bit64u          size;           
-      char            *redolog_name;  // Redolog name
-      char            *redolog_temp;  // Redolog temporary file name
-};
-
-
-#if BX_COMPRESSED_HD_SUPPORT
-
-#include <zlib.h>
-
-
-// Default compressed READ-ONLY image class
-class z_ro_image_t : public device_image_t
-{
-  public:
-      // Contructor
-      z_ro_image_t();
-
-      // Open a image. Returns non-negative if successful.
-      int open (const char* pathname);
-
-      // Close the image.
-      void close ();
-
-      // Position ourselves. Return the resulting offset from the
-      // beginning of the file.
-      off_t lseek (off_t offset, int whence);
-
-      // Read count bytes to the buffer buf. Return the number of
-      // bytes read (count).
-      ssize_t read (void* buf, size_t count);
-
-      // Write count bytes from buf. Return the number of bytes
-      // written (count).
-      ssize_t write (const void* buf, size_t count);
-
-  private:
-      off_t offset;
-      int fd;
-      gzFile gzfile;
-
-};
-
-// Z-UNDOABLE MODE
-class z_undoable_image_t : public device_image_t
-{
-  public:
-      // Contructor
-      z_undoable_image_t(Bit64u size, const char* redolog_name);
-
-      // Open a image. Returns non-negative if successful.
-      int open (const char* pathname);
-
-      // Close the image.
-      void close ();
-
-      // Position ourselves. Return the resulting offset from the
-      // beginning of the file.
-      off_t lseek (off_t offset, int whence);
-
-      // Read count bytes to the buffer buf. Return the number of
-      // bytes read (count).
-      ssize_t read (void* buf, size_t count);
-
-      // Write count bytes from buf. Return the number of bytes
-      // written (count).
-      ssize_t write (const void* buf, size_t count);
-
-  private:
-      redolog_t       *redolog;       // Redolog instance
-      z_ro_image_t    *ro_disk;       // Read-only compressed flat disk instance
-      Bit64u          size;           
-      char            *redolog_name;  // Redolog name
-};
-
-// Z-VOLATILE MODE
-class z_volatile_image_t : public device_image_t
-{
-  public:
-      // Contructor
-      z_volatile_image_t(Bit64u size, const char* redolog_name);
-
-      // Open a image. Returns non-negative if successful.
-      int open (const char* pathname);
-
-      // Close the image.
-      void close ();
-
-      // Position ourselves. Return the resulting offset from the
-      // beginning of the file.
-      off_t lseek (off_t offset, int whence);
-
-      // Read count bytes to the buffer buf. Return the number of
-      // bytes read (count).
-      ssize_t read (void* buf, size_t count);
-
-      // Write count bytes from buf. Return the number of bytes
-      // written (count).
-      ssize_t write (const void* buf, size_t count);
-
-  private:
-      redolog_t       *redolog;       // Redolog instance
-      z_ro_image_t    *ro_disk;       // Read-only compressed flat disk instance
-      Bit64u          size;           
-      char            *redolog_name;  // Redolog name
-      char            *redolog_temp;  // Redolog temporary file name
-};
-
-#endif
-
-
-typedef struct {
-  struct {
-    bx_bool busy;
-    bx_bool drive_ready;
-    bx_bool write_fault;
-    bx_bool seek_complete;
-    bx_bool drq;
-    bx_bool corrected_data;
-    bx_bool index_pulse;
-    unsigned index_pulse_count;
-    bx_bool err;
-    } status;
-  Bit8u    error_register;
-  Bit8u    head_no;
-  union {
-    Bit8u    sector_count;
-    struct {
-#ifdef BX_LITTLE_ENDIAN
-      unsigned c_d : 1;
-      unsigned i_o : 1;
-      unsigned rel : 1;
-      unsigned tag : 5;
-#else  /* BX_BIG_ENDIAN */
-      unsigned tag : 5;
-      unsigned rel : 1;
-      unsigned i_o : 1;
-      unsigned c_d : 1;
-#endif
-    } interrupt_reason;
-  };
-  Bit8u    sector_no;
-  union {
-    Bit16u   cylinder_no;
-    Bit16u   byte_count;
-  };
-  Bit8u    buffer[2048];
-  Bit32u   buffer_index;
-  Bit32u   drq_index;
-  Bit8u    current_command;
-  Bit8u    sectors_per_block;
-  Bit8u    lba_mode;
-  struct {
-    bx_bool reset;       // 0=normal, 1=reset controller
-    bx_bool disable_irq; // 0=allow irq, 1=disable irq
-    } control;
-  Bit8u    reset_in_progress;
-  Bit8u    features;
-  } controller_t;
-
-struct sense_info_t {
-  sense_t sense_key;
-  struct {
-    Bit8u arr[4];
-  } information;
-  struct {
-    Bit8u arr[4];
-  } specific_inf;
-  struct {
-    Bit8u arr[3];
-  } key_spec;
-  Bit8u fruc;
-  Bit8u asc;
-  Bit8u ascq;
-};
-
-struct error_recovery_t {
-  unsigned char data[8];
-
-  error_recovery_t ();
-};
-
-uint16 read_16bit(const uint8* buf) BX_CPP_AttrRegparmN(1);
-uint32 read_32bit(const uint8* buf) BX_CPP_AttrRegparmN(1);
-
-
-#ifdef LOWLEVEL_CDROM
-#  include "cdrom.h"
-#endif
-
-
-struct cdrom_t
-{
-  bx_bool ready;
-  bx_bool locked;
-#ifdef LOWLEVEL_CDROM
-  LOWLEVEL_CDROM* cd;
-#endif
-  uint32 capacity;
-  int next_lba;
-  int remaining_blocks;
-  struct currentStruct {
-    error_recovery_t error_recovery;
-  } current;
-};
-
-struct atapi_t
-{
-  uint8 command;
-  int drq_bytes;
-  int total_bytes_remaining;
-};
-
-#if BX_USE_HD_SMF
-#  define BX_HD_SMF  static
-#  define BX_HD_THIS theHardDrive->
-#else
-#  define BX_HD_SMF
-#  define BX_HD_THIS this->
-#endif
-
-typedef enum {
-      IDE_NONE, IDE_DISK, IDE_CDROM
-} device_type_t;
-
-class bx_hard_drive_c : public bx_hard_drive_stub_c {
-public:
-
-  bx_hard_drive_c(void);
-  virtual ~bx_hard_drive_c(void);
-  virtual void   close_harddrive(void);
-  virtual void   init();
-  virtual void   reset(unsigned type);
-  virtual Bit32u   get_device_handle(Bit8u channel, Bit8u device);
-  virtual Bit32u   get_first_cd_handle(void);
-  virtual unsigned get_cd_media_status(Bit32u handle);
-  virtual unsigned set_cd_media_status(Bit32u handle, unsigned status);
-
-  virtual Bit32u virt_read_handler(Bit32u address, unsigned io_len) {
-    return read_handler (this, address, io_len);
-  }
-  virtual void virt_write_handler(Bit32u address, 
-      Bit32u value, unsigned io_len)
-  {
-    write_handler(this, address, value, io_len);
-  }
-#if !BX_USE_HD_SMF
-  Bit32u read(Bit32u address, unsigned io_len);
-  void   write(Bit32u address, Bit32u value, unsigned io_len);
-#endif
-
-  static Bit32u read_handler(void *this_ptr, Bit32u address, unsigned io_len);
-  static void   write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);
-
-private:
-
-  BX_HD_SMF bx_bool calculate_logical_address(Bit8u channel, off_t *sector) BX_CPP_AttrRegparmN(2);
-  BX_HD_SMF void increment_address(Bit8u channel) BX_CPP_AttrRegparmN(1);
-  BX_HD_SMF void identify_drive(Bit8u channel);
-  BX_HD_SMF void identify_ATAPI_drive(Bit8u channel);
-  BX_HD_SMF void command_aborted(Bit8u channel, unsigned command);
-
-  BX_HD_SMF void init_send_atapi_command(Bit8u channel, Bit8u command, int req_length, int alloc_length, bool lazy = false) BX_CPP_AttrRegparmN(3);
-  BX_HD_SMF void ready_to_send_atapi(Bit8u channel) BX_CPP_AttrRegparmN(1);
-  BX_HD_SMF void raise_interrupt(Bit8u channel) BX_CPP_AttrRegparmN(1);
-  BX_HD_SMF void atapi_cmd_error(Bit8u channel, sense_t sense_key, asc_t asc);
-  BX_HD_SMF void init_mode_sense_single(Bit8u channel, const void* src, int size);
-  BX_HD_SMF void atapi_cmd_nop(Bit8u channel) BX_CPP_AttrRegparmN(1);
-
-  // FIXME:
-  // For each ATA channel we should have one controller struct
-  // and an array of two drive structs
-  struct channel_t {
-    struct drive_t {
-      device_image_t* hard_drive;
-      device_type_t device_type;
-      // 512 byte buffer for ID drive command
-      // These words are stored in native word endian format, as
-      // they are fetched and returned via a return(), so
-      // there's no need to keep them in x86 endian format.
-      Bit16u id_drive[256];
-
-      controller_t controller;
-      cdrom_t cdrom;
-      sense_info_t sense;
-      atapi_t atapi;
-
-      Bit8u model_no[41];
-      } drives[2];
-    unsigned drive_select;
-
-    Bit16u ioaddr1;
-    Bit16u ioaddr2;
-    Bit8u  irq;
-
-    } channels[BX_MAX_ATA_CHANNEL];
-
-#if BX_PDC20230C_VLBIDE_SUPPORT
-// pdc20630c is only available for 1st ata channel
-  struct pdc20630c_t {
-    bx_bool prog_mode;
-    Bit8u   prog_count;
-    Bit32u  p1f3_value;
-    Bit32u  p1f4_value;
-    } pdc20230c;
-#endif
-
-  };
-#endif // INCLUDE_ONLY_SPARSE_HEADER
-
diff --git a/tools/ioemu/iodev/ioapic.cc b/tools/ioemu/iodev/ioapic.cc
deleted file mode 100644 (file)
index 8aaf67f..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: ioapic.cc,v 1.11 2002/11/19 05:47:45 bdenney Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-#include <stdio.h>
-#include  "bochs.h"
-#if BX_SUPPORT_APIC
-
-class bx_ioapic_c bx_ioapic;
-#define LOG_THIS  bx_ioapic.
-
-void
-bx_io_redirect_entry_t::parse_value ()
-{
-  dest = (value >> 56) & 0xff;
-  masked = (value >> 16) & 1;
-  trig_mode = (value >> 15) & 1;
-  remote_irr = (value >> 14) & 1;
-  polarity = (value >> 13) & 1;
-  //delivery_status = (value >> 12) & 1;
-  delivery_status = 0;  // always say the message has gone through
-  dest_mode = (value >> 11) & 1;
-  delivery_mode = (value >> 8) & 7;
-  vector = (value >> 0) & 0xff;
-}
-
-void
-bx_io_redirect_entry_t::sprintf_self (char *buf)
-{
-  sprintf (buf, "dest=%02x, masked=%d, trig_mode=%d, remote_irr=%d, polarity=%d, delivery_status=%d, dest_mode=%d, delivery_mode=%d, vector=%02x", dest, masked, trig_mode, remote_irr, polarity, delivery_status, dest_mode, delivery_mode, vector);
-}
-
-bx_ioapic_c::bx_ioapic_c () 
-  : bx_generic_apic_c ()
-{
-  put("IOAP");
-  settype(IOAPICLOG);
-}
-
-bx_ioapic_c::~bx_ioapic_c () {
-}
-
-void 
-bx_ioapic_c::init () 
-{
-  bx_generic_apic_c::init ();
-  BX_DEBUG(("initializing I/O APIC"));
-  base_addr = 0xfec00000;
-  ioregsel = 0;
-  // all interrupts masked
-  for (int i=0; i<BX_IOAPIC_NUM_PINS; i++) {
-    ioredtbl[i].set_even_word (0x00010000);
-    ioredtbl[i].set_odd_word  (0x00000000);
-  }
-  irr = 0;
-}
-
-void 
-bx_ioapic_c::reset (unsigned type) 
-{
-}
-
-void 
-bx_ioapic_c::read_aligned(Bit32u address, Bit32u *data, unsigned len)
-{
-  BX_DEBUG( ("I/O APIC read_aligned addr=%08x, len=%d", address, len));
-  BX_ASSERT (len == 4);
-  address &= 0xff;
-  if (address == 0x00) {
-    // select register
-    *data = ioregsel;
-    return;
-  } else if (address != 0x10) {
-      BX_PANIC(("IOAPIC: read from unsupported address"));
-  }
-  // only reached when reading data register
-  switch (ioregsel) {
-  case 0x00:  // APIC ID
-    *data = ((id & 0xf) << 24);
-    return;
-  case 0x01:  // version
-    *data = (((BX_IOAPIC_NUM_PINS-1) & 0xff) << 16) 
-            | (BX_IOAPIC_VERSION_ID & 0x0f);
-    return;
-  case 0x02:
-    BX_INFO(("IOAPIC: arbitration ID unsupported, returned 0"));
-    *data = 0;
-    return;
-  default:
-    int index = (ioregsel - 0x10) >> 1;
-    if (index >= 0 && index < BX_IOAPIC_NUM_PINS) {
-      bx_io_redirect_entry_t *entry = ioredtbl + index;
-      *data = (ioregsel&1) ? entry->get_odd_word() : entry->get_even_word ();
-      return;
-    }
-    BX_PANIC(("IOAPIC: IOREGSEL points to undefined register %02x", ioregsel));
-  }
-}
-
-void 
-bx_ioapic_c::write(Bit32u address, Bit32u *value, unsigned len)
-{
-  BX_DEBUG(("IOAPIC: write addr=%08x, data=%08x, len=%d", address, *value, len));
-  address &= 0xff;
-  if (address == 0x00)  {
-    ioregsel = *value;
-    return;
-  } else if (address != 0x10) {
-    BX_PANIC(("IOAPIC: write to unsupported address"));
-  }
-  // only reached when writing data register
-  switch (ioregsel) {
-    case 0x00: // set APIC ID
-      {
-       Bit8u newid = (*value >> 24) & 0xf;
-       BX_INFO(("IOAPIC: setting id to 0x%x", newid));
-       set_id (newid);
-       return;
-      }
-    case 0x01: // version
-    case 0x02: // arbitration id
-      BX_INFO(("IOAPIC: could not write, IOREGSEL=0x%02x", ioregsel));
-      return;
-    default:
-      int index = (ioregsel - 0x10) >> 1;
-      if (index >= 0 && index < BX_IOAPIC_NUM_PINS) {
-       bx_io_redirect_entry_t *entry = ioredtbl + index;
-       if (ioregsel&1) 
-         entry->set_odd_word (*value);
-       else 
-         entry->set_even_word (*value);
-       char buf[1024];
-       entry->sprintf_self (buf);
-       BX_DEBUG(("IOAPIC: now entry[%d] is %s", index, buf));
-       service_ioapic ();
-       return;
-      }
-      BX_PANIC(("IOAPIC: IOREGSEL points to undefined register %02x", ioregsel));
-  }
-}
-
-void bx_ioapic_c::trigger_irq (unsigned vector, unsigned from) 
-{
-  BX_DEBUG(("IOAPIC: received interrupt %d", vector));
-  if (vector >= 0 && vector < BX_IOAPIC_NUM_PINS) {
-    Bit32u bit = 1<<vector;
-    if ((irr & bit) == 0) {
-      irr |= bit;
-      service_ioapic ();
-    }
-  } else BX_PANIC(("IOAPIC: vector %d out of range", vector));
-}
-
-void bx_ioapic_c::untrigger_irq (unsigned num, unsigned from) 
-{
-  BX_DEBUG(("IOAPIC: interrupt %d went away", num));
-}
-
-void bx_ioapic_c::service_ioapic ()
-{
-  // look in IRR and deliver any interrupts that are not masked.
-  BX_DEBUG(("IOAPIC: servicing"));
-  for (unsigned bit=0; bit < BX_IOAPIC_NUM_PINS; bit++) {
-    if (irr & (1<<bit)) {
-      bx_io_redirect_entry_t *entry = ioredtbl + bit;
-      if (!entry->masked) {
-       // clear irr bit and deliver
-       bx_bool done = deliver (entry->dest, entry->dest_mode, entry->delivery_mode, entry->vector, entry->polarity, entry->trig_mode);
-       if (done) irr &= ~(1<<bit);
-      }
-    }
-  }
-}
-
-#endif /* if BX_SUPPORT_APIC */
diff --git a/tools/ioemu/iodev/ioapic.h b/tools/ioemu/iodev/ioapic.h
deleted file mode 100644 (file)
index be008f0..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: ioapic.h,v 1.5 2002/10/25 11:44:40 bdenney Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-extern class bx_ioapic_c bx_ioapic;
-
-#define BX_IOAPIC_VERSION_ID 0x00170011  // same version as 82093 IOAPIC
-#define BX_IOAPIC_NUM_PINS 0x18
-
-class bx_io_redirect_entry_t {
-  Bit64u value;
-public:
-  Bit32u get_even_word () { return value & 0xffffffff; }
-  Bit32u get_odd_word () { return (value>>32) & 0xffffffff; }
-  void set_even_word (Bit32u even) {
-    // keep high 32 bits of value, replace low 32
-    value = ((value >> 32) << 32) | (even & 0xffffffff);
-    parse_value ();
-  }
-  void set_odd_word (Bit32u odd) { 
-    // keep low 32 bits of value, replace high 32
-    value = (((Bit64u)odd & 0xffffffff) << 32) | (value & 0xffffffff);
-    parse_value ();
-  }
-  void parse_value ();
-  // parse_value sets the value and all the fields below.  Do not change
-  // these fields except by calling parse_value.
-  Bit8u dest, masked, trig_mode, remote_irr, polarity, delivery_status, dest_mode, delivery_mode, vector;
-  void sprintf_self (char *buf);
-};
-
-class bx_ioapic_c : public bx_generic_apic_c {
-  Bit32u ioregsel;    // selects between various registers
-  // interrupt request bitmask, not visible from the outside.  Bits in the
-  // irr are set when trigger_irq is called, and cleared when the interrupt
-  // is delivered to the processor.  If an interrupt is masked, the irr
-  // will still be set but delivery will not occur until it is unmasked.
-  // It's not clear if this is how the real device works.
-  Bit32u irr;
-public:
-  bx_io_redirect_entry_t ioredtbl[BX_IOAPIC_NUM_PINS];  // table of redirections
-  bx_ioapic_c ();
-  ~bx_ioapic_c ();
-  virtual void init ();
-  virtual void reset (unsigned type);
-  virtual void read_aligned(Bit32u address, Bit32u *data, unsigned len);
-  virtual void write(Bit32u address, Bit32u *value, unsigned len);
-  void trigger_irq (unsigned num, unsigned from);
-  void untrigger_irq (unsigned num, unsigned from);
-  void service_ioapic ();
-  virtual bx_bool match_logical_addr (Bit8u address) { return false; }
-  virtual bx_bool is_local_apic () { return false; }
-  virtual bx_apic_type_t get_type () { return APIC_TYPE_IOAPIC; }
-};
diff --git a/tools/ioemu/iodev/iodebug.cc b/tools/ioemu/iodev/iodebug.cc
deleted file mode 100644 (file)
index ca2314e..0000000
+++ /dev/null
@@ -1,354 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: iodebug.cc,v 1.15 2002/11/19 05:47:45 bdenney Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-#include "bochs.h"
-#if BX_IODEBUG_SUPPORT
-
-
-
-bx_iodebug_c bx_iodebug;
-bx_iodebug_c *bx_iodebug_ptr;
-
-  struct bx_iodebug_s_type {
-    bx_bool enabled;
-    unsigned int register_select;
-    Bit32u registers[2];
-    Bit32u monitored_mem_areas_start[BX_IODEBUG_MAX_AREAS];
-    Bit32u monitored_mem_areas_end[BX_IODEBUG_MAX_AREAS];
-  } bx_iodebug_s;
-
-
-
-
-// Constructor
-bx_iodebug_c::bx_iodebug_c( void )
-{
-  put("IODEBUG");
-  settype(IODEBUGLOG);
-
-}
-
-
-
-
-
-// Destructor
-bx_iodebug_c::~bx_iodebug_c( void )
-{
-}
-
-
-
-
-
-void bx_iodebug_c::init(void)
-{
-  int i;
-
-  DEV_register_ioread_handler(this, read_handler, 0x8A00,"BOCHS IODEBUG", 7);
-  DEV_register_iowrite_handler(this, write_handler, 0x8A00,"BOCHS IODEBUG", 7);
-  DEV_register_iowrite_handler(this, write_handler, 0x8A01,"BOCHS IODEBUG", 7);
-//  fprintf( stderr, "IODEBUG initialized\n");
-
-  bx_iodebug_s.enabled = 0;
-  bx_iodebug_s.register_select = 0;
-  for(i=0;i<BX_IODEBUG_MAX_AREAS;i++) {
-    bx_iodebug_s.monitored_mem_areas_start[i] = 0;
-    bx_iodebug_s.monitored_mem_areas_end[i] = 0;
-  }
-}
-
-void bx_iodebug_c::reset(unsigned type)
-{
-}
-
-
-Bit32u bx_iodebug_c::read_handler(void *this_ptr, Bit32u addr, unsigned io_len)
-{
-  bx_iodebug_ptr = (bx_iodebug_c *) this_ptr;
-  return( bx_iodebug_ptr->read(addr, io_len) );
-}
-
-
-
-
-
-
-Bit32u bx_iodebug_c::read( Bit32u addr, unsigned io_len )
-{
-
-  if(bx_iodebug_s.enabled) return(0x8A00);
-  return(0);
-}
-
-
-
-
-
-
-
-
-
-
-void bx_iodebug_c::write_handler(void *this_ptr, Bit32u addr, Bit32u dvalue, unsigned io_len)
-{
-  bx_iodebug_c *class_ptr = (bx_iodebug_c *) this_ptr;
-  class_ptr->write( addr, dvalue, io_len );
-}
-
-
-
-
-
-
-void bx_iodebug_c::write( Bit32u addr, Bit32u dvalue, unsigned int io_len )
-{
-
-
-//  fprintf(stderr, "IODEBUG addr: %4x\tdvalue: %8x\tio_len: %8x\n", (unsigned int)addr, (unsigned int)dvalue, io_len);
-
-  if( addr == 0x8A01 && io_len == 2 )
-  {
-      bx_iodebug_s.registers[bx_iodebug_s.register_select] =
-        (bx_iodebug_s.registers[bx_iodebug_s.register_select] << 16) +
-       (dvalue & 0x0000FFFF );
-  }
-
-  if( (addr != 0x8A00) || (io_len != 2) ) return;
-
-  if( !bx_iodebug_s.enabled )
-  {
-    if( dvalue == 0x8A00 )
-    {
-      bx_iodebug_s.enabled = 1;
-//      fprintf(stderr, "IODEBUG enabled\n");
-      bx_iodebug_s.registers[0] = 0;
-      bx_iodebug_s.registers[1] = 0;
-    }
-    return;
-  }
-
-  switch( dvalue )
-  {
-    case( 0x8A01 ):
-      bx_iodebug_s.register_select = 0;
-//      fprintf( stderr, "IODEBUG register 0 selected\n");
-      break;
-
-    case( 0x8A02 ):
-      bx_iodebug_s.register_select = 1;
-//      fprintf( stderr, "IODEBUG register 1 selected\n");
-      break;
-
-    case( 0x8A80 ):
-      bx_iodebug_s.register_select = 0;
-      bx_iodebug_c::add_range(
-          bx_iodebug_s.registers[0],
-         bx_iodebug_s.registers[1]);
-      bx_iodebug_s.registers[0] = 0;
-      bx_iodebug_s.registers[1] = 0;
-      break;
-
-#if BX_DEBUGGER
-    case( 0x8AE0 ):
-      fprintf( stderr, "request return to dbg prompt received, 0x8AE0 command (iodebug)\n");
-      bx_guard.interrupt_requested=1;
-      break;
-
-    case( 0x8AE2):
-      fprintf( stderr, "request made by the guest os to disable tracing, iodebug port 0x8A00->0x8AE2\n");
-      BX_CPU(dbg_cpu)->trace = 0;
-      break;
-
-    case( 0x8AE3 ):
-      fprintf( stderr, "request made by the guest os to enable tracing, iodebug port 0x8A00->0x8AE3\n");
-      BX_CPU(dbg_cpu)->trace = 1;
-      break;
-
-    case( 0x8AE4 ):
-      fprintf( stderr, "request made by the guest os to disable register tracing, iodebug port 0x8A00->0x8AE4\n");
-      BX_CPU(dbg_cpu)->trace_reg = 0;
-      break;
-
-    case( 0x8AE5 ):
-      fprintf( stderr, "request made by the guest os to enable register tracing, iodebug port 0x8A00->0x8AE5\n");
-      BX_CPU(dbg_cpu)->trace_reg = 1;
-      break;
-
-#endif
-
-    case( 0x8AFF ):
-      bx_iodebug_s.enabled = 0;
-//      fprintf( stderr, "IODEBUG device deactivated\n");
-//      break;
-
-//    default:
-//      fprintf(stderr,"IODEBUG unsupported register code\n");
-  }
-}
-
-
-
-
-
-
-
-
-// Static function
-void bx_iodebug_c::mem_write( BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data)
-{
-  Bit32u data32;
-  Bit16u data16;
-  Bit8u  data8;
-
-  unsigned int area;
-  if( !bx_iodebug_s.enabled ) return;
-
-  area = bx_iodebug_c::range_test( addr, len );
-  // Device is enabled, testing address ranges
-  if( area )
-  {
-    area--;
-#if BX_DEBUGGER
-  fprintf( stdout, "%s @ eip: %08X wrote at monitored memory location %8X\n", cpu->name, cpu->get_EIP(), addr);
-  bx_guard.interrupt_requested=1;
-#else
-    fprintf( stderr,
-             "IODEBUG write to monitored memory area: %2i\tby EIP:\t\t%08X\n\trange start: \t\t%08X\trange end:\t%08X\n\taddress accessed:\t%08X\tdata written:\t",
-            area,
-            cpu->get_EIP(),
-            bx_iodebug_s.monitored_mem_areas_start[area],
-            bx_iodebug_s.monitored_mem_areas_end[area],
-            (unsigned int)addr);
-
-    data32 = * (Bit32u *)data;
-    data16 = (Bit16u)data32;
-    data8  = (Bit8u)data32;
-
-    switch(len)
-    {
-      case(1):
-        fprintf(stderr,"%02X\n", (unsigned int)data8);
-       break;
-
-      case(2):
-        fprintf(stderr,"%04X\n", (unsigned int)data16);
-       break;
-
-      case(4):
-        fprintf(stderr,"%08X\n", (unsigned int)data32);
-       break;
-
-      default:
-        fprintf(stderr, "unsupported write size\n");
-    }
-#endif
-  }
-}
-
-
-
-
-
-
-
-
-void bx_iodebug_c::mem_read( BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data)
-{
-  Bit32u data32;
-  Bit16u data16;
-  Bit8u  data8;
-
-  unsigned int area;
-  if( !bx_iodebug_s.enabled ) return;
-
-  area = bx_iodebug_c::range_test( addr, len );
-  // Device is enabled, testing address ranges
-  if( area )
-  {
-    area--;
-#if BX_DEBUGGER
-  fprintf( stdout, "%s @ eip: %8X wrote at monitored memory location %8X\n", cpu->name, cpu->get_EIP(), addr);
-  bx_guard.interrupt_requested=1;
-#else
-    fprintf( stderr,
-             "IODEBUG read to monitored memory area: %2i\tby EIP:\t\t%08X\n\trange start: \t\t%08X\trange end:\t%08X\n\taddress accessed:\t%08X\tdata written:\t",
-            area,
-            cpu->get_EIP(),
-            bx_iodebug_s.monitored_mem_areas_start[area],
-            bx_iodebug_s.monitored_mem_areas_end[area],
-            (unsigned int)addr);
-    data32 = * (Bit32u *)data;
-    data16 = (Bit16u)data32;
-    data8  = (Bit8u)data32;
-
-    switch(len)
-    {
-      case(1):
-        fprintf(stderr,"%02X\n", (unsigned int)data8);
-       break;
-
-      case(2):
-        fprintf(stderr,"%04X\n", (unsigned int)data16);
-       break;
-
-      case(4):
-        fprintf(stderr,"%08X\n", (unsigned int)data32);
-       break;
-
-      default:
-        fprintf(stderr, "unsupported write size\n");
-    }
-#endif
-  }
-}
-
-
-
-
-
-
-
-unsigned int bx_iodebug_c::range_test( Bit32u addr, unsigned int len )
-{
-  unsigned int i;
-
-  for(i=0;i<BX_IODEBUG_MAX_AREAS;i++)
-  {
-    if( (bx_iodebug_s.monitored_mem_areas_start[i]!=0) ||
-        (bx_iodebug_s.monitored_mem_areas_end[i]!=0) )
-    {
-      if( (Bit32u)(addr+len-1) < bx_iodebug_s.monitored_mem_areas_start[i] )
-        continue;
-      if( addr < bx_iodebug_s.monitored_mem_areas_end[i] )
-      {
-        return(++i);
-      }
-    }  
-  }
-  return(0);
-}
-
-
-
-
-
-
-void bx_iodebug_c::add_range( Bit32u addr_start, Bit32u addr_end )
-{
-  unsigned int i;
-  for(i=0;i<BX_IODEBUG_MAX_AREAS;i++)
-  {
-    if( !bx_iodebug_s.monitored_mem_areas_start[i] &&
-        !bx_iodebug_s.monitored_mem_areas_end[i] )
-    {
-       bx_iodebug_s.monitored_mem_areas_start[i] = addr_start;
-       bx_iodebug_s.monitored_mem_areas_end[i] = addr_end;
-//     fprintf(stderr, "IODEBUG added range successfully in slot: %i\n",i);
-       return;
-    }
-  }
-//  fprintf(stderr, "IODEBUG unable to register memory range, all slots taken\n");
-}
-#endif /* if BX_IODEBUG_SUPPORT */
diff --git a/tools/ioemu/iodev/iodebug.h b/tools/ioemu/iodev/iodebug.h
deleted file mode 100644 (file)
index a31f7cf..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: iodebug.h,v 1.7 2002/10/26 03:53:22 bdenney Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-#ifndef _BX_IODEBUG_H
-#define _BX_IODEBUG_H
-
-#include "config.h"
-
-#define BX_IODEBUG_THIS this->
-
-#define BX_IODEBUG_MAX_AREAS   30
-
-class bx_iodebug_c : public bx_devmodel_c
-{
-public:
-  bx_iodebug_c( void );
-  ~bx_iodebug_c( void );
-  virtual void init(void);
-  virtual void reset (unsigned type);
-  static void mem_write( BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data);
-  static void mem_read( BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data);
-
-private:
-  static Bit32u read_handler(void *this_ptr, Bit32u address, unsigned io_len);
-  static void write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);
-  Bit32u read(Bit32u addr, unsigned int io_len);
-  void write(Bit32u addr, Bit32u dvalue, unsigned int io_len);
-  static unsigned int range_test(Bit32u addr, unsigned int len);
-  static void add_range( Bit32u addr_start, Bit32u addr_end);
-
-};
-
-extern bx_iodebug_c bx_iodebug;
-#endif
diff --git a/tools/ioemu/iodev/iodev.h b/tools/ioemu/iodev/iodev.h
deleted file mode 100644 (file)
index 3057f6c..0000000
+++ /dev/null
@@ -1,422 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: iodev.h,v 1.37 2003/08/04 16:03:09 akrisak Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-
-/* maximum number of emulated devices allowed.  floppy, vga, etc...
-   you can increase this to anything below 256 since an 8-bit handle
-   is used for each device */
-#define BX_MAX_IO_DEVICES 30
-
-/* the last device in the array is the "default" I/O device */
-#define BX_DEFAULT_IO_DEVICE   (BX_MAX_IO_DEVICES-1)
-
-/* number of IRQ lines supported.  In an ISA PC there are two
-   PIC chips cascaded together.  each has 8 IRQ lines, so there
-   should be 16 IRQ's total */
-#define BX_MAX_IRQS 16
-#define BX_NO_IRQ  -1
-
-
-class bx_pit_c;
-class bx_keyb_c;
-class bx_ioapic_c;
-class bx_g2h_c;
-#if BX_IODEBUG_SUPPORT
-class bx_iodebug_c;
-#endif
-
-
-
-typedef Bit32u (*bx_read_handler_t)(void *, Bit32u, unsigned);
-typedef void   (*bx_write_handler_t)(void *, Bit32u, Bit32u, unsigned);
-
-
-#if BX_USE_DEV_SMF
-#  define BX_DEV_SMF  static
-#  define BX_DEV_THIS bx_devices.
-#else
-#  define BX_DEV_SMF
-#  define BX_DEV_THIS this->
-#endif
-
-//////////////////////////////////////////////////////////////////////
-// bx_devmodel_c declaration
-//////////////////////////////////////////////////////////////////////
-
-// This class defines virtual methods that are common to all devices. 
-// Child classes do not need to implement all of them, because in this 
-// definition they are defined as empty, as opposed to being pure 
-// virtual (= 0).
-class BOCHSAPI bx_devmodel_c : public logfunctions {
-  public:
-  virtual ~bx_devmodel_c () {}
-  virtual void init_mem(BX_MEM_C *) {}
-  virtual void init(void) {}
-  virtual void reset(unsigned type) {}
-  virtual void device_load_state () {}
-  virtual void device_save_state () {}
-};
-
-//////////////////////////////////////////////////////////////////////
-// declare stubs for devices
-//////////////////////////////////////////////////////////////////////
-
-#define STUBFUNC(dev,method) \
-   pluginlog->panic("%s called in %s stub. you must not have loaded the %s plugin", #dev, #method, #dev )
-
-class BOCHSAPI bx_keyb_stub_c : public bx_devmodel_c {
-  public:
-  virtual ~bx_keyb_stub_c () {}
-  // stubs for bx_keyb_c methods
-  virtual void mouse_motion(int delta_x, int delta_y, unsigned button_state) {
-    STUBFUNC(keyboard, mouse_motion);
-  }
-  virtual void gen_scancode(Bit32u key) {
-    STUBFUNC(keyboard, gen_scancode);
-  }
-  virtual void paste_bytes(Bit8u *data, Bit32s length) {
-    STUBFUNC(keyboard, paste_bytes);
-  }
-  virtual void paste_delay_changed () {
-    STUBFUNC(keyboard, paste_delay_changed);
-  }
-  virtual void mouse_enabled_changed(bool enabled) {
-    STUBFUNC(keyboard, mouse_enabled_changed);
-  }
-};
-
-class BOCHSAPI bx_hard_drive_stub_c : public bx_devmodel_c {
-  public:
-  virtual void   close_harddrive(void) {
-    STUBFUNC(HD, close_harddrive);
-  }
-  virtual void   init() {
-    STUBFUNC(HD, init);
-  }
-  virtual void   reset(unsigned type) {
-    STUBFUNC(HD, reset);
-  }
-  virtual Bit32u   get_device_handle(Bit8u channel, Bit8u device) {
-    STUBFUNC(HD, get_device_handle); return 0;
-  }
-  virtual Bit32u   get_first_cd_handle(void) {
-    STUBFUNC(HD, get_first_cd_handle); return 0;
-  }
-  virtual unsigned get_cd_media_status(Bit32u handle) {
-    STUBFUNC(HD, get_cd_media_status); return 0;
-  }
-  virtual unsigned set_cd_media_status(Bit32u handle, unsigned status) {
-    STUBFUNC(HD, set_cd_media_status); return 0;
-  }
-  virtual Bit32u virt_read_handler(Bit32u address, unsigned io_len) 
-  {
-    STUBFUNC(HD, virt_read_handler); return 0;
-  }
-  virtual void   virt_write_handler(Bit32u address,
-      Bit32u value, unsigned io_len) 
-  {
-    STUBFUNC(HD, virt_write_handler);
-  }
-};
-
-class BOCHSAPI bx_floppy_stub_c : public bx_devmodel_c {
-  public:
-  virtual unsigned get_media_status(unsigned drive) {
-    STUBFUNC(floppy,  get_media_status); return 0;
-  }
-  virtual unsigned set_media_status(unsigned drive, unsigned status) {
-    STUBFUNC(floppy, set_media_status); return 0;
-  }
-};
-
-class BOCHSAPI bx_cmos_stub_c : public bx_devmodel_c {
-  public:
-  virtual Bit32u get_reg(unsigned reg) {
-    STUBFUNC(cmos, get_reg); return 0;
-  }
-  virtual void set_reg(unsigned reg, Bit32u val) {
-    STUBFUNC(cmos, set_reg);
-  }
-  virtual time_t get_timeval() {
-    // STUBFUNC(cmos, get_timeval); 
-    return 0;
-  }
-  virtual void checksum_cmos(void) {
-    STUBFUNC(cmos, checksum);
-  }
-};
-
-class BOCHSAPI bx_dma_stub_c : public bx_devmodel_c {
-  public:
-  virtual unsigned registerDMA8Channel(
-    unsigned channel,
-    void (* dmaRead)(Bit8u *data_byte),
-    void (* dmaWrite)(Bit8u *data_byte),
-    const char *name
-    ) {
-    STUBFUNC(dma, registerDMA8Channel); return 0;
-  }
-  virtual unsigned registerDMA16Channel(
-    unsigned channel,
-    void (* dmaRead)(Bit16u *data_word),
-    void (* dmaWrite)(Bit16u *data_word),   
-    const char *name
-    ) {
-    STUBFUNC(dma, registerDMA16Channel); return 0;
-  }
-  virtual unsigned unregisterDMAChannel(unsigned channel) {
-    STUBFUNC(dma, unregisterDMAChannel); return 0;
-  }
-  virtual unsigned get_TC(void) {
-    STUBFUNC(dma, get_TC); return 0;
-  }
-  virtual void set_DRQ(unsigned channel, bx_bool val) {
-    STUBFUNC(dma, set_DRQ);
-  }
-  virtual void raise_HLDA(void) {
-    STUBFUNC(dma, raise_HLDA);
-  }
-};
-
-class BOCHSAPI bx_pic_stub_c : public bx_devmodel_c {
-  public:
-  virtual void raise_irq(unsigned irq_no) {
-    STUBFUNC(pic, raise_irq); 
-  }
-  virtual void lower_irq(unsigned irq_no) {
-    STUBFUNC(pic, lower_irq); 
-  }
-  virtual Bit8u IAC(void) {
-    STUBFUNC(pic, IAC); return 0;
-  }
-  virtual void show_pic_state(void) {
-    STUBFUNC(pic, show_pic_state);
-  }
-};
-
-class BOCHSAPI bx_vga_stub_c : public bx_devmodel_c {
-  public:
-  virtual void redraw_area(unsigned x0, unsigned y0, 
-                           unsigned width, unsigned height) {
-    STUBFUNC(vga, redraw_area);  
-  }
-  virtual Bit8u mem_read(Bit32u addr) {
-    STUBFUNC(vga, mem_read);  return 0;
-  }
-  virtual void mem_write(Bit32u addr, Bit8u value) {
-    STUBFUNC(vga, mem_write);
-  }
-  virtual void get_text_snapshot(Bit8u **text_snapshot, 
-                                 unsigned *txHeight, unsigned *txWidth) {
-    STUBFUNC(vga, get_text_snapshot); 
-  }
-  virtual void trigger_timer(void *this_ptr) {
-    STUBFUNC(vga, trigger_timer); 
-  }
-  virtual void set_update_interval (unsigned interval) {
-    STUBFUNC(vga, set_update_interval); 
-  }
-  virtual Bit8u get_actl_palette_idx(Bit8u index) {
-    return 0;
-  }
-};
-
-class BOCHSAPI bx_pci_stub_c : public bx_devmodel_c {
-  public:
-  virtual bx_bool register_pci_handlers(void *this_ptr,
-                                        Bit32u (*bx_pci_read_handler)(void *, Bit8u, unsigned),
-                                        void(*bx_pci_write_handler)(void *, Bit8u, Bit32u, unsigned),
-                                        Bit8u devfunc, const char *name) {
-    STUBFUNC(pci, register_pci_handlers); return 0;
-  }
-  virtual Bit8u rd_memType (Bit32u addr) {
-    return 0;
-  }
-  virtual Bit8u wr_memType (Bit32u addr) {
-    return 0;
-  }
-  virtual void print_i440fx_state(void) {}
-};
-
-class BOCHSAPI bx_ne2k_stub_c : public bx_devmodel_c {
-  public:
-  virtual void print_info(FILE *file, int page, int reg, int nodups) {}
-};
-
-class BOCHSAPI bx_devices_c : public logfunctions {
-public:
-  bx_devices_c(void);
-  ~bx_devices_c(void);
-  // Register I/O addresses and IRQ lines. Initialize any internal
-  // structures.  init() is called only once, even if the simulator
-  // reboots or is restarted.
-  void init(BX_MEM_C *);
-  // Enter reset state in response to a reset condition.
-  // The types of reset conditions are defined in bochs.h:
-  // power-on, hardware, or software.
-  void reset(unsigned type);
-  BX_MEM_C *mem;  // address space associated with these devices
-  bx_bool register_io_read_handler(void *this_ptr, bx_read_handler_t f, Bit32u addr, const char *name, Bit8u mask );
-  bx_bool register_io_write_handler(void *this_ptr, bx_write_handler_t f, Bit32u addr, const char *name, Bit8u mask );
-  bx_bool register_default_io_read_handler(void *this_ptr, bx_read_handler_t f, const char *name, Bit8u mask );
-  bx_bool register_default_io_write_handler(void *this_ptr, bx_write_handler_t f, const char *name, Bit8u mask );
-  bx_bool register_irq(unsigned irq, const char *name);
-  bx_bool unregister_irq(unsigned irq, const char *name);
-  void iodev_init(void);
-  Bit32u inp(Bit16u addr, unsigned io_len) BX_CPP_AttrRegparmN(2);
-  void   outp(Bit16u addr, Bit32u value, unsigned io_len) BX_CPP_AttrRegparmN(3);
-
-  static void timer_handler(void *);
-  void timer(void);
-
-  bx_devmodel_c    *pluginBiosDevice;
-  bx_ioapic_c      *ioapic;
-  bx_pci_stub_c    *pluginPciBridge;
-  bx_devmodel_c    *pluginPci2IsaBridge;
-  bx_devmodel_c    *pluginPciVgaAdapter;
-  bx_devmodel_c    *pluginPciUSBAdapter;
-  bx_pit_c         *pit;
-  bx_keyb_stub_c   *pluginKeyboard;
-  bx_dma_stub_c    *pluginDmaDevice;
-  bx_floppy_stub_c *pluginFloppyDevice;
-  bx_cmos_stub_c   *pluginCmosDevice;
-  bx_devmodel_c    *pluginSerialDevice;
-  bx_devmodel_c    *pluginParallelDevice;
-  bx_devmodel_c    *pluginUnmapped;
-  bx_vga_stub_c    *pluginVgaDevice;
-  bx_pic_stub_c    *pluginPicDevice;
-  bx_hard_drive_stub_c *pluginHardDrive;
-  bx_devmodel_c    *pluginSB16Device;
-  bx_ne2k_stub_c   *pluginNE2kDevice;
-  bx_g2h_c         *g2h;
-  bx_devmodel_c    *pluginExtFpuIrq;
-  bx_devmodel_c    *pluginGameport;
-#if BX_IODEBUG_SUPPORT
-  bx_iodebug_c    *iodebug;
-#endif
-
-  // stub classes that the pointers (above) can point to until a plugin is
-  // loaded
-  bx_cmos_stub_c stubCmos;
-  bx_keyb_stub_c stubKeyboard;
-  bx_hard_drive_stub_c stubHardDrive;
-  bx_dma_stub_c  stubDma;
-  bx_pic_stub_c  stubPic;
-  bx_floppy_stub_c  stubFloppy;
-  bx_vga_stub_c  stubVga;
-  bx_pci_stub_c  stubPci;
-  bx_ne2k_stub_c stubNE2k;
-
-  // Some info to pass to devices which can handled bulk IO.  This allows
-  // the interface to remain the same for IO devices which can't handle
-  // bulk IO.  We should probably implement special INPBulk() and OUTBulk()
-  // functions which stick these values in the bx_devices_c class, and
-  // then call the normal functions rather than having gross globals
-  // variables.
-  Bit32u   bulkIOHostAddr;
-  unsigned bulkIOQuantumsRequested;
-  unsigned bulkIOQuantumsTransferred;
-
-private:
-
-  Bit8u                 read_handler_id[0x10000];  // 64K
-  struct {
-    bx_read_handler_t funct;
-    void             *this_ptr;
-    const char       *handler_name;  // name of device
-    Bit8u             mask;          // io_len mask
-    } io_read_handler[BX_MAX_IO_DEVICES];
-  unsigned              num_read_handles;
-
-  Bit8u                 write_handler_id[0x10000]; // 64K
-  struct {
-    bx_write_handler_t funct;
-    void              *this_ptr;
-    const char        *handler_name;  // name of device
-    Bit8u              mask;          // io_len mask
-    } io_write_handler[BX_MAX_IO_DEVICES];
-  unsigned              num_write_handles;
-
-  // more for informative purposes, the names of the devices which
-  // are use each of the IRQ 0..15 lines are stored here
-  const char *irq_handler_name[BX_MAX_IRQS];
-
-  static Bit32u read_handler(void *this_ptr, Bit32u address, unsigned io_len);
-  static void   write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);
-  BX_DEV_SMF Bit32u port92_read(Bit32u address, unsigned io_len);
-  BX_DEV_SMF void   port92_write(Bit32u address, Bit32u value, unsigned io_len);
-
-  static Bit32u default_read_handler(void *this_ptr, Bit32u address, unsigned io_len);
-  static void   default_write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);
-
-  int timer_handle;
-  bx_bool is_serial_enabled ();
-  bx_bool is_usb_enabled ();
-  bx_bool is_parallel_enabled ();
-  };
-
-
-
-#if BX_PCI_SUPPORT
-#include "iodev/pci.h"
-#include "iodev/pci2isa.h"
-#if BX_PCI_VGA_SUPPORT
-#include "iodev/pcivga.h"
-#endif
-#if BX_PCI_USB_SUPPORT
-#include "iodev/pciusb.h"
-#endif
-#endif
-#include "iodev/vga.h"
-#if BX_SUPPORT_APIC
-#  include "iodev/ioapic.h"
-#endif
-#include "iodev/biosdev.h"
-#include "iodev/cmos.h"
-#include "iodev/dma.h"
-#include "iodev/floppy.h"
-#include "iodev/harddrv.h"
-#if BX_IODEBUG_SUPPORT
-#   include "iodev/iodebug.h"
-#endif
-#include "iodev/keyboard.h"
-#include "iodev/parallel.h"
-#include "iodev/pic.h"
-#include "iodev/pit.h"
-#include "iodev/pit_wrap.h"
-#include "iodev/virt_timer.h"
-#include "iodev/serial.h"
-#if BX_SUPPORT_SB16
-#  include "iodev/sb16.h"
-#endif
-#include "iodev/unmapped.h"
-#include "iodev/eth.h"
-#include "iodev/ne2k.h"
-#include "iodev/guest2host.h"
-#include "iodev/slowdown_timer.h"
-#include "iodev/extfpuirq.h"
-#include "iodev/gameport.h"
diff --git a/tools/ioemu/iodev/keyboard.cc b/tools/ioemu/iodev/keyboard.cc
deleted file mode 100644 (file)
index 693f4a4..0000000
+++ /dev/null
@@ -1,1611 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: keyboard.cc,v 1.82 2003/11/11 18:18:36 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-// Now features proper implementation of keyboard opcodes 0xF4 to 0xF6
-// Silently ignores PS/2 keyboard extensions (0xF7 to 0xFD)
-// Explicit panic on resend (0xFE)
-//
-// Emmanuel Marty <core@ggi-project.org>
-
-// NB: now the PS/2 mouse support is in, outb changes meaning
-// in conjunction with auxb
-// auxb == 0 && outb == 0  => both buffers empty (nothing to read)
-// auxb == 0 && outb == 1  => keyboard controller output buffer full
-// auxb == 1 && outb == 0  => not used
-// auxb == 1 && outb == 1  => mouse output buffer full.
-// (das)
-
-// Notes from Christophe Bothamy <cbbochs@free.fr>
-//
-// This file includes code from Ludovic Lange (http://ludovic.lange.free.fr)
-// Implementation of 3 scancodes sets mf1,mf2,mf3 with or without translation. 
-// Default is mf2 with translation
-// Ability to switch between scancodes sets
-// Ability to turn translation on or off
-
-// Define BX_PLUGGABLE in files that can be compiled into plugins.  For
-// platforms that require a special tag on exported symbols, BX_PLUGGABLE 
-// is used to know when we are exporting symbols and when we are importing.
-#define BX_PLUGGABLE
-
-#include "bochs.h"
-#include <math.h>
-#include "scancodes.h"
-
-#define LOG_THIS  theKeyboard->
-#define VERBOSE_KBD_DEBUG 0
-
-
-bx_keyb_c *theKeyboard = NULL;
-
-  int
-libkeyboard_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
-{
-  // Create one instance of the keyboard device object.
-  theKeyboard = new bx_keyb_c ();
-  // Before this plugin was loaded, pluginKeyboard pointed to a stub.
-  // Now make it point to the real thing.
-  bx_devices.pluginKeyboard = theKeyboard;
-  // Register this device.
-  BX_REGISTER_DEVICE_DEVMODEL (plugin, type, theKeyboard, BX_PLUGIN_KEYBOARD);
-  return(0); // Success
-}
-
-  void
-libkeyboard_LTX_plugin_fini(void)
-{
-  BX_INFO (("keyboard plugin_fini"));
-}
-
-bx_keyb_c::bx_keyb_c(void)
-{
-  // constructor
-  put("KBD");
-  settype(KBDLOG);
-}
-
-bx_keyb_c::~bx_keyb_c(void)
-{
-  // destructor
-  BX_DEBUG(("Exit."));
-}
-
-
-// flush internal buffer and reset keyboard settings to power-up condition
-  void
-bx_keyb_c::resetinternals(bx_bool powerup)
-{
-  Bit32u   i;
-
-  BX_KEY_THIS s.kbd_internal_buffer.num_elements = 0;
-  for (i=0; i<BX_KBD_ELEMENTS; i++)
-    BX_KEY_THIS s.kbd_internal_buffer.buffer[i] = 0;
-  BX_KEY_THIS s.kbd_internal_buffer.head = 0;
-
-  BX_KEY_THIS s.kbd_internal_buffer.expecting_typematic = 0;
-
-  // Default scancode set is mf2 with translation
-  BX_KEY_THIS s.kbd_controller.expecting_scancodes_set = 0;
-  BX_KEY_THIS s.kbd_controller.current_scancodes_set = 1;
-  BX_KEY_THIS s.kbd_controller.scancodes_translate = 1;
-  
-  if (powerup) {
-    BX_KEY_THIS s.kbd_internal_buffer.expecting_led_write = 0;
-    BX_KEY_THIS s.kbd_internal_buffer.delay = 1; // 500 mS
-    BX_KEY_THIS s.kbd_internal_buffer.repeat_rate = 0x0b; // 10.9 chars/sec
-    }
-}
-
-
-
-  void
-bx_keyb_c::init(void)
-{
-  BX_DEBUG(("Init $Id: keyboard.cc,v 1.82 2003/11/11 18:18:36 vruppert Exp $"));
-  Bit32u   i;
-
-  DEV_register_irq(1, "8042 Keyboard controller");
-  DEV_register_irq(12, "8042 Keyboard controller (PS/2 mouse)");
-
-  DEV_register_ioread_handler(this, read_handler,
-                                      0x0060, "8042 Keyboard controller", 1);
-  DEV_register_ioread_handler(this, read_handler,
-                                      0x0064, "8042 Keyboard controller", 1);
-  DEV_register_iowrite_handler(this, write_handler,
-                                      0x0060, "8042 Keyboard controller", 1);
-  DEV_register_iowrite_handler(this, write_handler,
-                                      0x0064, "8042 Keyboard controller", 1);
-  BX_KEY_THIS timer_handle = bx_pc_system.register_timer( this, timer_handler,
-                                 bx_options.Okeyboard_serial_delay->get(), 1, 1,
-                                "8042 Keyboard controller");
-
-  resetinternals(1);
-
-  BX_KEY_THIS s.kbd_internal_buffer.led_status = 0;
-  BX_KEY_THIS s.kbd_internal_buffer.scanning_enabled = 1;
-
-  BX_KEY_THIS s.mouse_internal_buffer.num_elements = 0;
-  for (i=0; i<BX_MOUSE_BUFF_SIZE; i++)
-    BX_KEY_THIS s.mouse_internal_buffer.buffer[i] = 0;
-  BX_KEY_THIS s.mouse_internal_buffer.head = 0;
-
-  //  BX_INFO(("kbd: %04d outb 0 auxb 0",__LINE__)); // das
-  BX_KEY_THIS s.kbd_controller.pare = 0;
-  BX_KEY_THIS s.kbd_controller.tim  = 0;
-  BX_KEY_THIS s.kbd_controller.auxb = 0;
-  BX_KEY_THIS s.kbd_controller.keyl = 1;
-  BX_KEY_THIS s.kbd_controller.c_d  = 1;
-  BX_KEY_THIS s.kbd_controller.sysf = 0;
-  BX_KEY_THIS s.kbd_controller.inpb = 0;
-  BX_KEY_THIS s.kbd_controller.outb = 0;
-
-  BX_KEY_THIS s.kbd_controller.kbd_clock_enabled = 1;
-  BX_KEY_THIS s.kbd_controller.aux_clock_enabled = 0;
-  BX_KEY_THIS s.kbd_controller.allow_irq1 = 1;
-  BX_KEY_THIS s.kbd_controller.allow_irq12 = 1;
-  BX_KEY_THIS s.kbd_controller.kbd_output_buffer = 0;
-  BX_KEY_THIS s.kbd_controller.aux_output_buffer = 0;
-  BX_KEY_THIS s.kbd_controller.last_comm = 0;
-  BX_KEY_THIS s.kbd_controller.expecting_port60h = 0;
-  BX_KEY_THIS s.kbd_controller.irq1_requested = 0;
-  BX_KEY_THIS s.kbd_controller.irq12_requested = 0;
-  BX_KEY_THIS s.kbd_controller.expecting_mouse_parameter = 0;
-
-//BX_DEBUG(( "# Okeyboard_serial_delay is %u usec",
-//        (unsigned) bx_options.Okeyboard_serial_delay->get ()));
-  BX_KEY_THIS s.kbd_controller.timer_pending = 0;
-
-  // Mouse initialization stuff
-  BX_KEY_THIS s.mouse.sample_rate     = 100; // reports per second
-  BX_KEY_THIS s.mouse.resolution_cpmm = 4;   // 4 counts per millimeter
-  BX_KEY_THIS s.mouse.scaling         = 1;   /* 1:1 (default) */
-  BX_KEY_THIS s.mouse.mode            = MOUSE_MODE_RESET;
-  BX_KEY_THIS s.mouse.enable          = 0;
-  BX_KEY_THIS s.mouse.delayed_dx      = 0;
-  BX_KEY_THIS s.mouse.delayed_dy      = 0;
-
-  for (i=0; i<BX_KBD_CONTROLLER_QSIZE; i++)
-    BX_KEY_THIS s.controller_Q[i] = 0;
-  BX_KEY_THIS s.controller_Qsize = 0;
-  BX_KEY_THIS s.controller_Qsource = 0;
-
-  // clear paste buffer
-  BX_KEY_THIS pastebuf = NULL;
-  BX_KEY_THIS pastebuf_len = 0;
-  BX_KEY_THIS pastebuf_ptr = 0;
-  BX_KEY_THIS paste_delay_changed ();
-  BX_KEY_THIS stop_paste = 0;
-
-  // mouse port installed on system board
-  DEV_cmos_set_reg(0x14, DEV_cmos_get_reg(0x14) | 0x04);
-
-#if BX_WITH_WX
-  static bx_bool first_time = 1;
-  if (first_time) {
-    first_time = 0;
-    // register shadow params (Experimental, not a complete list by far)
-    bx_list_c *list = new bx_list_c (BXP_KBD_PARAMETERS, "Keyboard State", "", 20);
-    list->add (new bx_shadow_bool_c (BXP_KBD_IRQ1_REQ, 
-         "Keyboard IRQ1 requested: ", "",
-         &BX_KEY_THIS s.kbd_controller.irq1_requested));
-    list->add (new bx_shadow_bool_c (BXP_KBD_IRQ12_REQ,
-         "Keyboard IRQ12 requested: ", "",
-         &BX_KEY_THIS s.kbd_controller.irq12_requested));
-    list->add (new bx_shadow_num_c (BXP_KBD_TIMER_PENDING,
-       "Keyboard timer pending: ", "",
-       &BX_KEY_THIS s.kbd_controller.timer_pending));
-    list->add (new bx_shadow_bool_c (BXP_KBD_PARE,
-       "Keyboard PARE", "",
-       &BX_KEY_THIS s.kbd_controller.pare));
-    list->add (new bx_shadow_bool_c (BXP_KBD_TIM,
-       "Keyboard TIM", "",
-       &BX_KEY_THIS s.kbd_controller.tim));
-    list->add (new bx_shadow_bool_c (BXP_KBD_AUXB,
-       "Keyboard AUXB", "",
-       &BX_KEY_THIS s.kbd_controller.auxb));
-    list->add (new bx_shadow_bool_c (BXP_KBD_KEYL,
-       "Keyboard KEYL", "",
-       &BX_KEY_THIS s.kbd_controller.keyl));
-    list->add (new bx_shadow_bool_c (BXP_KBD_C_D,
-       "Keyboard C_D", "",
-       &BX_KEY_THIS s.kbd_controller.c_d));
-    list->add (new bx_shadow_bool_c (BXP_KBD_SYSF,
-       "Keyboard SYSF", "",
-       &BX_KEY_THIS s.kbd_controller.sysf));
-    list->add (new bx_shadow_bool_c (BXP_KBD_INPB,
-       "Keyboard INPB", "",
-       &BX_KEY_THIS s.kbd_controller.inpb));
-    list->add (new bx_shadow_bool_c (BXP_KBD_OUTB,
-       "Keyboard OUTB", "",
-       &BX_KEY_THIS s.kbd_controller.outb));
-  }
-#endif
-}
-
-  void
-bx_keyb_c::reset(unsigned type)
-{
-  if (BX_KEY_THIS pastebuf != NULL) {
-    BX_KEY_THIS stop_paste = 1;
-  }
-}
-
-  void
-bx_keyb_c::paste_delay_changed()
-{
-  BX_KEY_THIS pastedelay = bx_options.Okeyboard_paste_delay->get()/BX_IODEV_HANDLER_PERIOD;
-  BX_INFO(("will paste characters every %d keyboard ticks",BX_KEY_THIS pastedelay));
-}
-
-  // static IO port read callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-// read function - the big picture:
-// if address == data port then
-//    if byte for mouse then return it
-//    else if byte for keyboard then return it
-// else address== status port
-//    assemble the status bits and return them.
-//
-  Bit32u
-bx_keyb_c::read_handler(void *this_ptr, Bit32u address, unsigned io_len)
-{
-#if !BX_USE_KEY_SMF
-  bx_keyb_c *class_ptr = (bx_keyb_c *) this_ptr;
-
-  return( class_ptr->read(address, io_len) );
-}
-
-
-  Bit32u
-bx_keyb_c::read(Bit32u   address, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif  // !BX_USE_KEY_SMF
-
-//BX_DEBUG(( "read from port 0x%04x", (unsigned) address));
-
-  if (address == 0x60) { /* output buffer */
-    Bit8u   val;
-    if (BX_KEY_THIS s.kbd_controller.auxb) { /* mouse byte available */
-      val = BX_KEY_THIS s.kbd_controller.aux_output_buffer;
-      BX_KEY_THIS s.kbd_controller.aux_output_buffer = 0;
-      //      BX_INFO(("kbd: %04d outb 0 auxb 0",__LINE__)); // das
-      BX_KEY_THIS s.kbd_controller.outb = 0;
-      BX_KEY_THIS s.kbd_controller.auxb = 0;
-      BX_KEY_THIS s.kbd_controller.irq12_requested = 0;
-
-      if (BX_KEY_THIS s.controller_Qsize) {
-        unsigned i;
-        BX_KEY_THIS s.kbd_controller.aux_output_buffer = BX_KEY_THIS s.controller_Q[0];
-       //      BX_INFO(("kbd: %04d outb 1 auxb 1",__LINE__)); // das
-        BX_KEY_THIS s.kbd_controller.outb = 1;
-        BX_KEY_THIS s.kbd_controller.auxb = 1;
-        if (BX_KEY_THIS s.kbd_controller.allow_irq12)
-          BX_KEY_THIS s.kbd_controller.irq12_requested = 1;
-        for (i=0; i<BX_KEY_THIS s.controller_Qsize-1; i++) {
-          // move Q elements towards head of queue by one
-          BX_KEY_THIS s.controller_Q[i] = BX_KEY_THIS s.controller_Q[i+1];
-          }
-        BX_KEY_THIS s.controller_Qsize--;
-        }
-
-//BX_DEBUG(("mouse: ___io_read aux = 0x%02x", (unsigned) val));
-
-      DEV_pic_lower_irq(12);
-      activate_timer();
-      BX_DEBUG(("READ(%02x) (from mouse) = %02x", (unsigned) address,
-          (unsigned) val));
-      return val;
-      }
-    else if (BX_KEY_THIS s.kbd_controller.outb) { /* kbd byte available */
-      val = BX_KEY_THIS s.kbd_controller.kbd_output_buffer;
-      // BX_INFO(("kbd: %04d outb 0 auxb 0",__LINE__)); // das
-      BX_KEY_THIS s.kbd_controller.outb = 0;
-      BX_KEY_THIS s.kbd_controller.auxb = 0;
-      BX_KEY_THIS s.kbd_controller.irq1_requested = 0;
-//BX_DEBUG(( "___io_read kbd"));
-
-      if (BX_KEY_THIS s.controller_Qsize) {
-        unsigned i;
-        BX_KEY_THIS s.kbd_controller.aux_output_buffer = BX_KEY_THIS s.controller_Q[0];
-       //      BX_INFO(("kbd: %04d outb 1 auxb 1",__LINE__)); // das
-        BX_KEY_THIS s.kbd_controller.outb = 1;
-        BX_KEY_THIS s.kbd_controller.auxb = 1;
-        if (BX_KEY_THIS s.kbd_controller.allow_irq1)
-          BX_KEY_THIS s.kbd_controller.irq1_requested = 1;
-        for (i=0; i<BX_KEY_THIS s.controller_Qsize-1; i++) {
-          // move Q elements towards head of queue by one
-          BX_KEY_THIS s.controller_Q[i] = BX_KEY_THIS s.controller_Q[i+1];
-          }
-       BX_DEBUG(("s.controller_Qsize: %02X",BX_KEY_THIS s.controller_Qsize));
-        BX_KEY_THIS s.controller_Qsize--;
-        }
-
-      DEV_pic_lower_irq(1);
-      activate_timer();
-      BX_DEBUG(("READ(%02x) = %02x", (unsigned) address,
-          (unsigned) val));
-      return val;
-      }
-    else {
-        BX_DEBUG(("num_elements = %d", BX_KEY_THIS s.kbd_internal_buffer.num_elements));
-        BX_DEBUG(("read from port 60h with outb empty"));
-//        val = BX_KEY_THIS s.kbd_controller.kbd_output_buffer;
-      return BX_KEY_THIS s.kbd_controller.kbd_output_buffer;
-      }
-    }
-
-#if BX_CPU_LEVEL >= 2
-  else if (address == 0x64) { /* status register */
-
-    return (BX_KEY_THIS s.kbd_controller.pare << 7)  |
-          (BX_KEY_THIS s.kbd_controller.tim  << 6)  |
-          (BX_KEY_THIS s.kbd_controller.auxb << 5)  |
-          (BX_KEY_THIS s.kbd_controller.keyl << 4)  |
-          (BX_KEY_THIS s.kbd_controller.c_d  << 3)  |
-          (BX_KEY_THIS s.kbd_controller.sysf << 2)  |
-          (BX_KEY_THIS s.kbd_controller.inpb << 1)  |
-          BX_KEY_THIS s.kbd_controller.outb;
-    }
-
-#else /* BX_CPU_LEVEL > 0 */
-  /* XT MODE, System 8255 Mode Register */
-  else if (address == 0x64) { /* status register */
-    BX_DEBUG(("IO read from port 64h, system 8255 mode register"));
-    return BX_KEY_THIS s.kbd_controller.outb;
-    }
-#endif /* BX_CPU_LEVEL > 0 */
-
-  BX_PANIC(("unknown address in io read to keyboard port %x",
-      (unsigned) address));
-  return 0; /* keep compiler happy */
-}
-
-
-  // static IO port write callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-  void
-bx_keyb_c::write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len)
-{
-#if !BX_USE_KEY_SMF
-  bx_keyb_c *class_ptr = (bx_keyb_c *) this_ptr;
-
-  class_ptr->write(address, value, io_len);
-}
-
-  void
-bx_keyb_c::write( Bit32u   address, Bit32u   value, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif  // !BX_USE_KEY_SMF
-  Bit8u   command_byte;
-  static int kbd_initialized=0;
-
-  BX_DEBUG(("keyboard: 8-bit write to %04x = %02x", (unsigned)address, (unsigned)value));
-
-  switch (address) {
-    case 0x60: // input buffer
-      // if expecting data byte from command last sent to port 64h
-      if (BX_KEY_THIS s.kbd_controller.expecting_port60h) {
-        BX_KEY_THIS s.kbd_controller.expecting_port60h = 0;
-        // data byte written last to 0x60
-        BX_KEY_THIS s.kbd_controller.c_d = 0;
-        if (BX_KEY_THIS s.kbd_controller.inpb) {
-          BX_PANIC(("write to port 60h, not ready for write"));
-          }
-        switch (BX_KEY_THIS s.kbd_controller.last_comm) {
-          case 0x60: // write command byte
-            {
-            bx_bool scan_convert, disable_keyboard,
-                    disable_aux;
-
-            scan_convert = (value >> 6) & 0x01;
-            disable_aux      = (value >> 5) & 0x01;
-            disable_keyboard = (value >> 4) & 0x01;
-            BX_KEY_THIS s.kbd_controller.sysf = (value >> 2) & 0x01;
-            BX_KEY_THIS s.kbd_controller.allow_irq1  = (value >> 0) & 0x01;
-            BX_KEY_THIS s.kbd_controller.allow_irq12 = (value >> 1) & 0x01;
-            set_kbd_clock_enable(!disable_keyboard);
-            set_aux_clock_enable(!disable_aux);
-            if (BX_KEY_THIS s.kbd_controller.allow_irq12 && BX_KEY_THIS s.kbd_controller.auxb)
-              BX_KEY_THIS s.kbd_controller.irq12_requested = 1;
-            else if (BX_KEY_THIS s.kbd_controller.allow_irq1  && BX_KEY_THIS s.kbd_controller.outb)
-              BX_KEY_THIS s.kbd_controller.irq1_requested = 1;
-
-                       BX_DEBUG(( " allow_irq12 set to %u", (unsigned)
-                               BX_KEY_THIS s.kbd_controller.allow_irq12));
-            if ( !scan_convert )
-              BX_ERROR(("keyboard: (mch) scan convert turned off"));
-
-           // (mch) NT needs this
-           BX_KEY_THIS s.kbd_controller.scancodes_translate = scan_convert;
-            }
-            break;
-          case 0xd1: // write output port
-            BX_DEBUG(("write output port with value %02xh",
-                (unsigned) value));
-            BX_SET_ENABLE_A20( (value & 0x02) != 0 );
-            if (!(value & 0x01))
-                               BX_PANIC(("IO write: processor reset requested!"));
-            break;
-          case 0xd4: // Write to mouse
-            // I don't think this enables the AUX clock
-            //set_aux_clock_enable(1); // enable aux clock line
-            kbd_ctrl_to_mouse(value);
-            // ??? should I reset to previous value of aux enable?
-            break;
-
-          case 0xd3: // write mouse output buffer
-            // Queue in mouse output buffer
-            controller_enQ(value, 1);
-            break;
-
-         case 0xd2:
-           // Queue in keyboard output buffer
-           controller_enQ(value, 0);
-           break;
-
-          default:
-            BX_PANIC(("=== unsupported write to port 60h(lastcomm=%02x): %02x",
-              (unsigned) BX_KEY_THIS s.kbd_controller.last_comm, (unsigned) value));
-          }
-        }
-      else {
-        // data byte written last to 0x60
-        BX_KEY_THIS s.kbd_controller.c_d = 0;
-        BX_KEY_THIS s.kbd_controller.expecting_port60h = 0;
-        /* pass byte to keyboard */
-        /* ??? should conditionally pass to mouse device here ??? */
-        if (BX_KEY_THIS s.kbd_controller.kbd_clock_enabled==0) {
-          BX_ERROR(("keyboard disabled & send of byte %02x to kbd",
-            (unsigned) value));
-          }
-        kbd_ctrl_to_kbd(value);
-        }
-      break;
-
-    case 0x64: // control register
-      // command byte written last to 0x64
-      BX_KEY_THIS s.kbd_controller.c_d = 1;
-      BX_KEY_THIS s.kbd_controller.last_comm = value;
-      // most commands NOT expecting port60 write next
-      BX_KEY_THIS s.kbd_controller.expecting_port60h = 0;
-
-      switch (value) {
-        case 0x20: // get keyboard command byte
-          BX_DEBUG(("get keyboard command byte"));
-          // controller output buffer must be empty
-          if (BX_KEY_THIS s.kbd_controller.outb) {
-                       BX_ERROR(("kbd: OUTB set and command 0x%02x encountered", value));
-            break;
-            }
-          command_byte =
-            (BX_KEY_THIS s.kbd_controller.scancodes_translate << 6) |
-            ((!BX_KEY_THIS s.kbd_controller.aux_clock_enabled) << 5) |
-            ((!BX_KEY_THIS s.kbd_controller.kbd_clock_enabled) << 4) |
-            (0 << 3) |
-            (BX_KEY_THIS s.kbd_controller.sysf << 2) |
-            (BX_KEY_THIS s.kbd_controller.allow_irq12 << 1) |
-            (BX_KEY_THIS s.kbd_controller.allow_irq1  << 0);
-          controller_enQ(command_byte, 0);
-          break;
-        case 0x60: // write command byte
-          BX_DEBUG(("write command byte"));
-          // following byte written to port 60h is command byte
-          BX_KEY_THIS s.kbd_controller.expecting_port60h = 1;
-          break;
-
-        case 0xa0:
-          BX_DEBUG(("keyboard BIOS name not supported"));
-          break;
-
-        case 0xa1:
-          BX_DEBUG(("keyboard BIOS version not supported"));
-          break;
-
-        case 0xa7: // disable the aux device
-          set_aux_clock_enable(0);
-          BX_DEBUG(("aux device disabled"));
-          break;
-        case 0xa8: // enable the aux device
-          set_aux_clock_enable(1);
-          BX_DEBUG(("aux device enabled"));
-          break;
-        case 0xa9: // Test Mouse Port
-          // controller output buffer must be empty
-          if (BX_KEY_THIS s.kbd_controller.outb) {
-                       BX_PANIC(("kbd: OUTB set and command 0x%02x encountered", value));
-            break;
-            }
-          controller_enQ(0x00, 0); // no errors detected
-          break;
-        case 0xaa: // motherboard controller self test
-          BX_DEBUG(("Self Test"));
-         if( kbd_initialized == 0 )
-         {
-           BX_KEY_THIS s.controller_Qsize = 0;
-           BX_KEY_THIS s.kbd_controller.outb = 0;
-           kbd_initialized++;
-         }
-          // controller output buffer must be empty
-          if (BX_KEY_THIS s.kbd_controller.outb) {
-               BX_ERROR(("kbd: OUTB set and command 0x%02x encountered", value));
-            break;
-            }
-         // (mch) Why is this commented out??? Enabling
-          BX_KEY_THIS s.kbd_controller.sysf = 1; // self test complete
-          controller_enQ(0x55, 0); // controller OK
-          break;
-        case 0xab: // Interface Test
-          // controller output buffer must be empty
-          if (BX_KEY_THIS s.kbd_controller.outb) {
-BX_PANIC(("kbd: OUTB set and command 0x%02x encountered", value));
-            break;
-            }
-          controller_enQ(0x00, 0);
-          break;
-        case 0xad: // disable keyboard
-          set_kbd_clock_enable(0);
-          BX_DEBUG(("keyboard disabled"));
-          break;
-        case 0xae: // enable keyboard
-          set_kbd_clock_enable(1);
-          BX_DEBUG(("keyboard enabled"));
-          break;
-        case 0xc0: // read input port
-          // controller output buffer must be empty
-          if (BX_KEY_THIS s.kbd_controller.outb) {
-BX_PANIC(("kbd: OUTB set and command 0x%02x encountered", value));
-            break;
-            }
-          // keyboard power normal
-          controller_enQ(0x00, 0);
-          break;
-        case 0xd0: // read output port: next byte read from port 60h
-          BX_DEBUG(("io write to port 64h, command d0h (partial)"));
-          // controller output buffer must be empty
-          if (BX_KEY_THIS s.kbd_controller.outb) {
-BX_PANIC(("kbd: OUTB set and command 0x%02x encountered", value));
-            break;
-            }
-          controller_enQ(
-              (BX_KEY_THIS s.kbd_controller.auxb << 5) |
-              (BX_KEY_THIS s.kbd_controller.outb << 4) |
-              (BX_GET_ENABLE_A20() << 1) |
-              0x01, 0);
-          break;
-
-        case 0xd1: // write output port: next byte written to port 60h
-          BX_DEBUG(("write output port"));
-          // following byte to port 60h written to output port
-          BX_KEY_THIS s.kbd_controller.expecting_port60h = 1;
-          break;
-
-        case 0xd3: // write mouse output buffer
-         //FIXME: Why was this a panic?
-          BX_DEBUG(("io write 0x64: command = 0xD3(write mouse outb)"));
-         // following byte to port 60h written to output port as mouse write.
-          BX_KEY_THIS s.kbd_controller.expecting_port60h = 1;
-          break;
-
-        case 0xd4: // write to mouse
-          BX_DEBUG(("io write 0x64: command = 0xD4 (write to mouse)"));
-          // following byte written to port 60h
-          BX_KEY_THIS s.kbd_controller.expecting_port60h = 1;
-          break;
-
-        case 0xd2: // write keyboard output buffer
-         BX_DEBUG(("io write 0x64: write keyboard output buffer"));
-         BX_KEY_THIS s.kbd_controller.expecting_port60h = 1;
-         break;
-        case 0xdd: // Disable A20 Address Line
-         BX_SET_ENABLE_A20(0);
-         break;
-        case 0xdf: // Enable A20 Address Line
-         BX_SET_ENABLE_A20(1);
-         break;
-        case 0xc1: // Continuous Input Port Poll, Low
-        case 0xc2: // Continuous Input Port Poll, High
-        case 0xe0: // Read Test Inputs
-          BX_PANIC(("io write 0x64: command = %02xh", (unsigned) value));
-          break;
-
-        case 0xfe: // System Reset, transition to real mode
-          BX_INFO(("system reset"));
-          bx_pc_system.ResetSignal( PCS_SET ); /* XXX is this right? */
-         {
-         for (int i=0; i<BX_SMP_PROCESSORS; i++) 
-            BX_CPU(i)->reset(BX_RESET_HARDWARE);
-         }
-          // Use bx_pc_system if necessary bx_cpu.reset_cpu();
-          // bx_pc_system.ResetSignal( PCS_SET );
-          break;
-
-        default:
-          if (value==0xff || (value>=0xf0 && value<=0xfd)) {
-            /* useless pulse output bit commands ??? */
-            BX_DEBUG(("io write to port 64h, useless command %02x",
-                (unsigned) value));
-            return;
-           }
-          BX_PANIC(("unsupported io write to keyboard port %x, value = %x",
-            (unsigned) address, (unsigned) value));
-          break;
-        }
-      break;
-
-    default: BX_PANIC(("unknown address in bx_keyb_c::write()"));
-    }
-}
-
-// service_paste_buf() transfers data from the paste buffer to the hardware
-// keyboard buffer.  It tries to transfer as many chars as possible at a
-// time, but because different chars require different numbers of scancodes
-// we have to be conservative.  Note that this process depends on the
-// keymap tables to know what chars correspond to what keys, and which
-// chars require a shift or other modifier.
-void 
-bx_keyb_c::service_paste_buf ()
-{
-  if (!BX_KEY_THIS pastebuf) return;
-  BX_DEBUG (("service_paste_buf: ptr at %d out of %d", BX_KEY_THIS pastebuf_ptr, BX_KEY_THIS pastebuf_len));
-  int fill_threshold = BX_KBD_ELEMENTS - 8;
-  while ( (BX_KEY_THIS pastebuf_ptr < BX_KEY_THIS pastebuf_len) && ! BX_KEY_THIS stop_paste) {
-    if (BX_KEY_THIS s.kbd_internal_buffer.num_elements >= fill_threshold)
-      return;
-    // there room in the buffer for a keypress and a key release.
-    // send one keypress and a key release.
-    Bit8u byte = BX_KEY_THIS pastebuf[BX_KEY_THIS pastebuf_ptr];
-    BXKeyEntry *entry = bx_keymap.findAsciiChar (byte);
-    if (!entry) {
-      BX_ERROR (("paste character 0x%02x ignored", byte));
-    } else {
-      BX_DEBUG (("pasting character 0x%02x. baseKey is %04x", byte, entry->baseKey));
-      if (entry->modKey != BX_KEYMAP_UNKNOWN)
-        BX_KEY_THIS gen_scancode (entry->modKey);
-      BX_KEY_THIS gen_scancode (entry->baseKey);
-      BX_KEY_THIS gen_scancode (entry->baseKey | BX_KEY_RELEASED);
-      if (entry->modKey != BX_KEYMAP_UNKNOWN)
-        BX_KEY_THIS gen_scancode (entry->modKey | BX_KEY_RELEASED);
-    }
-    BX_KEY_THIS pastebuf_ptr++;
-  }
-  // reached end of pastebuf.  free the memory it was using.
-  delete [] BX_KEY_THIS pastebuf;
-  BX_KEY_THIS pastebuf = NULL;
-  BX_KEY_THIS stop_paste = 0;
-}
-
-// paste_bytes schedules an arbitrary number of ASCII characters to be
-// inserted into the hardware queue as it become available.  Any previous
-// paste which is still in progress will be thrown out.  BYTES is a pointer
-// to a region of memory containing the chars to be pasted. When the paste
-// is complete, the keyboard code will call delete [] bytes;
-void
-bx_keyb_c::paste_bytes (Bit8u *bytes, Bit32s length)
-{
-  BX_DEBUG (("paste_bytes: %d bytes", length));
-  if (BX_KEY_THIS pastebuf) {
-    BX_ERROR (("previous paste was not completed!  %d chars lost", 
-         BX_KEY_THIS pastebuf_len - BX_KEY_THIS pastebuf_ptr));
-    delete [] BX_KEY_THIS pastebuf;  // free the old paste buffer
-  }
-  BX_KEY_THIS pastebuf = bytes;
-  BX_KEY_THIS pastebuf_ptr = 0;
-  BX_KEY_THIS pastebuf_len = length;
-  BX_KEY_THIS service_paste_buf ();
-}
-
-  void
-bx_keyb_c::gen_scancode(Bit32u key)
-{
-  unsigned char *scancode;
-  Bit8u  i;
-
-  BX_DEBUG(( "gen_scancode(): %s %s", bx_keymap.getBXKeyName(key), (key >> 31)?"released":"pressed"));
-
-  if (!BX_KEY_THIS s.kbd_controller.scancodes_translate)
-       BX_DEBUG(("keyboard: gen_scancode with scancode_translate cleared"));
-
-  // Ignore scancode if keyboard clock is driven low
-  if (BX_KEY_THIS s.kbd_controller.kbd_clock_enabled==0)
-    return;
-
-  // Ignore scancode if scanning is disabled
-  if (BX_KEY_THIS s.kbd_internal_buffer.scanning_enabled==0)
-    return;
-
-  // Switch between make and break code
-  if (key & BX_KEY_RELEASED)
-    scancode=(unsigned char *)scancodes[(key&0xFF)][BX_KEY_THIS s.kbd_controller.current_scancodes_set].brek;
-  else
-    scancode=(unsigned char *)scancodes[(key&0xFF)][BX_KEY_THIS s.kbd_controller.current_scancodes_set].make;
-
-  if (BX_KEY_THIS s.kbd_controller.scancodes_translate) {
-    // Translate before send
-    Bit8u escaped=0x00;
-
-    for (i=0; i<strlen( (const char *)scancode ); i++) {
-      if (scancode[i] == 0xF0)
-        escaped=0x80;
-      else {
-       BX_DEBUG(("gen_scancode(): writing translated %02x",translation8042[scancode[i] ] | escaped));
-        kbd_enQ(translation8042[scancode[i] ] | escaped );
-        escaped=0x00;
-      }
-    }
-  } 
-  else {
-    // Send raw data
-    for (i=0; i<strlen( (const char *)scancode ); i++) {
-      BX_DEBUG(("gen_scancode(): writing raw %02x",scancode[i]));
-      kbd_enQ( scancode[i] );
-    }
-  }
-}
-
-
-
-  void BX_CPP_AttrRegparmN(1)
-bx_keyb_c::set_kbd_clock_enable(Bit8u   value)
-{
-  bx_bool prev_kbd_clock_enabled;
-
-  if (value==0) {
-    BX_KEY_THIS s.kbd_controller.kbd_clock_enabled = 0;
-    }
-  else {
-    /* is another byte waiting to be sent from the keyboard ? */
-    prev_kbd_clock_enabled = BX_KEY_THIS s.kbd_controller.kbd_clock_enabled;
-    BX_KEY_THIS s.kbd_controller.kbd_clock_enabled = 1;
-
-    if (prev_kbd_clock_enabled==0 && BX_KEY_THIS s.kbd_controller.outb==0) {
-      activate_timer();
-      }
-    }
-}
-
-
-
-  void
-bx_keyb_c::set_aux_clock_enable(Bit8u   value)
-{
-  bx_bool prev_aux_clock_enabled;
-
-  BX_DEBUG(("set_aux_clock_enable(%u)", (unsigned) value));
-  if (value==0) {
-    BX_KEY_THIS s.kbd_controller.aux_clock_enabled = 0;
-    }
-  else {
-    /* is another byte waiting to be sent from the keyboard ? */
-    prev_aux_clock_enabled = BX_KEY_THIS s.kbd_controller.aux_clock_enabled;
-    BX_KEY_THIS s.kbd_controller.aux_clock_enabled = 1;
-    if (prev_aux_clock_enabled==0 && BX_KEY_THIS s.kbd_controller.outb==0)
-      activate_timer();
-    }
-}
-
-  Bit8u
-bx_keyb_c::get_kbd_enable(void)
-{
-  BX_DEBUG(("get_kbd_enable(): getting kbd_clock_enabled of: %02x",
-      (unsigned) BX_KEY_THIS s.kbd_controller.kbd_clock_enabled));
-
-  return(BX_KEY_THIS s.kbd_controller.kbd_clock_enabled);
-}
-
-  void
-bx_keyb_c::controller_enQ(Bit8u   data, unsigned source)
-{
-  // source is 0 for keyboard, 1 for mouse
-
-  BX_DEBUG(("controller_enQ(%02x) source=%02x", (unsigned) data,source));
-
-  if (BX_KEY_THIS s.kbd_controller.outb)
-    BX_ERROR(("controller_enQ(): OUTB set!"));
-
-  // see if we need to Q this byte from the controller
-  // remember this includes mouse bytes.
-  if (BX_KEY_THIS s.kbd_controller.outb) {
-    if (BX_KEY_THIS s.controller_Qsize >= BX_KBD_CONTROLLER_QSIZE)
-      BX_PANIC(("controller_enq(): controller_Q full!"));
-    BX_KEY_THIS s.controller_Q[BX_KEY_THIS s.controller_Qsize++] = data;
-    BX_KEY_THIS s.controller_Qsource = source;
-    return;
-    }
-
-  // the Q is empty
-  if (source == 0) { // keyboard
-    BX_KEY_THIS s.kbd_controller.kbd_output_buffer = data;
-    //    BX_INFO(("kbd: %04d outb 1 auxb 0",__LINE__)); // das
-    BX_KEY_THIS s.kbd_controller.outb = 1;
-    BX_KEY_THIS s.kbd_controller.auxb = 0;
-    BX_KEY_THIS s.kbd_controller.inpb = 0;
-    if (BX_KEY_THIS s.kbd_controller.allow_irq1)
-      BX_KEY_THIS s.kbd_controller.irq1_requested = 1;
-    }
-  else { // mouse
-    BX_KEY_THIS s.kbd_controller.aux_output_buffer = data;
-    //    BX_INFO(("kbd: %04d outb 1 auxb 1",__LINE__)); // das
-    BX_KEY_THIS s.kbd_controller.outb = 1;
-    BX_KEY_THIS s.kbd_controller.auxb = 1;
-    BX_KEY_THIS s.kbd_controller.inpb = 0;
-    if (BX_KEY_THIS s.kbd_controller.allow_irq12)
-      BX_KEY_THIS s.kbd_controller.irq12_requested = 1;
-    }
-}
-
-void
-bx_keyb_c::kbd_enQ_imm(Bit8u val)
-{
-      int tail;
-
-      if (BX_KEY_THIS s.kbd_internal_buffer.num_elements >= BX_KBD_ELEMENTS) {
-           BX_PANIC(("internal keyboard buffer full (imm)"));
-           return;
-      }
-
-      /* enqueue scancode in multibyte internal keyboard buffer */
-      tail = (BX_KEY_THIS s.kbd_internal_buffer.head + BX_KEY_THIS s.kbd_internal_buffer.num_elements) %
-           BX_KBD_ELEMENTS;
-
-      BX_KEY_THIS s.kbd_controller.kbd_output_buffer = val;
-      //      BX_INFO(("kbd: %04d outb 1",__LINE__)); // das
-      BX_KEY_THIS s.kbd_controller.outb = 1;
-
-      if (BX_KEY_THIS s.kbd_controller.allow_irq1)
-           BX_KEY_THIS s.kbd_controller.irq1_requested = 1;
-}
-
-
-  void
-bx_keyb_c::kbd_enQ(Bit8u scancode)
-{
-  int tail;
-
-  BX_DEBUG(("kbd_enQ(0x%02x)", (unsigned) scancode));
-
-  if (BX_KEY_THIS s.kbd_internal_buffer.num_elements >= BX_KBD_ELEMENTS) {
-    BX_INFO(("internal keyboard buffer full, ignoring scancode.(%02x)",
-      (unsigned) scancode));
-    return;
-    }
-
-  /* enqueue scancode in multibyte internal keyboard buffer */
-  BX_DEBUG(("kbd_enQ: putting scancode 0x%02x in internal buffer",
-      (unsigned) scancode));
-  tail = (BX_KEY_THIS s.kbd_internal_buffer.head + BX_KEY_THIS s.kbd_internal_buffer.num_elements) %
-   BX_KBD_ELEMENTS;
-  BX_KEY_THIS s.kbd_internal_buffer.buffer[tail] = scancode;
-  BX_KEY_THIS s.kbd_internal_buffer.num_elements++;
-
-  if (!BX_KEY_THIS s.kbd_controller.outb && BX_KEY_THIS s.kbd_controller.kbd_clock_enabled) {
-    activate_timer();
-    BX_DEBUG(("activating timer..."));
-    return;
-    }
-//BX_DEBUG(( "# not activating timer...");
-//BX_DEBUG(( "#   allow_irq1 = %u", (unsigned) BX_KEY_THIS s.kbd_controller.allow_irq1);
-//BX_DEBUG(( "#   outb       = %u", (unsigned) BX_KEY_THIS s.kbd_controller.outb);
-//BX_DEBUG(( "#   clock_enab = %u", (unsigned) BX_KEY_THIS s.kbd_controller.kbd_clock_enabled);
-//BX_DEBUG(( "#   out_buffer = %u", (unsigned) BX_KEY_THIS s.kbd_controller.kbd_output_buffer);
-}
-
-  bx_bool BX_CPP_AttrRegparmN(3)
-bx_keyb_c::mouse_enQ_packet(Bit8u   b1, Bit8u   b2, Bit8u   b3)
-{
-  if ((BX_KEY_THIS s.mouse_internal_buffer.num_elements + 3) >= BX_MOUSE_BUFF_SIZE) {
-    return(0); /* buffer doesn't have the space */
-    }
-
-//BX_DEBUG(("mouse: enQ_packet(%02x, %02x, %02x)",
-//  (unsigned) b1, (unsigned) b2, (unsigned) b3));
-
-  mouse_enQ(b1);
-  mouse_enQ(b2);
-  mouse_enQ(b3);
-  return(1);
-}
-
-
-  void
-bx_keyb_c::mouse_enQ(Bit8u   mouse_data)
-{
-  int tail;
-
-  BX_DEBUG(("mouse_enQ(%02x)", (unsigned) mouse_data));
-
-  if (BX_KEY_THIS s.mouse_internal_buffer.num_elements >= BX_MOUSE_BUFF_SIZE) {
-    BX_ERROR(("mouse: internal mouse buffer full, ignoring mouse data.(%02x)",
-      (unsigned) mouse_data));
-    return;
-    }
-//BX_DEBUG(( "# mouse_enq() aux_clock_enabled = %u",
-//  (unsigned) BX_KEY_THIS s.kbd_controller.aux_clock_enabled);
-
-  /* enqueue mouse data in multibyte internal mouse buffer */
-  tail = (BX_KEY_THIS s.mouse_internal_buffer.head + BX_KEY_THIS s.mouse_internal_buffer.num_elements) %
-   BX_MOUSE_BUFF_SIZE;
-  BX_KEY_THIS s.mouse_internal_buffer.buffer[tail] = mouse_data;
-  BX_KEY_THIS s.mouse_internal_buffer.num_elements++;
-
-  if (!BX_KEY_THIS s.kbd_controller.outb && BX_KEY_THIS s.kbd_controller.aux_clock_enabled) {
-    activate_timer();
-//BX_DEBUG(( "# activating timer...");
-    return;
-    }
-//BX_DEBUG(( "# not activating timer...");
-//BX_DEBUG(( "#   allow_irq12= %u", (unsigned) BX_KEY_THIS s.kbd_controller.allow_irq12);
-//BX_DEBUG(( "#   outb       = %u", (unsigned) BX_KEY_THIS s.kbd_controller.outb);
-//BX_DEBUG(( "#   clock_enab = %u", (unsigned) BX_KEY_THIS s.kbd_controller.aux_clock_enabled);
-//BX_DEBUG(( "#   out_buffer = %u", (unsigned) BX_KEY_THIS s.kbd_controller.aux_output_buffer);
-}
-
-  void
-bx_keyb_c::kbd_ctrl_to_kbd(Bit8u   value)
-{
-
-  BX_DEBUG(("controller passed byte %02xh to keyboard", value));
-
-  if (BX_KEY_THIS s.kbd_internal_buffer.expecting_typematic) {
-    BX_KEY_THIS s.kbd_internal_buffer.expecting_typematic = 0;
-    BX_KEY_THIS s.kbd_internal_buffer.delay = (value >> 5) & 0x03;
-    switch (BX_KEY_THIS s.kbd_internal_buffer.delay) {
-      case 0: BX_INFO(("setting delay to 250 mS (unused)")); break;
-      case 1: BX_INFO(("setting delay to 500 mS (unused)")); break;
-      case 2: BX_INFO(("setting delay to 750 mS (unused)")); break;
-      case 3: BX_INFO(("setting delay to 1000 mS (unused)")); break;
-      }
-    BX_KEY_THIS s.kbd_internal_buffer.repeat_rate = value & 0x1f;
-    double cps = 1 /((double)(8 + (value & 0x07)) * (double)exp(log((double)2) * (double)((value >> 3) & 0x03)) * 0.00417);
-    BX_INFO(("setting repeat rate to %.1f cps (unused)", cps));
-    kbd_enQ(0xFA); // send ACK
-    return;
-    }
-
-  if (BX_KEY_THIS s.kbd_internal_buffer.expecting_led_write) {
-    BX_KEY_THIS s.kbd_internal_buffer.expecting_led_write = 0;
-    BX_KEY_THIS s.kbd_internal_buffer.led_status = value;
-    BX_DEBUG(("LED status set to %02x",
-      (unsigned) BX_KEY_THIS s.kbd_internal_buffer.led_status));
-    kbd_enQ(0xFA); // send ACK %%%
-    return;
-    }
-
-  if (BX_KEY_THIS s.kbd_controller.expecting_scancodes_set) {
-    BX_KEY_THIS s.kbd_controller.expecting_scancodes_set = 0;
-    if( value != 0 ) {
-      if( value<4 ) {
-        BX_KEY_THIS s.kbd_controller.current_scancodes_set = (value-1);
-        BX_INFO(("Switched to scancode set %d\n",
-          (unsigned) BX_KEY_THIS s.kbd_controller.current_scancodes_set + 1));
-        kbd_enQ(0xFA);
-        } 
-      else {
-        BX_ERROR(("Received scancodes set out of range: %d\n", value ));
-        kbd_enQ(0xFF); // send ERROR
-        }
-      } 
-    else {
-      // Send current scancodes set to port 0x60
-      kbd_enQ( 1 + (BX_KEY_THIS s.kbd_controller.current_scancodes_set) ); 
-      }
-    return;
-    }
-
-  switch (value) {
-    case 0x00: // ??? ignore and let OS timeout with no response
-      kbd_enQ(0xFA); // send ACK %%%
-      return;
-      break;
-
-    case 0x05: // ???
-         // (mch) trying to get this to work...
-          BX_KEY_THIS s.kbd_controller.sysf = 1;
-         kbd_enQ_imm(0xfe);
-      return;
-      break;
-
-    case 0xed: // LED Write
-      BX_KEY_THIS s.kbd_internal_buffer.expecting_led_write = 1;
-      kbd_enQ_imm(0xFA); // send ACK %%%
-      return;
-      break;
-
-    case 0xee: // echo
-      kbd_enQ(0xEE); // return same byte (EEh) as echo diagnostic
-      return;
-      break;
-
-    case 0xf0: // Select alternate scan code set
-      BX_KEY_THIS s.kbd_controller.expecting_scancodes_set = 1;
-      BX_DEBUG(("Expecting scancode set info...\n"));
-      kbd_enQ(0xFA); // send ACK
-      return;
-      break;
-
-    case 0xf2:  // identify keyboard
-      BX_INFO(("identify keyboard command received"));
-
-      // XT sends nothing, AT sends ACK 
-      // MFII with translation sends ACK+ABh+41h
-      // MFII without translation sends ACK+ABh+83h
-      if (bx_options.Okeyboard_type->get() != BX_KBD_XT_TYPE) {
-        kbd_enQ(0xFA); 
-        if (bx_options.Okeyboard_type->get() == BX_KBD_MF_TYPE) {
-          kbd_enQ(0xAB);
-          
-          if(BX_KEY_THIS s.kbd_controller.scancodes_translate)
-            kbd_enQ(0x41);
-          else
-            kbd_enQ(0x83);
-          }
-        }
-      return;
-      break;
-
-    case 0xf3:  // typematic info
-      BX_KEY_THIS s.kbd_internal_buffer.expecting_typematic = 1;
-      BX_INFO(("setting typematic info"));
-      kbd_enQ(0xFA); // send ACK
-      return;
-      break;
-
-    case 0xf4:  // enable keyboard
-      BX_KEY_THIS s.kbd_internal_buffer.scanning_enabled = 1;
-      kbd_enQ(0xFA); // send ACK
-      return;
-      break;
-
-    case 0xf5:  // reset keyboard to power-up settings and disable scanning
-      resetinternals(1);
-      kbd_enQ(0xFA); // send ACK
-      BX_KEY_THIS s.kbd_internal_buffer.scanning_enabled = 0;
-      BX_INFO(("reset-disable command received"));
-      return;
-      break;
-
-    case 0xf6:  // reset keyboard to power-up settings and enable scanning
-      resetinternals(1);
-      kbd_enQ(0xFA); // send ACK
-      BX_KEY_THIS s.kbd_internal_buffer.scanning_enabled = 1;
-      BX_INFO(("reset-enable command received"));
-      return;
-      break;
-
-    case 0xf7:  // PS/2 Set All Keys To Typematic
-    case 0xf8:  // PS/2 Set All Keys to Make/Break
-    case 0xf9:  // PS/2 PS/2 Set All Keys to Make
-    case 0xfa:  // PS/2 Set All Keys to Typematic Make/Break
-    case 0xfb:  // PS/2 Set Key Type to Typematic
-    case 0xfc:  // PS/2 Set Key Type to Make/Break
-    case 0xfd:  // PS/2 Set Key Type to Make
-      // Silently ignore and let the OS timeout, for now.
-      // If anyone has code around that makes use of that, I can
-      // provide documentation on their behavior (ask core@ggi-project.org)
-      return;
-      break;
-
-    case 0xfe:  // resend. aiiee.
-      BX_PANIC( ("got 0xFE (resend)"));
-      return;
-      break;
-
-    case 0xff:  // reset: internal keyboard reset and afterwards the BAT
-      BX_DEBUG(("reset command received"));
-      resetinternals(1);
-      kbd_enQ(0xFA); // send ACK
-      kbd_enQ(0xAA); // BAT test passed
-      return;
-      break;
-
-    case 0xd3:
-      kbd_enQ(0xfa);
-      return;
-
-    default:
-                       /* XXX fix this properly:
-                       http://panda.cs.ndsu.nodak.edu/~achapwes/PICmicro/mouse/mouse.html
-                       http://sourceforge.net/tracker/index.php?func=detail&aid=422457&group_id=12580&atid=112580
-                        */
-      BX_ERROR(("kbd_ctrl_to_kbd(): got value of %02x",
-        (unsigned) value));
-      kbd_enQ(0xFA); /* send ACK ??? */
-      return;
-      break;
-    }
-}
-
-  void
-bx_keyb_c::timer_handler(void *this_ptr)
-{
-  bx_keyb_c *class_ptr = (bx_keyb_c *) this_ptr;
-  unsigned retval;
-
-  // retval=class_ptr->periodic( bx_options.Okeyboard_serial_delay->get());
-  retval=class_ptr->periodic(1);
-
-  if(retval&0x01)
-    DEV_pic_raise_irq(1);
-  if(retval&0x02)
-    DEV_pic_raise_irq(12);
-}
-
-  unsigned
-bx_keyb_c::periodic( Bit32u   usec_delta )
-{
-/*  static int multiple=0; */
-  static unsigned count_before_paste=0;
-  Bit8u   retval;
-
-  UNUSED( usec_delta );
-
-  if (BX_KEY_THIS s.kbd_controller.kbd_clock_enabled ) {
-    if(++count_before_paste>=BX_KEY_THIS pastedelay) {
-      // after the paste delay, consider adding moving more chars
-      // from the paste buffer to the keyboard buffer.
-      BX_KEY_THIS service_paste_buf ();
-      count_before_paste=0;
-    }
-  }
-
-  retval = BX_KEY_THIS s.kbd_controller.irq1_requested | (BX_KEY_THIS s.kbd_controller.irq12_requested << 1);
-  BX_KEY_THIS s.kbd_controller.irq1_requested = 0;
-  BX_KEY_THIS s.kbd_controller.irq12_requested = 0;
-
-  if ( BX_KEY_THIS s.kbd_controller.timer_pending == 0 ) {
-    return(retval);
-    }
-
-  if ( usec_delta >= BX_KEY_THIS s.kbd_controller.timer_pending ) {
-    BX_KEY_THIS s.kbd_controller.timer_pending = 0;
-    }
-  else {
-    BX_KEY_THIS s.kbd_controller.timer_pending -= usec_delta;
-    return(retval);
-    }
-
-  if (BX_KEY_THIS s.kbd_controller.outb) {
-    return(retval);
-    }
-
-  /* nothing in outb, look for possible data xfer from keyboard or mouse */
-  if (BX_KEY_THIS s.kbd_controller.kbd_clock_enabled && BX_KEY_THIS s.kbd_internal_buffer.num_elements) {
-//BX_DEBUG(( "#   servicing keyboard code");
-    BX_DEBUG(("service_keyboard: key in internal buffer waiting"));
-    BX_KEY_THIS s.kbd_controller.kbd_output_buffer =
-      BX_KEY_THIS s.kbd_internal_buffer.buffer[BX_KEY_THIS s.kbd_internal_buffer.head];
-    //    BX_INFO(("kbd: %04d outb 1",__LINE__)); // das
-    BX_KEY_THIS s.kbd_controller.outb = 1;
-    // commented out since this would override the current state of the
-    // mouse buffer flag - no bug seen - just seems wrong (das)
-    //    BX_KEY_THIS s.kbd_controller.auxb = 0;
-//BX_DEBUG(( "# ___kbd::periodic kbd");
-    BX_KEY_THIS s.kbd_internal_buffer.head = (BX_KEY_THIS s.kbd_internal_buffer.head + 1) %
-      BX_KBD_ELEMENTS;
-    BX_KEY_THIS s.kbd_internal_buffer.num_elements--;
-    if (BX_KEY_THIS s.kbd_controller.allow_irq1)
-      BX_KEY_THIS s.kbd_controller.irq1_requested = 1;
-    }
-  else { 
-    create_mouse_packet(0);
-    if (BX_KEY_THIS s.kbd_controller.aux_clock_enabled && BX_KEY_THIS s.mouse_internal_buffer.num_elements) {
-//BX_DEBUG(( "#   servicing mouse code");
-      BX_DEBUG(("service_keyboard: key(from mouse) in internal buffer waiting"));
-      BX_KEY_THIS s.kbd_controller.aux_output_buffer =
-       BX_KEY_THIS s.mouse_internal_buffer.buffer[BX_KEY_THIS s.mouse_internal_buffer.head];
-
-    //    BX_INFO(("kbd: %04d outb 1 auxb 1",__LINE__)); //das
-      BX_KEY_THIS s.kbd_controller.outb = 1;
-      BX_KEY_THIS s.kbd_controller.auxb = 1;
-//BX_DEBUG(( "# ___kbd:periodic aux");
-      BX_KEY_THIS s.mouse_internal_buffer.head = (BX_KEY_THIS s.mouse_internal_buffer.head + 1) %
-       BX_MOUSE_BUFF_SIZE;
-      BX_KEY_THIS s.mouse_internal_buffer.num_elements--;
-//BX_DEBUG(( "#   allow12 = %u", (unsigned) BX_KEY_THIS s.kbd_controller.allow_irq12);
-      if (BX_KEY_THIS s.kbd_controller.allow_irq12)
-       BX_KEY_THIS s.kbd_controller.irq12_requested = 1;
-    }
-    else {
-      BX_DEBUG(("service_keyboard(): no keys waiting"));
-    }
-  }
-  return(retval);
-}
-
-
-
-
-  void
-bx_keyb_c::activate_timer(void)
-{
-  if (BX_KEY_THIS s.kbd_controller.timer_pending == 0) {
-    // BX_KEY_THIS s.kbd_controller.timer_pending = bx_options.Okeyboard_serial_delay->get ();
-    BX_KEY_THIS s.kbd_controller.timer_pending = 1;
-    }
-}
-
-
-  void
-bx_keyb_c::kbd_ctrl_to_mouse(Bit8u   value)
-{
-BX_DEBUG(("MOUSE: kbd_ctrl_to_mouse(%02xh)", (unsigned) value));
-BX_DEBUG(("  enable = %u", (unsigned) BX_KEY_THIS s.mouse.enable));
-BX_DEBUG(("  allow_irq12 = %u",
-  (unsigned) BX_KEY_THIS s.kbd_controller.allow_irq12));
-BX_DEBUG(("  aux_clock_enabled = %u",
-  (unsigned) BX_KEY_THIS s.kbd_controller.aux_clock_enabled));
-//BX_DEBUG(( "MOUSE: kbd_ctrl_to_mouse(%02xh)", (unsigned) value));
-
-  // an ACK (0xFA) is always the first response to any valid input
-  // received from the system other than Set-Wrap-Mode & Resend-Command
-
-
- if (BX_KEY_THIS s.kbd_controller.expecting_mouse_parameter) {
-       BX_KEY_THIS s.kbd_controller.expecting_mouse_parameter = 0;
-       switch (BX_KEY_THIS s.kbd_controller.last_mouse_command) {
-            case 0xf3: // Set Mouse Sample Rate
-                  BX_KEY_THIS s.mouse.sample_rate = value;
-                  BX_DEBUG(("[mouse] Sampling rate set: %d Hz", value));
-                  controller_enQ(0xFA, 1); // ack
-                  break;
-
-            case 0xe8: // Set Mouse Resolution
-                  switch (value) {
-                        case 0:
-                              BX_KEY_THIS s.mouse.resolution_cpmm = 1;
-                              break;
-                        case 1:
-                              BX_KEY_THIS s.mouse.resolution_cpmm = 2;
-                              break;
-                        case 2:
-                              BX_KEY_THIS s.mouse.resolution_cpmm = 4;
-                              break;
-                        case 3:
-                              BX_KEY_THIS s.mouse.resolution_cpmm = 8;
-                              break;
-                        default:
-                              BX_PANIC(("[mouse] Unknown resolution %d", value));
-                              break;
-                  }
-                  BX_DEBUG(("[mouse] Resolution set to %d counts per mm",
-                                  BX_KEY_THIS s.mouse.resolution_cpmm));
-
-                  controller_enQ(0xFA, 1); // ack
-                  break;
-
-            default:
-                  BX_PANIC(("MOUSE: unknown last command (%02xh)", (unsigned) BX_KEY_THIS s.kbd_controller.last_mouse_command));
-       }
- } else {
-  BX_KEY_THIS s.kbd_controller.expecting_mouse_parameter = 0;
-  BX_KEY_THIS s.kbd_controller.last_mouse_command = value;
-
-  // test for wrap mode first
-  if (BX_KEY_THIS s.mouse.mode == MOUSE_MODE_WRAP) {
-    // if not a reset command or reset wrap mode
-    // then just echo the byte.
-    if ((value != 0xff) && (value != 0xec)) {
-      if (bx_dbg.mouse)
-       BX_INFO(("[mouse] wrap mode: Ignoring command %0X02.",value));
-      controller_enQ(value,1);
-      // bail out
-      return;
-    }
-  }
-  switch ( value ) {
-    case 0xe6: // Set Mouse Scaling to 1:1
-      controller_enQ(0xFA, 1); // ACK
-      BX_KEY_THIS s.mouse.scaling         = 2;
-         BX_DEBUG(("[mouse] Scaling set to 1:1"));
-      break;
-
-    case 0xe7: // Set Mouse Scaling to 2:1
-      controller_enQ(0xFA, 1); // ACK
-      BX_KEY_THIS s.mouse.scaling         = 2;
-         BX_DEBUG(("[mouse] Scaling set to 2:1"));
-      break;
-
-    case 0xe8: // Set Mouse Resolution
-      controller_enQ(0xFA, 1); // ACK
-      BX_KEY_THIS s.kbd_controller.expecting_mouse_parameter = 1;
-      break;
-
-    case 0xea: // Set Stream Mode
-      if (bx_dbg.mouse)
-       BX_INFO(("[mouse] Mouse stream mode on."));
-      BX_KEY_THIS s.mouse.mode = MOUSE_MODE_STREAM;
-      controller_enQ(0xFA, 1); // ACK
-      break;
-
-    case 0xec: // Reset Wrap Mode
-      // unless we are in wrap mode ignore the command
-      if ( BX_KEY_THIS s.mouse.mode == MOUSE_MODE_WRAP) {
-       if (bx_dbg.mouse)
-         BX_INFO(("[mouse] Mouse wrap mode off."));
-       // restore previous mode except disable stream mode reporting.
-       // ### TODO disabling reporting in stream mode
-       BX_KEY_THIS s.mouse.mode = BX_KEY_THIS s.mouse.saved_mode;
-       controller_enQ(0xFA, 1); // ACK
-      }
-      break;
-    case 0xee: // Set Wrap Mode
-      // ### TODO flush output queue.
-      // ### TODO disable interrupts if in stream mode.
-      if (bx_dbg.mouse)
-           BX_INFO(("[mouse] Mouse wrap mode on."));
-      BX_KEY_THIS s.mouse.saved_mode = BX_KEY_THIS s.mouse.mode;
-      BX_KEY_THIS s.mouse.mode = MOUSE_MODE_WRAP;
-      controller_enQ(0xFA, 1); // ACK
-      break;
-
-    case 0xf0: // Set Remote Mode (polling mode, i.e. not stream mode.)
-      if (bx_dbg.mouse)
-           BX_INFO(("[mouse] Mouse remote mode on."));
-      // ### TODO should we flush/discard/ignore any already queued packets?
-      BX_KEY_THIS s.mouse.mode = MOUSE_MODE_REMOTE;
-      controller_enQ(0xFA, 1); // ACK
-      break;
-
-
-    case 0xf2: // Read Device Type
-      controller_enQ(0xFA, 1); // ACK
-      controller_enQ(0x00, 1); // Device ID
-         BX_DEBUG(("[mouse] Read mouse ID"));
-      break;
-
-    case 0xf3: // Set Mouse Sample Rate (sample rate written to port 60h)
-      controller_enQ(0xFA, 1); // ACK
-      BX_KEY_THIS s.kbd_controller.expecting_mouse_parameter = 1;
-      break;
-
-    case 0xf4: // Enable (in stream mode)
-      BX_KEY_THIS s.mouse.enable = 1;
-      controller_enQ(0xFA, 1); // ACK
-         BX_DEBUG(("[mouse] Mouse enabled (stream mode)"));
-      break;
-
-    case 0xf5: // Disable (in stream mode)
-      BX_KEY_THIS s.mouse.enable = 0;
-      controller_enQ(0xFA, 1); // ACK
-         BX_DEBUG(("[mouse] Mouse disabled (stream mode)"));
-      break;
-
-    case 0xf6: // Set Defaults
-      BX_KEY_THIS s.mouse.sample_rate     = 100; /* reports per second (default) */
-      BX_KEY_THIS s.mouse.resolution_cpmm = 4; /* 4 counts per millimeter (default) */
-      BX_KEY_THIS s.mouse.scaling         = 1;   /* 1:1 (default) */
-      BX_KEY_THIS s.mouse.enable          = 0;
-      BX_KEY_THIS s.mouse.mode            = MOUSE_MODE_STREAM;
-      controller_enQ(0xFA, 1); // ACK
-         BX_DEBUG(("[mouse] Set Defaults"));
-      break;
-
-    case 0xff: // Reset
-      BX_KEY_THIS s.mouse.sample_rate     = 100; /* reports per second (default) */
-      BX_KEY_THIS s.mouse.resolution_cpmm = 4; /* 4 counts per millimeter (default) */
-      BX_KEY_THIS s.mouse.scaling         = 1;   /* 1:1 (default) */
-      BX_KEY_THIS s.mouse.mode            = MOUSE_MODE_RESET;
-      BX_KEY_THIS s.mouse.enable          = 0;
-      /* (mch) NT expects an ack here */
-      controller_enQ(0xFA, 1); // ACK
-      controller_enQ(0xAA, 1); // completion code
-      controller_enQ(0x00, 1); // ID code (normal mouse, wheelmouse has id 0x3)
-         BX_DEBUG(("[mouse] Mouse reset"));
-      break;
-
-    case 0xe9: // Get mouse information
-      // should we ack here? (mch): Yes
-      controller_enQ(0xFA, 1); // ACK
-      controller_enQ(BX_KEY_THIS s.mouse.get_status_byte(), 1); // status
-      controller_enQ(BX_KEY_THIS s.mouse.get_resolution_byte(), 1); // resolution
-      controller_enQ(BX_KEY_THIS s.mouse.sample_rate, 1); // sample rate
-         BX_DEBUG(("[mouse] Get mouse information"));
-      break;
-
-    case 0xeb: // Read Data (send a packet when in Remote Mode)
-      controller_enQ(0xFA, 1); // ACK
-      // perhaps we should be adding some movement here.
-      mouse_enQ_packet( ((BX_KEY_THIS s.mouse.button_status & 0x0f) | 0x08),
-                       0x00, 0x00 ); // bit3 of first byte always set
-      //assumed we really aren't in polling mode, a rather odd assumption.
-      BX_ERROR(("[mouse] Warning: Read Data command partially supported."));
-      break;
-
-    default:
-      //FEh Resend
-      BX_PANIC(("MOUSE: kbd_ctrl_to_mouse(%02xh)", (unsigned) value));
-    }
- }
-}
-
-void
-bx_keyb_c::create_mouse_packet(bool force_enq) {
-  Bit8u   b1, b2, b3;
-
-  //  BX_DEBUG("Calling create_mouse_packet: force_enq=%d\n",force_enq);
-
-  if(BX_KEY_THIS s.mouse_internal_buffer.num_elements && !force_enq)
-    return;
-
-  //  BX_DEBUG("Got to first milestone: force_enq=%d\n",force_enq);
-
-  Bit16s delta_x = BX_KEY_THIS s.mouse.delayed_dx;
-  Bit16s delta_y = BX_KEY_THIS s.mouse.delayed_dy;
-  Bit8u button_state=BX_KEY_THIS s.mouse.button_status | 0x08;
-
-  if(!force_enq && !delta_x && !delta_y) {
-    return;
-  }
-
-  //  BX_DEBUG("Got to second milestone: delta_x=%d, delta_y=%d\n",delta_x,delta_y);
-
-  if(delta_x>254) delta_x=254;
-  if(delta_x<-254) delta_x=-254;
-  if(delta_y>254) delta_y=254;
-  if(delta_y<-254) delta_y=-254;
-
-  b1 = (button_state & 0x0f) | 0x08; // bit3 always set
-
-  if ( (delta_x>=0) && (delta_x<=255) ) {
-    b2 = (Bit8u) delta_x;
-    BX_KEY_THIS s.mouse.delayed_dx-=delta_x;
-    }
-  else if ( delta_x > 255 ) {
-    b2 = (Bit8u) 0xff;
-    BX_KEY_THIS s.mouse.delayed_dx-=255;
-    }
-  else if ( delta_x >= -256 ) {
-    b2 = (Bit8u) delta_x;
-    b1 |= 0x10;
-    BX_KEY_THIS s.mouse.delayed_dx-=delta_x;
-    }
-  else {
-    b2 = (Bit8u) 0x00;
-    b1 |= 0x10;
-    BX_KEY_THIS s.mouse.delayed_dx+=256;
-    }
-
-  if ( (delta_y>=0) && (delta_y<=255) ) {
-    b3 = (Bit8u) delta_y;
-    BX_KEY_THIS s.mouse.delayed_dy-=delta_y;
-    }
-  else if ( delta_y > 255 ) {
-    b3 = (Bit8u) 0xff;
-    BX_KEY_THIS s.mouse.delayed_dy-=255;
-    }
-  else if ( delta_y >= -256 ) {
-    b3 = (Bit8u) delta_y;
-    b1 |= 0x20;
-    BX_KEY_THIS s.mouse.delayed_dy-=delta_y;
-    }
-  else {
-    b3 = (Bit8u) 0x00;
-    b1 |= 0x20;
-    BX_KEY_THIS s.mouse.delayed_dy+=256;
-    }
-  mouse_enQ_packet(b1, b2, b3);
-}
-
-
-void
-bx_keyb_c::mouse_enabled_changed(bool enabled) {
-  if(s.mouse.delayed_dx || BX_KEY_THIS s.mouse.delayed_dy) {
-    create_mouse_packet(1);
-  }
-  s.mouse.delayed_dx=0;
-  s.mouse.delayed_dy=0;
-  BX_DEBUG(("Keyboard mouse disable called."));
-}
-
-  void
-bx_keyb_c::mouse_motion(int delta_x, int delta_y, unsigned button_state)
-{
-  bool force_enq=0;
-
-  // If mouse events are disabled on the GUI headerbar, don't
-  // generate any mouse data
-  if (bx_options.Omouse_enabled->get () == 0)
-    return;
-
-
-  // don't generate interrupts if we are in remote mode.
-  if ( BX_KEY_THIS s.mouse.mode == MOUSE_MODE_REMOTE)
-    // is there any point in doing any work if we don't act on the result
-    // so go home.
-    return;
-
-
-  // Note: enable only applies in STREAM MODE.
-  if ( BX_KEY_THIS s.mouse.enable==0 )
-    return;
-
-  // scale down the motion
-  if ( (delta_x < -1) || (delta_x > 1) )
-    delta_x /= 2;
-  if ( (delta_y < -1) || (delta_y > 1) )
-    delta_y /= 2;
-
-#ifdef VERBOSE_KBD_DEBUG
-  if (delta_x != 0 || delta_y != 0)
-    BX_DEBUG(("[mouse] Dx=%d Dy=%d", delta_x, delta_y));
-#endif  /* ifdef VERBOSE_KBD_DEBUG */
-
-  if( (delta_x==0) && (delta_y==0) && (BX_KEY_THIS s.mouse.button_status == (button_state & 0x3) ) ) {
-    BX_DEBUG(("Ignoring useless mouse_motion call:\n"));
-    BX_DEBUG(("This should be fixed in the gui code.\n"));
-    return;
-  }
-
-  if(BX_KEY_THIS s.mouse.button_status != (button_state & 0x3)) {
-    force_enq=1;
-  }
-
-  BX_KEY_THIS s.mouse.button_status = button_state & 0x3;
-
-  if(delta_x>255) delta_x=255;
-  if(delta_y>255) delta_y=255;
-  if(delta_x<-256) delta_x=-256;
-  if(delta_y<-256) delta_y=-256;
-
-  BX_KEY_THIS s.mouse.delayed_dx+=delta_x;
-  BX_KEY_THIS s.mouse.delayed_dy+=delta_y;
-
-  if((BX_KEY_THIS s.mouse.delayed_dx>255)||
-     (BX_KEY_THIS s.mouse.delayed_dx<-256)||
-     (BX_KEY_THIS s.mouse.delayed_dy>255)||
-     (BX_KEY_THIS s.mouse.delayed_dy<-256)) {
-    force_enq=1;
-  }
-
-  create_mouse_packet(force_enq);
-}
-
-
-  int
-bx_keyb_c::SaveState( class state_file *fd )
-{
-  fd->write_check ("keyboard start");
-  fd->write (&BX_KEY_THIS s, sizeof (BX_KEY_THIS s));
-  fd->write_check ("keyboard end");
-  return(0);
-}
-
-
-  int
-bx_keyb_c::LoadState( class state_file *fd )
-{
-  fd->read_check ("keyboard start");
-  fd->read (&BX_KEY_THIS s, sizeof (BX_KEY_THIS s));
-  fd->read_check ("keyboard end");
-  return(0);
-}
-
diff --git a/tools/ioemu/iodev/keyboard.h b/tools/ioemu/iodev/keyboard.h
deleted file mode 100644 (file)
index 24d9ccf..0000000
+++ /dev/null
@@ -1,234 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: keyboard.h,v 1.22 2003/07/13 19:51:21 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2001  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-#ifndef _PCKEY_H
-#define _PCKEY_H
-
-
-#define BX_KBD_ELEMENTS 16
-#define BX_MOUSE_BUFF_SIZE 48
-
-// these keywords should only be used in keyboard.cc
-#if BX_USE_KEY_SMF
-#  define BX_KEY_SMF  static
-#  define BX_KEY_THIS theKeyboard->
-#else
-#  define BX_KEY_SMF
-#  define BX_KEY_THIS 
-#endif
-
-#define MOUSE_MODE_RESET  10
-#define MOUSE_MODE_STREAM 11
-#define MOUSE_MODE_REMOTE 12
-#define MOUSE_MODE_WRAP   13
-
-class bx_keyb_c : public bx_keyb_stub_c {
-public:
-  bx_keyb_c(void);
-  ~bx_keyb_c(void);
-  // implement bx_devmodel_c interface
-  virtual void     init(void);
-  virtual void     reset(unsigned type);
-  // override stubs from bx_keyb_stub_c
-  virtual void     gen_scancode(Bit32u key);
-  virtual void     paste_bytes(Bit8u *data, Bit32s length);
-  virtual void     mouse_motion(int delta_x, int delta_y, unsigned button_state);
-
-  // update the paste delay based on bx_options.Okeyboard_paste_delay
-  virtual void     paste_delay_changed ();
-  virtual void     mouse_enabled_changed(bool enabled);
-
-private:
-  BX_KEY_SMF Bit8u    get_kbd_enable(void);
-  BX_KEY_SMF void     service_paste_buf ();
-  BX_KEY_SMF void     create_mouse_packet(bool force_enq);
-  BX_KEY_SMF void     mouse_button(unsigned mouse_state);
-  BX_KEY_SMF int      SaveState( class state_file *fd );
-  BX_KEY_SMF int      LoadState( class state_file *fd );
-  BX_KEY_SMF unsigned periodic( Bit32u   usec_delta );
-
-
-  static Bit32u read_handler(void *this_ptr, Bit32u address, unsigned io_len);
-  static void   write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);
-#if !BX_USE_KEY_SMF
-  void     write(Bit32u   address, Bit32u   value, unsigned io_len);
-  Bit32u   read(Bit32u   address, unsigned io_len);
-#endif
-
-  struct {
-    struct {
-      /* status bits matching the status port*/
-      bx_bool pare; // Bit7, 1= parity error from keyboard/mouse - ignored.
-      bx_bool tim;  // Bit6, 1= timeout from keyboard - ignored.
-      bx_bool auxb; // Bit5, 1= mouse data waiting for CPU to read.
-      bx_bool keyl; // Bit4, 1= keyswitch in lock position - ignored.
-      bx_bool c_d; /*  Bit3, 1=command to port 64h, 0=data to port 60h */
-      bx_bool sysf; // Bit2,
-      bx_bool inpb; // Bit1,
-      bx_bool outb; // Bit0, 1= keyboard data or mouse data ready for CPU
-                    //       check aux to see which. Or just keyboard
-                    //       data before AT style machines
-
-      /* internal to our version of the keyboard controller */
-      bx_bool kbd_clock_enabled;
-      bx_bool aux_clock_enabled;
-      bx_bool allow_irq1;
-      bx_bool allow_irq12;
-      Bit8u   kbd_output_buffer;
-      Bit8u   aux_output_buffer;
-      Bit8u   last_comm;
-      Bit8u   expecting_port60h;
-      Bit8u   expecting_mouse_parameter;
-      Bit8u   last_mouse_command;
-      Bit32u   timer_pending;
-      bx_bool irq1_requested;
-      bx_bool irq12_requested;
-      bx_bool scancodes_translate;
-      bx_bool expecting_scancodes_set;
-      Bit8u   current_scancodes_set;
-      } kbd_controller;
-
-    struct mouseStruct {
-      Bit8u   sample_rate;
-      Bit8u   resolution_cpmm; // resolution in counts per mm
-      Bit8u   scaling;
-      Bit8u   mode;
-      Bit8u   saved_mode;  // the mode prior to entering wrap mode
-      bx_bool enable;
-
-      Bit8u get_status_byte ()
-       {
-         // top bit is 0 , bit 6 is 1 if remote mode.
-         Bit8u ret = (Bit8u) ((mode == MOUSE_MODE_REMOTE) ? 0x40 : 0);
-         ret |= (enable << 5);
-         ret |= (scaling == 1) ? 0 : (1 << 4);
-         ret |= ((button_status & 0x1) << 2);
-         ret |= ((button_status & 0x2) << 0);
-         return ret;
-       }
-
-      Bit8u get_resolution_byte ()
-       {
-         Bit8u ret = 0;
-
-         switch (resolution_cpmm) {
-         case 1:
-           ret = 0;
-           break;
-
-         case 2:
-           ret = 1;
-           break;
-
-         case 4:
-           ret = 2;
-           break;
-
-         case 8:
-           ret = 3;
-           break;
-
-         default:
-           genlog->panic("mouse: invalid resolution_cpmm");
-         };
-         return ret;
-       }
-
-      Bit8u button_status;
-      Bit16s delayed_dx;
-      Bit16s delayed_dy;
-      } mouse;
-
-    struct {
-      int     num_elements;
-      Bit8u   buffer[BX_KBD_ELEMENTS];
-      int     head;
-      bx_bool expecting_typematic;
-      bx_bool expecting_led_write;
-      Bit8u   delay;
-      Bit8u   repeat_rate;
-      Bit8u   led_status;
-      bx_bool scanning_enabled;
-      } kbd_internal_buffer;
-
-    struct {
-      int     num_elements;
-      Bit8u   buffer[BX_MOUSE_BUFF_SIZE];
-      int     head;
-      } mouse_internal_buffer;
-#define BX_KBD_CONTROLLER_QSIZE 5
-    Bit8u    controller_Q[BX_KBD_CONTROLLER_QSIZE];
-    unsigned controller_Qsize;
-    unsigned controller_Qsource; // 0=keyboard, 1=mouse
-    } s; // State information for saving/loading
-
-  // The paste buffer does NOT exist in the hardware.  It is a bochs
-  // construction that allows the user to "paste" arbitrary length sequences of
-  // keystrokes into the emulated machine.  Since the hardware buffer is only
-  // 16 bytes, a very small amount of data can be added to the hardware buffer
-  // at a time.  The paste buffer keeps track of the bytes that have not yet
-  // been pasted.
-  //
-  // Lifetime of a paste buffer: The paste data comes from the system
-  // clipboard, which must be accessed using platform independent code in the
-  // gui.  Because every gui has its own way of managing the clipboard memory
-  // (in X windows, you're supposed to call Xfree for example), in the platform
-  // specific code we make a copy of the clipboard buffer with 
-  // "new Bit8u[length]".  Then the pointer is passed into
-  // bx_keyb_c::paste_bytes, along with the length.  The gui code never touches
-  // the pastebuf again, and does not free it.  The keyboard code is
-  // responsible for deallocating the paste buffer using delete [] buf.  The
-  // paste buffer is binary data, and it is probably NOT null terminated.  
-  //
-  // Summary: A paste buffer is allocated (new) in the platform-specific gui
-  // code, passed to the keyboard model, and is freed (delete[]) when it is no
-  // longer needed.
-  Bit8u *pastebuf;   // ptr to bytes to be pasted, or NULL if none in progress
-  Bit32u pastebuf_len; // length of pastebuf
-  Bit32u pastebuf_ptr; // ptr to next byte to be added to hw buffer
-  Bit32u pastedelay;   // count before paste
-  bx_bool stop_paste;  // stop the current paste operation on hardware reset
-
-  BX_KEY_SMF void     resetinternals(bx_bool powerup);
-  BX_KEY_SMF void     set_kbd_clock_enable(Bit8u   value) BX_CPP_AttrRegparmN(1);
-  BX_KEY_SMF void     set_aux_clock_enable(Bit8u   value);
-  BX_KEY_SMF void     kbd_ctrl_to_kbd(Bit8u   value);
-  BX_KEY_SMF void     kbd_ctrl_to_mouse(Bit8u   value);
-  BX_KEY_SMF void     kbd_enQ(Bit8u   scancode);
-  BX_KEY_SMF void     kbd_enQ_imm(Bit8u   val);
-  BX_KEY_SMF void     activate_timer(void);
-  BX_KEY_SMF void     controller_enQ(Bit8u   data, unsigned source);
-  BX_KEY_SMF bx_bool  mouse_enQ_packet(Bit8u   b1, Bit8u   b2, Bit8u   b3) BX_CPP_AttrRegparmN(3);
-  BX_KEY_SMF void     mouse_enQ(Bit8u   mouse_data);
-
-  static void   timer_handler(void *);
-  void   timer(void);
-  int    timer_handle;
-  };
-
-
-#endif  // #ifndef _PCKEY_H
diff --git a/tools/ioemu/iodev/load32bitOShack.cc b/tools/ioemu/iodev/load32bitOShack.cc
deleted file mode 100644 (file)
index 6a0a490..0000000
+++ /dev/null
@@ -1,322 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: load32bitOShack.cc,v 1.14 2003/08/08 00:05:53 cbothamy Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2001  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-
-
-#include "bochs.h"
-#define LOG_THIS genlog->
-
-
-
-static void bx_load_linux_hack(void);
-static void bx_load_null_kernel_hack(void);
-static Bit32u bx_load_kernel_image(char *path, Bit32u paddr);
-
-  void
-bx_load32bitOSimagehack(void)
-{
-  // Replay IO from log to initialize IO devices to
-  // a reasonable state needed for the OS.  This is done
-  // in lieu of running the 16-bit BIOS to init things,
-  // since we want to test straight 32bit stuff for
-  // freemware.
-
-#ifndef BX_USE_VMX
-  FILE *fp;
-
-  fp = fopen(bx_options.load32bitOSImage.Oiolog->getptr (), "r");
-
-  if (fp == NULL) {
-    BX_PANIC(("could not open IO init file."));
-    }
-
-  while (1) {
-    unsigned len, op, port, val;
-    int ret;
-    ret = fscanf(fp, "%u %u %x %x\n",
-      &len, &op, &port, &val);
-    if (ret != 4) {
-      BX_PANIC(("could not open IO init file."));
-      }
-    if (op == 0) {
-      // read
-      (void) bx_devices.inp(port, len);
-      }
-    else if (op == 1) {
-      // write
-      bx_devices.outp(port, val, len);
-      }
-    else {
-      BX_PANIC(("bad IO op in init filen"));
-      }
-    if (feof(fp)) break;
-    }
-#endif
-
-  // Invoke proper hack depending on which OS image we're loading
-  switch (bx_options.load32bitOSImage.OwhichOS->get ()) {
-    case Load32bitOSLinux:
-      bx_load_linux_hack();
-      break;
-    case Load32bitOSNullKernel:
-      bx_load_null_kernel_hack();
-      break;
-    default:
-      BX_PANIC(("load32bitOSImage: OS not recognized"));
-    }
-}
-
-struct gdt_entry
-{
-  Bit32u low;
-  Bit32u high;
-};
-struct linux_setup_params
-{
-   /* 0x000 */ Bit8u   orig_x;
-   /* 0x001 */ Bit8u   orig_y;
-   /* 0x002 */ Bit16u  memory_size_std;
-   /* 0x004 */ Bit16u  orig_video_page;
-   /* 0x006 */ Bit8u   orig_video_mode;
-   /* 0x007 */ Bit8u   orig_video_cols;
-   /* 0x008 */ Bit16u  unused1;
-   /* 0x00a */ Bit16u  orig_video_ega_bx;
-   /* 0x00c */ Bit16u  unused2;
-   /* 0x00e */ Bit8u   orig_video_lines;
-   /* 0x00f */ Bit8u   orig_video_isVGA;
-   /* 0x010 */ Bit16u  orig_video_points;
-   /* 0x012 */ Bit8u   pad1[0x40 - 0x12];
-   /* 0x040 */ Bit8u   apm_info[0x80 - 0x40];
-   /* 0x080 */ Bit8u   hd0_info[16];
-   /* 0x090 */ Bit8u   hd1_info[16];
-   /* 0x0a0 */ Bit8u   pad2[0x1e0 - 0xa0];
-   /* 0x1e0 */ Bit32u  memory_size_ext;
-   /* 0x1e4 */ Bit8u   pad3[0x1f1 - 0x1e4];
-   /* 0x1f1 */ Bit8u   setup_sects;
-   /* 0x1f2 */ Bit16u  mount_root_rdonly;
-   /* 0x1f4 */ Bit16u  sys_size;
-   /* 0x1f6 */ Bit16u  swap_dev;
-   /* 0x1f8 */ Bit16u  ramdisk_flags;
-   /* 0x1fa */ Bit16u  vga_mode;
-   /* 0x1fc */ Bit16u  orig_root_dev;
-   /* 0x1fe */ Bit16u  bootsect_magic;
-   /* 0x200 */ Bit8u   pad4[0x210 - 0x200];
-   /* 0x210 */ Bit32u  loader_type;
-   /* 0x214 */ Bit32u  kernel_start;
-   /* 0x218 */ Bit32u  initrd_start;
-   /* 0x21c */ Bit32u  initrd_size;
-   /* 0x220 */ Bit8u   pad5[0x400 - 0x220];
-   /* 0x400 */ struct  gdt_entry gdt[128];
-   /* 0x800 */ Bit8u   commandline[2048];
-};
-
-  static void
-bx_load_linux_setup_params( Bit32u initrd_start, Bit32u initrd_size )
-{
-  BX_MEM_C *mem = BX_MEM(0);
-  struct linux_setup_params *params =
-         (struct linux_setup_params *) &mem->vector[0x00090000];
-
-  memset( params, '\0', sizeof(*params) );
-
-  /* Video settings (standard VGA) */
-  params->orig_x = 0;
-  params->orig_y = 0;
-  params->orig_video_page = 0;
-  params->orig_video_mode = 3;
-  params->orig_video_cols = 80;
-  params->orig_video_lines = 25;
-  params->orig_video_points = 16;
-  params->orig_video_isVGA = 1;
-  params->orig_video_ega_bx = 3;
-
-  /* Memory size (total mem - 1MB, in KB) */
-  params->memory_size_ext = (mem->megabytes - 1) * 1024;
-
-  /* Boot parameters */
-  params->loader_type = 1;
-  params->bootsect_magic = 0xaa55;
-  params->mount_root_rdonly = 0;
-  params->orig_root_dev = 0x0100;
-  params->initrd_start = initrd_start;
-  params->initrd_size  = initrd_size;
-
-  /* Initial GDT */
-  params->gdt[2].high = 0x00cf9a00;
-  params->gdt[2].low  = 0x0000ffff;
-  params->gdt[3].high = 0x00cf9200;
-  params->gdt[3].low  = 0x0000ffff;
-}
-
-  void
-bx_load_linux_hack(void)
-{
-#ifndef BX_USE_VMX
-  Bit32u initrd_start = 0, initrd_size = 0;
-
-  // The RESET function will have been called first.
-  // Set CPU and memory features which are assumed at this point.
-
-  // Load Linux kernel image
-  bx_load_kernel_image( bx_options.load32bitOSImage.Opath->getptr (), 0x100000 );
-
-  // Load initial ramdisk image if requested
-  if ( bx_options.load32bitOSImage.Oinitrd->getptr () )
-  {
-    initrd_start = 0x00800000;  /* FIXME: load at top of memory */
-    initrd_size  = bx_load_kernel_image( bx_options.load32bitOSImage.Oinitrd->getptr (), initrd_start );
-  }
-
-  // Setup Linux startup parameters buffer
-  bx_load_linux_setup_params( initrd_start, initrd_size );
-#endif
-
-  // Enable A20 line
-  BX_SET_ENABLE_A20( 1 );
-
-  // Setup PICs the way Linux likes it
-  BX_OUTP( 0x20, 0x11, 1 );
-  BX_OUTP( 0xA0, 0x11, 1 );
-  BX_OUTP( 0x21, 0x20, 1 );
-  BX_OUTP( 0xA1, 0x28, 1 );
-  BX_OUTP( 0x21, 0x04, 1 );
-  BX_OUTP( 0xA1, 0x02, 1 );
-  BX_OUTP( 0x21, 0x01, 1 );
-  BX_OUTP( 0xA1, 0x01, 1 );
-  BX_OUTP( 0x21, 0xFF, 1 );
-  BX_OUTP( 0xA1, 0xFB, 1 );
-
-#ifndef BX_USE_VMX
-  // Disable interrupts and NMIs
-  BX_CPU(0)->clear_IF ();
-#endif
-
-  BX_OUTP( 0x70, 0x80, 1 );
-
-#ifndef BX_USE_VMX
-  // Enter protected mode
-  // Fixed by george (kyriazis at nvidia.com)
-  // BX_CPU(0)->cr0.pe = 1;
-  // BX_CPU(0)->cr0.val32 |= 0x01;
-
-  BX_CPU(0)->SetCR0(BX_CPU(0)->cr0.val32 | 0x01);
-  // load esi with real_mode
-  BX_CPU(0)->gen_reg[BX_32BIT_REG_ESI].dword.erx = 0x90000; 
-
-  // Set up initial GDT
-  BX_CPU(0)->gdtr.limit = 0x400;
-  BX_CPU(0)->gdtr.base  = 0x00090400;
-
-  // Jump to protected mode entry point
-  BX_CPU(0)->jump_protected( NULL, 0x10, 0x00100000 );
-#endif
-}
-
-  void
-bx_load_null_kernel_hack(void)
-{
-#ifndef BX_USE_VMX
-  // The RESET function will have been called first.
-  // Set CPU and memory features which are assumed at this point.
-
-  bx_load_kernel_image(bx_options.load32bitOSImage.Opath->getptr (), 0x100000);
-
-  // EIP deltas
-  BX_CPU(0)->prev_eip =
-  BX_CPU(0)->dword.eip = 0x00100000;
-
-  // CS deltas
-  BX_CPU(0)->sregs[BX_SEG_REG_CS].cache.u.segment.base = 0x00000000;
-  BX_CPU(0)->sregs[BX_SEG_REG_CS].cache.u.segment.limit = 0xFFFFF;
-  BX_CPU(0)->sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled = 0xFFFFFFFF;
-  BX_CPU(0)->sregs[BX_SEG_REG_CS].cache.u.segment.g   = 1; // page gran
-  BX_CPU(0)->sregs[BX_SEG_REG_CS].cache.u.segment.d_b = 1; // 32bit
-
-  // DS deltas
-  BX_CPU(0)->sregs[BX_SEG_REG_DS].cache.u.segment.base = 0x00000000;
-  BX_CPU(0)->sregs[BX_SEG_REG_DS].cache.u.segment.limit = 0xFFFFF;
-  BX_CPU(0)->sregs[BX_SEG_REG_DS].cache.u.segment.limit_scaled = 0xFFFFFFFF;
-  BX_CPU(0)->sregs[BX_SEG_REG_DS].cache.u.segment.g   = 1; // page gran
-  BX_CPU(0)->sregs[BX_SEG_REG_DS].cache.u.segment.d_b = 1; // 32bit
-
-  // CR0 deltas
-  BX_CPU(0)->cr0.pe = 1; // protected mode
-#endif // BX_USE_VMX
-}
-
-  Bit32u
-bx_load_kernel_image(char *path, Bit32u paddr)
-{
-  struct stat stat_buf;
-  int fd, ret;
-  unsigned long size, offset;
-  Bit32u page_size;
-
-  // read in ROM BIOS image file
-  fd = open(path, O_RDONLY
-#ifdef O_BINARY
-            | O_BINARY
-#endif
-           );
-  if (fd < 0) {
-    BX_INFO(( "load_kernel_image: couldn't open image file '%s'.", path ));
-    BX_EXIT(1);
-    }
-  ret = fstat(fd, &stat_buf);
-  if (ret) {
-    BX_INFO(( "load_kernel_image: couldn't stat image file '%s'.", path ));
-    BX_EXIT(1);
-    }
-
-  size = stat_buf.st_size;
-  page_size = ((Bit32u)size + 0xfff) & ~0xfff;
-
-  BX_MEM_C *mem = BX_MEM(0);
-  if ( (paddr + size) > mem->len ) {
-    BX_INFO(( "load_kernel_image: address range > physical memsize!" ));
-    BX_EXIT(1);
-    }
-
-  offset = 0;
-  while (size > 0) {
-    ret = read(fd, (bx_ptr_t) &mem->vector[paddr + offset], size);
-    if (ret <= 0) {
-      BX_INFO(( "load_kernel_image: read failed on image" ));
-      BX_EXIT(1);
-      }
-    size -= ret;
-    offset += ret;
-    }
-  close(fd);
-  BX_INFO(( "#(%u) load_kernel_image: '%s', size=%u read into memory at %08x",
-          BX_SIM_ID, path,
-          (unsigned) stat_buf.st_size,
-          (unsigned) paddr ));
-
-  return page_size;
-}
diff --git a/tools/ioemu/iodev/logio.cc b/tools/ioemu/iodev/logio.cc
deleted file mode 100644 (file)
index 2b79719..0000000
+++ /dev/null
@@ -1,631 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: logio.cc,v 1.42 2003/08/24 10:30:07 cbothamy Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2001  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-
-#include "bochs.h"
-#include <assert.h>
-#include "state_file.h"
-
-#if BX_WITH_CARBON
-#include <Carbon/Carbon.h>
-#endif
-
-// Just for the iofunctions
-
-
-int Allocio=0;
-
-void
-iofunctions::flush(void) {
-       if(logfd && magic == MAGIC_LOGNUM) {
-               fflush(logfd);
-       }
-}
-
-void
-iofunctions::init(void) {
-       // iofunctions methods must not be called before this magic
-       // number is set.
-       magic=MAGIC_LOGNUM;
-
-       // sets the default logprefix
-       strcpy(logprefix,"%t%e%d");
-       n_logfn = 0;
-       init_log(stderr);
-       log = new logfunc_t(this);
-       log->put("IO");
-       log->settype(IOLOG);
-       log->ldebug ("Init(log file: '%s').",logfn);
-}
-
-void
-iofunctions::add_logfn (logfunc_t *fn)
-{
-  assert (n_logfn < MAX_LOGFNS);
-  logfn_list[n_logfn++] = fn;
-}
-
-void
-iofunctions::set_log_action (int loglevel, int action)
-{
-  for (int i=0; i<n_logfn; i++)
-    logfn_list[i]->setonoff(loglevel, action);
-}
-
-void
-iofunctions::init_log(const char *fn)
-{
-       assert (magic==MAGIC_LOGNUM);
-       // use newfd/newfn so that we can log the message to the OLD log
-       // file descriptor.
-       FILE *newfd = stderr;
-       char *newfn = "/dev/stderr";
-       if( strcmp( fn, "-" ) != 0 ) {
-               newfd = fopen(fn, "w");
-               if(newfd != NULL) {
-                       newfn = strdup(fn);
-                       log->ldebug ("Opened log file '%s'.", fn );
-               } else {
-                       // in constructor, genlog might not exist yet, so do it the safe way.
-                       log->error("Couldn't open log file: %s, using stderr instead", fn);
-                       newfd = stderr;
-               }
-       }
-       logfd = newfd;
-       logfn = newfn;
-}
-
-void
-iofunctions::init_log(FILE *fs)
-{
-       assert (magic==MAGIC_LOGNUM);
-       logfd = fs;
-
-       if(fs == stderr) {
-               logfn = "/dev/stderr";
-       } else if(fs == stdout) { 
-               logfn = "/dev/stdout";
-       } else {
-               logfn = "(unknown)";
-       }
-
-}
-
-void
-iofunctions::init_log(int fd)
-{
-       assert (magic==MAGIC_LOGNUM);
-       FILE *tmpfd;
-       if( (tmpfd = fdopen(fd,"w")) == NULL ) {
-         log->panic("Couldn't open fd %d as a stream for writing", fd);
-         return;
-       }
-
-       init_log(tmpfd);
-       return;
-};
-
-// all other functions may use genlog safely.
-#define LOG_THIS genlog->
-
-// This converts the option string to a printf style string with the following args:
-// 1. timer, 2. event, 3. cpu0 eip, 4. device
-void 
-iofunctions::set_log_prefix(const char* prefix) {
-       
-       strcpy(logprefix,prefix);
-}
-
-//  iofunctions::out( class, level, prefix, fmt, ap)
-//  DO NOT nest out() from ::info() and the like.
-//    fmt and ap retained for direct printinf from iofunctions only!
-
-void
-iofunctions::out(int f, int l, const char *prefix, const char *fmt, va_list ap)
-{
-       char c=' ', *s;
-       assert (magic==MAGIC_LOGNUM);
-       assert (this != NULL);
-       assert (logfd != NULL);
-
-       //if( showtick )
-       //      fprintf(logfd, "%011lld", bx_pc_system.time_ticks());
-
-       switch(l) {
-               case LOGLEV_INFO: c='i'; break;
-               case LOGLEV_PANIC: c='p'; break;
-               case LOGLEV_PASS: c='s'; break;
-               case LOGLEV_ERROR: c='e'; break;
-               case LOGLEV_DEBUG: c='d'; break;
-               default: break;
-       }
-       //fprintf(logfd, "-%c",c);
-
-       //if(prefix != NULL)
-       //      fprintf(logfd, "%s ", prefix);
-
-       s=logprefix;
-       while(*s) {
-         switch(*s) {
-           case '%':
-             if(*(s+1))s++;
-             else break;
-             switch(*s) {
-               case 'd':
-                  fprintf(logfd, "%s", prefix==NULL?"":prefix);
-                 break;
-               case 't':
-                  fprintf(logfd, "%011lld", bx_pc_system.time_ticks());
-                 break;
-#ifndef BX_USE_VMX
-               case 'i':
-                  fprintf(logfd, "%08x", BX_CPU(0)==NULL?0:BX_CPU(0)->dword.eip);
-                 break;
-#endif
-               case 'e':
-                  fprintf(logfd, "%c", c);
-                 break;
-               case '%':
-                  fprintf(logfd,"%%");
-                 break;
-               default:
-                  fprintf(logfd,"%%%c",*s);
-               }
-              break;
-           default :
-              fprintf(logfd,"%c",*s);
-           }
-         s++;
-          }
-
-        fprintf(logfd," ");
-
-       if(l==LOGLEV_PANIC)
-               fprintf(logfd, ">>PANIC<< ");
-       if(l==LOGLEV_PASS)
-               fprintf(logfd, ">>PASS<< ");
-
-       vfprintf(logfd, fmt, ap);
-       fprintf(logfd, "\n");
-       fflush(logfd);
-
-       return;
-}
-
-iofunctions::iofunctions(FILE *fs)
-{
-       init();
-       init_log(fs);
-}
-
-iofunctions::iofunctions(const char *fn)
-{
-       init();
-       init_log(fn);
-}
-
-iofunctions::iofunctions(int fd)
-{
-       init();
-       init_log(fd);
-}
-
-iofunctions::iofunctions(void)
-{
-       this->init();
-}
-
-iofunctions::~iofunctions(void)
-{
-       // flush before erasing magic number, or flush does nothing.
-       this->flush();
-       this->magic=0;
-}
-
-#define LOG_THIS genlog->
-
-int logfunctions::default_onoff[N_LOGLEV] = {
-  ACT_IGNORE,  // ignore debug
-  ACT_REPORT,  // report info
-  ACT_REPORT,  // report error
-#if BX_WITH_WX
-  ACT_ASK,      // on panic, ask user what to do
-#else
-  ACT_FATAL,    // on panic, quit
-#endif
-  ACT_FATAL
-};
-
-logfunctions::logfunctions(void)
-{
-       prefix = NULL;
-       put(" ");
-       settype(GENLOG);
-       if (io == NULL && Allocio == 0) {
-               Allocio = 1;
-               io = new iofunc_t(stderr);
-       }
-       setio(io);
-       // BUG: unfortunately this can be called before the bochsrc is read,
-       // which means that the bochsrc has no effect on the actions.
-       for (int i=0; i<N_LOGLEV; i++)
-         onoff[i] = get_default_action(i);
-}
-
-logfunctions::logfunctions(iofunc_t *iofunc)
-{
-       prefix = NULL;
-       put(" ");
-       settype(GENLOG);
-       setio(iofunc);
-       // BUG: unfortunately this can be called before the bochsrc is read,
-       // which means that the bochsrc has no effect on the actions.
-       for (int i=0; i<N_LOGLEV; i++)
-         onoff[i] = get_default_action(i);
-}
-
-logfunctions::~logfunctions(void)
-{
-    if ( this->prefix )
-    {
-        free(this->prefix);
-        this->prefix = NULL;
-    }
-}
-
-void
-logfunctions::setio(iofunc_t *i)
-{
-       // add pointer to iofunction object to use
-       this->logio = i;
-       // give iofunction a pointer to me
-       i->add_logfn (this);
-}
-
-void
-logfunctions::put(char *p)
-{
-       char *tmpbuf;
-       tmpbuf=strdup("[     ]");// if we ever have more than 32 chars,
-                                                  //  we need to rethink this
-
-       if ( tmpbuf == NULL)
-       {
-           return ;                        /* allocation not successful */
-       }
-       if ( this->prefix != NULL )
-       {
-           free(this->prefix);             /* free previously allocated memory */
-           this->prefix = NULL;
-       }
-       int len=strlen(p);
-       for(int i=1;i<len+1;i++) {
-               tmpbuf[i]=p[i-1];
-       }
-               
-       switch(len) {
-       case  1: tmpbuf[2]=' ';
-       case  2: tmpbuf[3]=' ';
-       case  3: tmpbuf[4]=' ';
-       case  4: tmpbuf[5]=' ';
-       default: tmpbuf[6]=']'; tmpbuf[7]='\0'; break;
-       }
-       
-       this->prefix=tmpbuf;
-}
-
-void
-logfunctions::settype(int t)
-{
-       type=t;
-}
-
-void
-logfunctions::info(const char *fmt, ...)
-{
-       va_list ap;
-
-       assert (this != NULL);
-       assert (this->logio != NULL);
-
-       if(!onoff[LOGLEV_INFO]) return;
-
-       va_start(ap, fmt);
-       this->logio->out(this->type,LOGLEV_INFO,this->prefix, fmt, ap);
-       if (onoff[LOGLEV_INFO] == ACT_ASK) 
-         ask (LOGLEV_INFO, this->prefix, fmt, ap);
-       if (onoff[LOGLEV_INFO] == ACT_FATAL) 
-         fatal (this->prefix, fmt, ap, 1);
-       va_end(ap);
-
-}
-
-void
-logfunctions::error(const char *fmt, ...)
-{
-       va_list ap;
-
-       assert (this != NULL);
-       assert (this->logio != NULL);
-
-       if(!onoff[LOGLEV_ERROR]) return;
-
-       va_start(ap, fmt);
-       this->logio->out(this->type,LOGLEV_ERROR,this->prefix, fmt, ap);
-       if (onoff[LOGLEV_ERROR] == ACT_ASK) 
-         ask (LOGLEV_ERROR, this->prefix, fmt, ap);
-       if (onoff[LOGLEV_ERROR] == ACT_FATAL) 
-         fatal (this->prefix, fmt, ap, 1);
-       va_end(ap);
-}
-
-void
-logfunctions::panic(const char *fmt, ...)
-{
-       va_list ap;
-
-       assert (this != NULL);
-       assert (this->logio != NULL);
-
-       // Special case for panics since they are so important.  Always print
-       // the panic to the log, no matter what the log action says.
-       //if(!onoff[LOGLEV_PANIC]) return;
-
-       va_start(ap, fmt);
-       this->logio->out(this->type,LOGLEV_PANIC,this->prefix, fmt, ap);
-
-       // This fixes a funny bug on linuxppc where va_list is no pointer but a struct
-       va_end(ap);
-       va_start(ap, fmt);
-
-       if (onoff[LOGLEV_PANIC] == ACT_ASK) 
-         ask (LOGLEV_PANIC, this->prefix, fmt, ap);
-       if (onoff[LOGLEV_PANIC] == ACT_FATAL) 
-         fatal (this->prefix, fmt, ap, 1);
-       va_end(ap);
-}
-
-void
-logfunctions::pass(const char *fmt, ...)
-{
-       va_list ap;
-
-       assert (this != NULL);
-       assert (this->logio != NULL);
-
-       // Special case for panics since they are so important.  Always print
-       // the panic to the log, no matter what the log action says.
-       //if(!onoff[LOGLEV_PASS]) return;
-
-       va_start(ap, fmt);
-       this->logio->out(this->type,LOGLEV_PASS,this->prefix, fmt, ap);
-
-       // This fixes a funny bug on linuxppc where va_list is no pointer but a struct
-       va_end(ap);
-       va_start(ap, fmt);
-
-       if (onoff[LOGLEV_PASS] == ACT_ASK) 
-         ask (LOGLEV_PASS, this->prefix, fmt, ap);
-       if (onoff[LOGLEV_PASS] == ACT_FATAL) 
-         fatal (this->prefix, fmt, ap, 101);
-       va_end(ap);
-}
-
-void
-logfunctions::ldebug(const char *fmt, ...)
-{
-       va_list ap;
-
-       assert (this != NULL);
-       assert (this->logio != NULL);
-
-       if(!onoff[LOGLEV_DEBUG]) return;
-
-       va_start(ap, fmt);
-       this->logio->out(this->type,LOGLEV_DEBUG,this->prefix, fmt, ap);
-       if (onoff[LOGLEV_DEBUG] == ACT_ASK) 
-         ask (LOGLEV_DEBUG, this->prefix, fmt, ap);
-       if (onoff[LOGLEV_DEBUG] == ACT_FATAL) 
-         fatal (this->prefix, fmt, ap, 1);
-       va_end(ap);
-}
-
-void
-logfunctions::ask (int level, const char *prefix, const char *fmt, va_list ap)
-{
-  // Guard against reentry on ask() function.  The danger is that some
-  // function that's called within ask() could trigger another
-  // BX_PANIC that could call ask() again, leading to infinite
-  // recursion and infinite asks.
-  static char in_ask_already = 0;
-  char buf1[1024];
-  if (in_ask_already) {
-    fprintf (stderr, "logfunctions::ask() should not reenter!!\n");
-    return;
-  }
-  in_ask_already = 1;
-  vsprintf (buf1, fmt, ap);
-  // FIXME: facility set to 0 because it's unknown.
-
-  // update vga screen.  This is useful because sometimes useful messages
-  // are printed on the screen just before a panic.  It's also potentially
-  // dangerous if this function calls ask again...  That's why I added
-  // the reentry check above.
-  if (SIM->get_init_done()) DEV_vga_refresh();
-
-#if !BX_EXTERNAL_DEBUGGER
-  // ensure the text screen is showing
-  SIM->set_display_mode (DISP_MODE_CONFIG);
-  int val = SIM->log_msg (prefix, level, buf1);
-  switch (val)
-  {
-    case BX_LOG_ASK_CHOICE_CONTINUE:
-      break;
-    case BX_LOG_ASK_CHOICE_CONTINUE_ALWAYS:
-      // user said continue, and don't "ask" for this facility again.
-      setonoff (level, ACT_REPORT);
-      break;
-    case BX_LOG_ASK_CHOICE_DIE:
-      bx_user_quit = 1;
-      in_ask_already = 0;  // because fatal will longjmp out
-      fatal (prefix, fmt, ap, 1);
-      // should never get here
-      BX_PANIC (("in ask(), fatal() should never return!"));
-      break;
-    case BX_LOG_ASK_CHOICE_DUMP_CORE:
-      fprintf (stderr, "User chose to dump core...\n");
-#if BX_HAVE_ABORT
-      abort ();
-#else
-      // do something highly illegal that should kill the process.
-      // Hey, this is fun!
-      {
-      char *crashptr = (char *)0; char c = *crashptr;
-      }
-      fprintf (stderr, "Sorry, I couldn't find your abort() function.  Exiting.");
-      exit (0);
-#endif
-#if BX_DEBUGGER
-    case BX_LOG_ASK_CHOICE_ENTER_DEBUG:
-      // user chose debugger.  To "drop into the debugger" we just set the
-      // interrupt_requested bit and continue execution.  Before the next
-      // instruction, it should notice the user interrupt and return to
-      // the debugger.
-      bx_guard.interrupt_requested = 1;
-      break;
-#endif
-    default:
-      // this happens if panics happen before the callback is initialized
-      // in gui/control.cc.
-      fprintf (stderr, "WARNING: log_msg returned unexpected value %d\n", val);
-  }
-#else
-  // external debugger ask code goes here
-#endif
-  // return to simulation mode
-  SIM->set_display_mode (DISP_MODE_SIM);
-  in_ask_already = 0;
-}
-
-#if BX_WITH_CARBON
-/* Panic button to display fatal errors.
-  Completely self contained, can't rely on carbon.cc being available */
-static void carbonFatalDialog(const char *error, const char *exposition)
-{
-  DialogRef                     alertDialog;
-  CFStringRef                   cfError;
-  CFStringRef                   cfExposition;
-  DialogItemIndex               index;
-  AlertStdCFStringAlertParamRec alertParam = {0};
-  
-  // Init libraries
-  InitCursor();
-  // Assemble dialog
-  cfError = CFStringCreateWithCString(NULL, error, kCFStringEncodingASCII);
-  if(exposition != NULL)
-  {
-    cfExposition = CFStringCreateWithCString(NULL, exposition, kCFStringEncodingASCII);
-  }
-  else { cfExposition = NULL; }
-  alertParam.version       = kStdCFStringAlertVersionOne;
-  alertParam.defaultText   = CFSTR("Quit");
-  alertParam.position      = kWindowDefaultPosition;
-  alertParam.defaultButton = kAlertStdAlertOKButton;
-  // Display Dialog
-  CreateStandardAlert(
-    kAlertStopAlert,
-    cfError,
-    cfExposition,       /* can be NULL */
-    &alertParam,             /* can be NULL */
-    &alertDialog);
-  RunStandardAlert( alertDialog, NULL, &index);
-  // Cleanup
-  CFRelease( cfError );
-  if( cfExposition != NULL ) { CFRelease( cfExposition ); }
-}
-#endif
-
-void
-logfunctions::fatal (const char *prefix, const char *fmt, va_list ap, int exit_status)
-{
-  bx_atexit();
-#if BX_WITH_CARBON
-  if(!isatty(STDIN_FILENO) && !SIM->get_init_done())
-  {
-    char buf1[1024];
-    char buf2[1024];
-    vsprintf (buf1, fmt, ap);
-    sprintf (buf2, "Bochs startup error\n%s", buf1);
-    carbonFatalDialog(buf2,
-      "For more information, try running Bochs within Terminal by clicking on \"bochs.scpt\".");
-  }
-#endif
-#if !BX_WITH_WX
-  static char *divider = "========================================================================";
-  fprintf (stderr, "%s\n", divider);
-  fprintf (stderr, "Bochs is exiting with the following message:\n");
-  fprintf (stderr, "%s ", prefix);
-  vfprintf (stderr, fmt, ap);
-  fprintf (stderr, "\n%s\n", divider);
-#endif
-#if 0 && defined(WIN32)
-#error disabled because it is not working yet!
-  // wait for a keypress before quitting.  Depending on how bochs is
-  // installed, the console window can disappear before the user has
-  // a chance to read the final message.
-  fprintf (stderr, "\n\nPress Enter to exit...\n");
-  char buf[8];
-  fgets (buf, 8, stdin);
-#endif
-#if !BX_DEBUGGER
-  BX_EXIT(exit_status);
-#else
-  static bx_bool dbg_exit_called = 0;
-  if (dbg_exit_called == 0) {
-    dbg_exit_called = 1;
-    bx_dbg_exit(exit_status);
-    }
-#endif
-  // not safe to use BX_* log functions in here.
-  fprintf (stderr, "fatal() should never return, but it just did\n");
-}
-
-iofunc_t *io = NULL;
-logfunc_t *genlog = NULL;
-
-void bx_center_print (FILE *file, char *line, int maxwidth)
-{
-  int imax;
-  int len = strlen(line);
-  if (len > maxwidth)
-    BX_PANIC (("bx_center_print: line is too long: '%s'", line));
-  imax = (maxwidth - len) >> 1;
-  for (int i=0; i<imax; i++) fputc (' ', file);
-  fputs (line, file);
-}
-
-
diff --git a/tools/ioemu/iodev/main.cc b/tools/ioemu/iodev/main.cc
deleted file mode 100644 (file)
index e82f47d..0000000
+++ /dev/null
@@ -1,4071 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: main.cc,v 1.256.2.3 2004/02/08 14:39:50 cbothamy Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//  Copyright (C) 2004  Arun Sharma <arun.sharma@intel.com>
-//  Copyright (C) 2004  Intel Corp
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-#include "bochs.h"
-#include <assert.h>
-#include "state_file.h"
-
-#ifdef HAVE_LOCALE_H
-#include <locale.h>
-#endif
-
-extern "C" {
-#include <signal.h>
-}
-
-#if BX_GUI_SIGHANDLER
-bx_bool bx_gui_sighandler = 0;
-#endif
-
-// single processor simulation, so there's one of everything
-BOCHSAPI BX_CPU_C    bx_cpu;
-BOCHSAPI BX_MEM_C    bx_mem;
-
-int xc_handle;
-int bochsrc_include_count = 0;
-
-// some prototypes from iodev/
-// I want to stay away from including iodev/iodev.h here
-Bit32u bx_unmapped_io_read_handler(Bit32u address, unsigned io_len);
-void   bx_unmapped_io_write_handler(Bit32u address, Bit32u value,
-                                    unsigned io_len);
-void   bx_close_harddrive(void);
-
-
-void bx_init_bx_dbg (void);
-static char *divider = "========================================================================";
-static logfunctions thePluginLog;
-logfunctions *pluginlog = &thePluginLog;
-
-bx_startup_flags_t bx_startup_flags;
-bx_bool bx_user_quit;
-
-/* typedefs */
-
-#define LOG_THIS genlog->
-
-#if ( BX_PROVIDE_DEVICE_MODELS==1 )
-bx_pc_system_c bx_pc_system;
-class state_file state_stuff("state_file.out", "options");
-#endif
-
-bx_debug_t bx_dbg;
-
-bx_options_t bx_options; // initialized in bx_init_options()
-char *bochsrc_filename = NULL;
-
-static Bit32s parse_line_unformatted(char *context, char *line);
-static Bit32s parse_line_formatted(char *context, int num_params, char *params[]);
-static int parse_bochsrc(char *rcfile);
-
-static Bit64s
-bx_param_handler (bx_param_c *param, int set, Bit64s val)
-{
-  bx_id id = param->get_id ();
-  switch (id) {
-    case BXP_VGA_UPDATE_INTERVAL:
-      // if after init, notify the vga device to change its timer.
-      if (set && SIM->get_init_done ())
-        DEV_vga_set_update_interval (val);
-      break;
-    case BXP_MOUSE_ENABLED:
-      // if after init, notify the GUI
-      if (set && SIM->get_init_done ()) {
-        bx_gui->mouse_enabled_changed (val!=0);
-        DEV_mouse_enabled_changed (val!=0);
-      }
-      break;
-    case BXP_NE2K_PRESENT:
-      if (set) {
-        int enable = (val != 0);
-        SIM->get_param (BXP_NE2K_IOADDR)->set_enabled (enable);
-        SIM->get_param (BXP_NE2K_IRQ)->set_enabled (enable);
-        SIM->get_param (BXP_NE2K_MACADDR)->set_enabled (enable);
-        SIM->get_param (BXP_NE2K_ETHMOD)->set_enabled (enable);
-        SIM->get_param (BXP_NE2K_ETHDEV)->set_enabled (enable);
-        SIM->get_param (BXP_NE2K_SCRIPT)->set_enabled (enable);
-      }
-      break;
-    case BXP_LOAD32BITOS_WHICH:
-      if (set) {
-        int enable = (val != Load32bitOSNone);
-        SIM->get_param (BXP_LOAD32BITOS_PATH)->set_enabled (enable);
-        SIM->get_param (BXP_LOAD32BITOS_IOLOG)->set_enabled (enable);
-        SIM->get_param (BXP_LOAD32BITOS_INITRD)->set_enabled (enable);
-      }
-      break;
-    case BXP_ATA0_MASTER_STATUS:
-    case BXP_ATA0_SLAVE_STATUS:
-    case BXP_ATA1_MASTER_STATUS:
-    case BXP_ATA1_SLAVE_STATUS:
-    case BXP_ATA2_MASTER_STATUS:
-    case BXP_ATA2_SLAVE_STATUS:
-    case BXP_ATA3_MASTER_STATUS:
-    case BXP_ATA3_SLAVE_STATUS:
-      if ((set) && (SIM->get_init_done ())) {
-        Bit8u device = id - BXP_ATA0_MASTER_STATUS;
-        Bit32u handle = DEV_hd_get_device_handle (device/2, device%2);
-        DEV_hd_set_cd_media_status(handle, val == BX_INSERTED);
-        bx_gui->update_drive_status_buttons ();
-      }
-      break;
-    case BXP_FLOPPYA_TYPE:
-      if ((set) && (!SIM->get_init_done ())) {
-        bx_options.floppya.Odevtype->set (val);
-      }
-      break;
-    case BXP_FLOPPYA_STATUS:
-      if ((set) && (SIM->get_init_done ())) {
-        DEV_floppy_set_media_status(0, val == BX_INSERTED);
-        bx_gui->update_drive_status_buttons ();
-      }
-      break;
-    case BXP_FLOPPYB_TYPE:
-      if ((set) && (!SIM->get_init_done ())) {
-        bx_options.floppyb.Odevtype->set (val);
-      }
-      break;
-    case BXP_FLOPPYB_STATUS:
-      if ((set) && (SIM->get_init_done ())) {
-        DEV_floppy_set_media_status(1, val == BX_INSERTED);
-        bx_gui->update_drive_status_buttons ();
-      }
-      break;
-    case BXP_KBD_PASTE_DELAY:
-      if ((set) && (SIM->get_init_done ())) {
-        DEV_kbd_paste_delay_changed ();
-        }
-      break;
-
-    case BXP_ATA0_MASTER_MODE:
-    case BXP_ATA0_SLAVE_MODE:
-    case BXP_ATA1_MASTER_MODE:
-    case BXP_ATA1_SLAVE_MODE:
-    case BXP_ATA2_MASTER_MODE:
-    case BXP_ATA2_SLAVE_MODE:
-    case BXP_ATA3_MASTER_MODE:
-    case BXP_ATA3_SLAVE_MODE:
-      if (set) {
-        int device = id - BXP_ATA0_MASTER_MODE;
-        switch (val) {
-          case BX_ATA_MODE_UNDOABLE:
-          case BX_ATA_MODE_VOLATILE:
-          //case BX_ATA_MODE_Z_UNDOABLE:
-          //case BX_ATA_MODE_Z_VOLATILE:
-            SIM->get_param ((bx_id)(BXP_ATA0_MASTER_JOURNAL + device))->set_enabled (1);
-            break;
-          default:
-            SIM->get_param ((bx_id)(BXP_ATA0_MASTER_JOURNAL + device))->set_enabled (0);
-          }
-        }
-      break;
-
-    case BXP_ATA0_MASTER_TYPE:
-    case BXP_ATA0_SLAVE_TYPE:
-    case BXP_ATA1_MASTER_TYPE:
-    case BXP_ATA1_SLAVE_TYPE:
-    case BXP_ATA2_MASTER_TYPE:
-    case BXP_ATA2_SLAVE_TYPE:
-    case BXP_ATA3_MASTER_TYPE:
-    case BXP_ATA3_SLAVE_TYPE:
-      if (set) {
-        int device = id - BXP_ATA0_MASTER_TYPE;
-        switch (val) {
-          case BX_ATA_DEVICE_DISK:
-            SIM->get_param_num ((bx_id)(BXP_ATA0_MASTER_PRESENT + device))->set (1);
-            SIM->get_param ((bx_id)(BXP_ATA0_MASTER_MODE + device))->set_enabled (1);
-            SIM->get_param ((bx_id)(BXP_ATA0_MASTER_PATH + device))->set_enabled (1);
-            //SIM->get_param ((bx_id)(BXP_ATA0_MASTER_JOURNAL + device))->set_enabled (1);
-            SIM->get_param ((bx_id)(BXP_ATA0_MASTER_CYLINDERS + device))->set_enabled (1);
-            SIM->get_param ((bx_id)(BXP_ATA0_MASTER_HEADS + device))->set_enabled (1);
-            SIM->get_param ((bx_id)(BXP_ATA0_MASTER_SPT + device))->set_enabled (1);
-            SIM->get_param ((bx_id)(BXP_ATA0_MASTER_STATUS + device))->set_enabled (0);
-            SIM->get_param ((bx_id)(BXP_ATA0_MASTER_MODEL + device))->set_enabled (1);
-            SIM->get_param ((bx_id)(BXP_ATA0_MASTER_BIOSDETECT + device))->set_enabled (1);
-            SIM->get_param ((bx_id)(BXP_ATA0_MASTER_TRANSLATION + device))->set_enabled (1);
-            SIM->get_param ((bx_id)(BXP_ATA0_MASTER_PATH + device))->set_runtime_param (0);
-            SIM->get_param ((bx_id)(BXP_ATA0_MASTER_STATUS + device))->set_runtime_param (0);
-            break;
-          case BX_ATA_DEVICE_CDROM:
-            SIM->get_param_num ((bx_id)(BXP_ATA0_MASTER_PRESENT + device))->set (1);
-            SIM->get_param ((bx_id)(BXP_ATA0_MASTER_MODE + device))->set_enabled (0);
-            SIM->get_param ((bx_id)(BXP_ATA0_MASTER_PATH + device))->set_enabled (1);
-            SIM->get_param ((bx_id)(BXP_ATA0_MASTER_JOURNAL + device))->set_enabled (0);
-            SIM->get_param ((bx_id)(BXP_ATA0_MASTER_CYLINDERS + device))->set_enabled (0);
-            SIM->get_param ((bx_id)(BXP_ATA0_MASTER_HEADS + device))->set_enabled (0);
-            SIM->get_param ((bx_id)(BXP_ATA0_MASTER_SPT + device))->set_enabled (0);
-            SIM->get_param ((bx_id)(BXP_ATA0_MASTER_STATUS + device))->set_enabled (1);
-            SIM->get_param ((bx_id)(BXP_ATA0_MASTER_MODEL + device))->set_enabled (1);
-            SIM->get_param ((bx_id)(BXP_ATA0_MASTER_BIOSDETECT + device))->set_enabled (1);
-            SIM->get_param ((bx_id)(BXP_ATA0_MASTER_TRANSLATION + device))->set_enabled (0);
-            SIM->get_param ((bx_id)(BXP_ATA0_MASTER_PATH + device))->set_runtime_param (1);
-            SIM->get_param ((bx_id)(BXP_ATA0_MASTER_STATUS + device))->set_runtime_param (1);
-            break;
-          }
-        }
-      break;
-    default:
-      BX_PANIC (("bx_param_handler called with unknown id %d", id));
-      return -1;
-  }
-  return val;
-}
-
-char *bx_param_string_handler (bx_param_string_c *param, int set, char *val, int maxlen)
-{
-  bx_id id = param->get_id ();
-
-  int empty = 0;
-  if ((strlen(val) < 1) || !strcmp ("none", val)) {
-    empty = 1;
-    val = "none";
-  }
-  switch (id) {
-    case BXP_FLOPPYA_PATH:
-      if (set==1) {
-        if (SIM->get_init_done ()) {
-          if (empty) {
-            DEV_floppy_set_media_status(0, 0);
-            bx_gui->update_drive_status_buttons ();
-          } else {
-            if (!SIM->get_param_num(BXP_FLOPPYA_TYPE)->get_enabled()) {
-              BX_ERROR(("Cannot add a floppy drive at runtime"));
-              bx_options.floppya.Opath->set ("none");
-            }
-          }
-          if ((DEV_floppy_present()) &&
-              (SIM->get_param_num(BXP_FLOPPYA_STATUS)->get () == BX_INSERTED)) {
-            // tell the device model that we removed, then inserted the disk
-            DEV_floppy_set_media_status(0, 0);
-            DEV_floppy_set_media_status(0, 1);
-          }
-        } else {
-          SIM->get_param_num(BXP_FLOPPYA_DEVTYPE)->set_enabled (!empty);
-          SIM->get_param_num(BXP_FLOPPYA_TYPE)->set_enabled (!empty);
-          SIM->get_param_num(BXP_FLOPPYA_STATUS)->set_enabled (!empty);
-        }
-      }
-      break;
-    case BXP_FLOPPYB_PATH:
-      if (set==1) {
-        if (SIM->get_init_done ()) {
-          if (empty) {
-            DEV_floppy_set_media_status(1, 0);
-            bx_gui->update_drive_status_buttons ();
-          } else {
-            if (!SIM->get_param_num(BXP_FLOPPYB_TYPE)->get_enabled ()) {
-              BX_ERROR(("Cannot add a floppy drive at runtime"));
-              bx_options.floppyb.Opath->set ("none");
-            }
-          }
-          if ((DEV_floppy_present()) &&
-              (SIM->get_param_num(BXP_FLOPPYB_STATUS)->get () == BX_INSERTED)) {
-            // tell the device model that we removed, then inserted the disk
-            DEV_floppy_set_media_status(1, 0);
-            DEV_floppy_set_media_status(1, 1);
-          }
-        } else {
-          SIM->get_param_num(BXP_FLOPPYB_DEVTYPE)->set_enabled (!empty);
-          SIM->get_param_num(BXP_FLOPPYB_TYPE)->set_enabled (!empty);
-          SIM->get_param_num(BXP_FLOPPYB_STATUS)->set_enabled (!empty);
-        }
-      }
-      break;
-
-    case BXP_ATA0_MASTER_PATH:
-    case BXP_ATA0_SLAVE_PATH:
-    case BXP_ATA1_MASTER_PATH:
-    case BXP_ATA1_SLAVE_PATH:
-    case BXP_ATA2_MASTER_PATH:
-    case BXP_ATA2_SLAVE_PATH:
-    case BXP_ATA3_MASTER_PATH:
-    case BXP_ATA3_SLAVE_PATH:
-      if (set==1) {
-        if (SIM->get_init_done ()) {
-
-          Bit8u device = id - BXP_ATA0_MASTER_PATH;
-          Bit32u handle = DEV_hd_get_device_handle(device/2, device%2);
-
-          if (empty) {
-            DEV_hd_set_cd_media_status(handle, 0);
-            bx_gui->update_drive_status_buttons ();
-          } else {
-            if (!SIM->get_param_num((bx_id)(BXP_ATA0_MASTER_PRESENT + device))->get ()) {
-              BX_ERROR(("Cannot add a cdrom drive at runtime"));
-              bx_options.atadevice[device/2][device%2].Opresent->set (0);
-            }
-            if (SIM->get_param_num((bx_id)(BXP_ATA0_MASTER_TYPE + device))->get () != BX_ATA_DEVICE_CDROM) {
-              BX_ERROR(("Device is not a cdrom drive"));
-              bx_options.atadevice[device/2][device%2].Opresent->set (0);
-            }
-          }
-          if (DEV_hd_present() &&
-              (SIM->get_param_num((bx_id)(BXP_ATA0_MASTER_STATUS + device))->get () == BX_INSERTED) &&
-              (SIM->get_param_num((bx_id)(BXP_ATA0_MASTER_TYPE + device))->get () == BX_ATA_DEVICE_CDROM)) {
-            // tell the device model that we removed, then inserted the cd
-            DEV_hd_set_cd_media_status(handle, 0);
-            DEV_hd_set_cd_media_status(handle, 1);
-          }
-        }
-      }
-      break;
-    
-    case BXP_SCREENMODE:
-      if (set==1) {
-        BX_INFO (("Screen mode changed to %s", val));
-      }
-      break;
-    default:
-        BX_PANIC (("bx_string_handler called with unexpected parameter %d", param->get_id()));
-  }
-  return val;
-}
-
-static int
-bx_param_enable_handler (bx_param_c *param, int val)
-{
-  bx_id id = param->get_id ();
-  switch (id) {
-    case BXP_ATA0_MASTER_STATUS:
-    case BXP_ATA0_SLAVE_STATUS:
-    case BXP_ATA1_MASTER_STATUS:
-    case BXP_ATA1_SLAVE_STATUS:
-    case BXP_ATA2_MASTER_STATUS:
-    case BXP_ATA2_SLAVE_STATUS:
-    case BXP_ATA3_MASTER_STATUS:
-    case BXP_ATA3_SLAVE_STATUS:
-      if (val != 0) {
-        Bit8u device = id - BXP_ATA0_MASTER_STATUS;
-  
-        switch (SIM->get_param_enum ((bx_id)(BXP_ATA0_MASTER_TYPE + device))->get()) {
-          case BX_ATA_DEVICE_CDROM:
-            return (1);
-            break;
-          }
-        }
-      return (0);
-      break;
-
-    case BXP_ATA0_MASTER_JOURNAL:
-    case BXP_ATA0_SLAVE_JOURNAL:
-    case BXP_ATA1_MASTER_JOURNAL:
-    case BXP_ATA1_SLAVE_JOURNAL:
-    case BXP_ATA2_MASTER_JOURNAL:
-    case BXP_ATA2_SLAVE_JOURNAL:
-    case BXP_ATA3_MASTER_JOURNAL:
-    case BXP_ATA3_SLAVE_JOURNAL:
-      if (val != 0) {
-        Bit8u device = id - BXP_ATA0_MASTER_JOURNAL;
-  
-        switch (SIM->get_param_enum ((bx_id)(BXP_ATA0_MASTER_TYPE + device))->get()) {
-          case BX_ATA_DEVICE_DISK:
-            switch (SIM->get_param_enum ((bx_id)(BXP_ATA0_MASTER_MODE + device))->get()) {
-              case BX_ATA_MODE_UNDOABLE:
-              case BX_ATA_MODE_VOLATILE:
-              //case BX_ATA_MODE_Z_UNDOABLE:
-              //case BX_ATA_MODE_Z_VOLATILE:
-              return (1);
-              break;
-            }
-          }
-        }
-      return (0);
-      break;
-
-    default:
-      BX_PANIC (("bx_param_handler called with unknown id %d", id));
-  }
-  return val;
-}
-
-
-
-void bx_init_options ()
-{
-  int i;
-  bx_list_c *menu;
-  bx_list_c *deplist;
-  char name[1024], descr[1024], label[1024];
-
-  memset (&bx_options, 0, sizeof(bx_options));
-
-  // quick start option, set by command line arg
-  new bx_param_enum_c (BXP_BOCHS_START,
-      "Bochs start types",
-      "Bochs start types",
-      bochs_start_names,
-      BX_RUN_START,
-      BX_QUICK_START);
-
-  // floppya
-  bx_options.floppya.Opath = new bx_param_filename_c (BXP_FLOPPYA_PATH,
-      "floppya:path",
-      "Pathname of first floppy image file or device.  If you're booting from floppy, this should be a bootable floppy.",
-      "", BX_PATHNAME_LEN);
-  bx_options.floppya.Opath->set_ask_format ("Enter new filename, or 'none' for no disk: [%s] ");
-  bx_options.floppya.Opath->set_label ("First floppy image/device");
-  bx_options.floppya.Odevtype = new bx_param_enum_c (BXP_FLOPPYA_DEVTYPE,
-      "floppya:devtype",
-      "Type of floppy drive",
-      floppy_type_names,
-      BX_FLOPPY_NONE,
-      BX_FLOPPY_NONE);
-  bx_options.floppya.Otype = new bx_param_enum_c (BXP_FLOPPYA_TYPE,
-      "floppya:type",
-      "Type of floppy disk",
-      floppy_type_names,
-      BX_FLOPPY_NONE,
-      BX_FLOPPY_NONE);
-  bx_options.floppya.Otype->set_ask_format ("What type of floppy disk? [%s] ");
-  bx_options.floppya.Ostatus = new bx_param_enum_c (BXP_FLOPPYA_STATUS,
-      "Is floppya inserted",
-      "Inserted or ejected",
-      floppy_status_names,
-      BX_INSERTED,
-      BX_EJECTED);
-  bx_options.floppya.Ostatus->set_ask_format ("Is the floppy inserted or ejected? [%s] ");
-  bx_options.floppya.Opath->set_format ("%s");
-  bx_options.floppya.Otype->set_format ("size=%s");
-  bx_options.floppya.Ostatus->set_format ("%s");
-  bx_param_c *floppya_init_list[] = {
-    // if the order "path,type,status" changes, corresponding changes must
-    // be made in gui/wxmain.cc, MyFrame::editFloppyConfig.
-    bx_options.floppya.Opath,
-    bx_options.floppya.Otype,
-    bx_options.floppya.Ostatus,
-    NULL
-  };
-  menu = new bx_list_c (BXP_FLOPPYA, "Floppy Disk 0", "All options for first floppy disk", floppya_init_list);
-  menu->get_options ()->set (menu->SERIES_ASK);
-  bx_options.floppya.Opath->set_handler (bx_param_string_handler);
-  bx_options.floppya.Opath->set ("none");
-  bx_options.floppya.Otype->set_handler (bx_param_handler);
-  bx_options.floppya.Ostatus->set_handler (bx_param_handler);
-
-  bx_options.floppyb.Opath = new bx_param_filename_c (BXP_FLOPPYB_PATH,
-      "floppyb:path",
-      "Pathname of second floppy image file or device.",
-      "", BX_PATHNAME_LEN);
-  bx_options.floppyb.Opath->set_ask_format ("Enter new filename, or 'none' for no disk: [%s] ");
-  bx_options.floppyb.Opath->set_label ("Second floppy image/device");
-  bx_options.floppyb.Odevtype = new bx_param_enum_c (BXP_FLOPPYB_DEVTYPE,
-      "floppyb:devtype",
-      "Type of floppy drive",
-      floppy_type_names,
-      BX_FLOPPY_NONE,
-      BX_FLOPPY_NONE);
-  bx_options.floppyb.Otype = new bx_param_enum_c (BXP_FLOPPYB_TYPE,
-      "floppyb:type",
-      "Type of floppy disk",
-      floppy_type_names,
-      BX_FLOPPY_NONE,
-      BX_FLOPPY_NONE);
-  bx_options.floppyb.Otype->set_ask_format ("What type of floppy disk? [%s] ");
-  bx_options.floppyb.Ostatus = new bx_param_enum_c (BXP_FLOPPYB_STATUS,
-      "Is floppyb inserted",
-      "Inserted or ejected",
-      floppy_status_names,
-      BX_INSERTED,
-      BX_EJECTED);
-  bx_options.floppyb.Ostatus->set_ask_format ("Is the floppy inserted or ejected? [%s] ");
-  bx_options.floppyb.Opath->set_format ("%s");
-  bx_options.floppyb.Otype->set_format ("size=%s");
-  bx_options.floppyb.Ostatus->set_format ("%s");
-  bx_param_c *floppyb_init_list[] = {
-    bx_options.floppyb.Opath,
-    bx_options.floppyb.Otype,
-    bx_options.floppyb.Ostatus,
-    NULL
-  };
-  menu = new bx_list_c (BXP_FLOPPYB, "Floppy Disk 1", "All options for second floppy disk", floppyb_init_list);
-  menu->get_options ()->set (menu->SERIES_ASK);
-  bx_options.floppyb.Opath->set_handler (bx_param_string_handler);
-  bx_options.floppyb.Opath->set ("none");
-  bx_options.floppyb.Otype->set_handler (bx_param_handler);
-  bx_options.floppyb.Ostatus->set_handler (bx_param_handler);
-
-  // disk options
-
-  // FIXME use descr and name
-  char *s_atachannel[] = {
-    "ATA channel 0",
-    "ATA channel 1",
-    "ATA channel 2",
-    "ATA channel 3",
-    };
-  char *s_atadevice[4][2] = {
-    { "First HD/CD on channel 0",
-      "Second HD/CD on channel 0" },
-    { "First HD/CD on channel 1",
-    "Second HD/CD on channel 1" },
-    { "First HD/CD on channel 2",
-    "Second HD/CD on channel 2" },
-    { "First HD/CD on channel 3",
-    "Second HD/CD on channel 3" }
-    };
-  Bit16u ata_default_ioaddr1[BX_MAX_ATA_CHANNEL] = {
-    0x1f0, 0x170, 0x1e8, 0x168 
-  };
-  Bit16u ata_default_ioaddr2[BX_MAX_ATA_CHANNEL] = {
-    0x3f0, 0x370, 0x3e0, 0x360 
-  };
-  Bit8u ata_default_irq[BX_MAX_ATA_CHANNEL] = { 
-    14, 15, 11, 9 
-  };
-
-  bx_list_c *ata[BX_MAX_ATA_CHANNEL];
-  bx_list_c *ata_menu[BX_MAX_ATA_CHANNEL];
-
-  Bit8u channel;
-  for (channel=0; channel<BX_MAX_ATA_CHANNEL; channel ++) {
-
-    ata[channel] = new bx_list_c ((bx_id)(BXP_ATAx(channel)), s_atachannel[channel], s_atachannel[channel], 8);
-    ata[channel]->get_options ()->set (bx_list_c::SERIES_ASK);
-
-    ata[channel]->add (bx_options.ata[channel].Opresent = new bx_param_bool_c ((bx_id)(BXP_ATAx_PRESENT(channel)),
-      "ata:present",                                
-      "Controls whether ata channel is installed or not",
-      0));
-
-    ata[channel]->add (bx_options.ata[channel].Oioaddr1 = new bx_param_num_c ((bx_id)(BXP_ATAx_IOADDR1(channel)),
-      "ata:ioaddr1",
-      "IO adress of ata command block",
-      0, 0xffff,
-      ata_default_ioaddr1[channel]));
-
-    ata[channel]->add (bx_options.ata[channel].Oioaddr2 = new bx_param_num_c ((bx_id)(BXP_ATAx_IOADDR2(channel)),
-      "ata:ioaddr2",
-      "IO adress of ata control block",
-      0, 0xffff,
-      ata_default_ioaddr2[channel]));
-
-    ata[channel]->add (bx_options.ata[channel].Oirq = new bx_param_num_c ((bx_id)(BXP_ATAx_IRQ(channel)),
-      "ata:irq",
-      "IRQ used by this ata channel",
-      0, 15,
-      ata_default_irq[channel]));
-
-    // all items in the ata[channel] menu depend on the present flag.
-    // The menu list is complete, but a few dependent_list items will
-    // be added later.  Use clone() to make a copy of the dependent_list
-    // so that it can be changed without affecting the menu.
-    bx_options.ata[channel].Opresent->set_dependent_list (
-        ata[channel]->clone());
-
-    for (Bit8u slave=0; slave<2; slave++) {
-
-      menu = bx_options.atadevice[channel][slave].Omenu = new bx_list_c ((bx_id)(BXP_ATAx_DEVICE(channel,slave)),
-          s_atadevice[channel][slave], 
-          s_atadevice[channel][slave],
-          BXP_PARAMS_PER_ATA_DEVICE + 1 );
-      menu->get_options ()->set (menu->SERIES_ASK);
-
-      menu->add (bx_options.atadevice[channel][slave].Opresent = new bx_param_bool_c ((bx_id)(BXP_ATAx_DEVICE_PRESENT(channel,slave)),
-        "ata-device:present",                                
-        "Controls whether ata device is installed or not",  
-        0));
-
-      menu->add (bx_options.atadevice[channel][slave].Otype = new bx_param_enum_c ((bx_id)(BXP_ATAx_DEVICE_TYPE(channel,slave)),
-          "ata-device:type",
-          "Type of ATA device (disk or cdrom)",
-          atadevice_type_names,
-          BX_ATA_DEVICE_DISK,
-          BX_ATA_DEVICE_DISK));
-
-      menu->add (bx_options.atadevice[channel][slave].Opath = new bx_param_filename_c ((bx_id)(BXP_ATAx_DEVICE_PATH(channel,slave)),
-          "ata-device:path",
-          "Pathname of the image or physical device (cdrom only)",
-          "", BX_PATHNAME_LEN));
-
-      menu->add (bx_options.atadevice[channel][slave].Omode = new bx_param_enum_c ((bx_id)(BXP_ATAx_DEVICE_MODE(channel,slave)),
-          "ata-device:mode",
-          "Mode of the ATA harddisk",
-          atadevice_mode_names,
-          BX_ATA_MODE_FLAT,
-          BX_ATA_MODE_FLAT));
-
-      menu->add (bx_options.atadevice[channel][slave].Ostatus = new bx_param_enum_c ((bx_id)(BXP_ATAx_DEVICE_STATUS(channel,slave)),
-       "ata-device:status",
-       "CD-ROM media status (inserted / ejected)",
-       atadevice_status_names,
-       BX_INSERTED,
-       BX_EJECTED));
-
-      menu->add (bx_options.atadevice[channel][slave].Ojournal = new bx_param_filename_c ((bx_id)(BXP_ATAx_DEVICE_JOURNAL(channel,slave)),
-          "ata-device:journal",
-          "Pathname of the journal file",
-          "", BX_PATHNAME_LEN));
-
-      menu->add (bx_options.atadevice[channel][slave].Ocylinders = new bx_param_num_c ((bx_id)(BXP_ATAx_DEVICE_CYLINDERS(channel,slave)),
-          "ata-device:cylinders",
-          "Number of cylinders",
-          0, 65535,
-          0));
-      menu->add (bx_options.atadevice[channel][slave].Oheads = new bx_param_num_c ((bx_id)(BXP_ATAx_DEVICE_HEADS(channel,slave)),
-          "ata-device:heads",
-          "Number of heads",
-          0, 65535,
-          0));
-      menu->add (bx_options.atadevice[channel][slave].Ospt = new bx_param_num_c ((bx_id)(BXP_ATAx_DEVICE_SPT(channel,slave)),
-          "ata-device:spt",
-          "Number of sectors per track",
-          0, 65535,
-          0));
-      
-      menu->add (bx_options.atadevice[channel][slave].Omodel = new bx_param_string_c ((bx_id)(BXP_ATAx_DEVICE_MODEL(channel,slave)),
-       "ata-device:model",
-       "String returned by the 'identify device' command",
-       "Generic 1234", 40));
-
-      menu->add (bx_options.atadevice[channel][slave].Obiosdetect = new bx_param_enum_c ((bx_id)(BXP_ATAx_DEVICE_BIOSDETECT(channel,slave)),
-       "ata-device:biosdetect",
-       "Type of bios detection",
-       atadevice_biosdetect_names,
-       BX_ATA_BIOSDETECT_AUTO,
-       BX_ATA_BIOSDETECT_NONE));
-
-      menu->add (bx_options.atadevice[channel][slave].Otranslation = new bx_param_enum_c ((bx_id)(BXP_ATAx_DEVICE_TRANSLATION(channel,slave)),
-       "How the ata-disk translation is done by the bios",
-       "Type of translation",
-       atadevice_translation_names,
-       BX_ATA_TRANSLATION_AUTO,
-       BX_ATA_TRANSLATION_NONE));
-
-      bx_options.atadevice[channel][slave].Opresent->set_dependent_list (
-          menu->clone ());
-      // the menu and all items on it depend on the Opresent flag
-      bx_options.atadevice[channel][slave].Opresent->get_dependent_list()->add(menu);
-      // the present flag depends on the ATA channel's present flag
-      bx_options.ata[channel].Opresent->get_dependent_list()->add (
-          bx_options.atadevice[channel][slave].Opresent);
-      }
-
-      // set up top level menu for ATA[i] controller configuration.  This list
-      // controls what will appear on the ATA configure dialog.  It now
-      // requests the USE_TAB_WINDOW display, which is implemented in wx.
-      char buffer[32];
-      sprintf (buffer, "Configure ATA%d", channel);
-      ata_menu[channel] = new bx_list_c ((bx_id)(BXP_ATAx_MENU(channel)), strdup(buffer), "", 4);
-      ata_menu[channel]->add (ata[channel]);
-      ata_menu[channel]->add (bx_options.atadevice[channel][0].Omenu);
-      ata_menu[channel]->add (bx_options.atadevice[channel][1].Omenu);
-      ata_menu[channel]->get_options()->set (bx_list_c::USE_TAB_WINDOW);
-    }
-
-  // Enable first ata interface by default, disable the others.
-  bx_options.ata[0].Opresent->set_initial_val(1);
-
-  // now that the dependence relationships are established, call set() on
-  // the ata device present params to set all enables correctly.
-  for (i=0; i<BX_MAX_ATA_CHANNEL; i++)
-    bx_options.ata[i].Opresent->set (i==0);
-
-  for (channel=0; channel<BX_MAX_ATA_CHANNEL; channel ++) {
-
-    bx_options.ata[channel].Opresent->set_ask_format ("Channel is enabled: [%s] ");
-    bx_options.ata[channel].Oioaddr1->set_ask_format ("Enter new ioaddr1: [0x%x] ");
-    bx_options.ata[channel].Oioaddr2->set_ask_format ("Enter new ioaddr2: [0x%x] ");
-    bx_options.ata[channel].Oirq->set_ask_format ("Enter new IRQ: [%d] ");
-#if BX_WITH_WX
-    bx_options.ata[channel].Opresent->set_label ("Enable this channel?");
-    bx_options.ata[channel].Oioaddr1->set_label ("I/O Address 1:");
-    bx_options.ata[channel].Oioaddr2->set_label ("I/O Address 2:");
-    bx_options.ata[channel].Oirq->set_label ("IRQ:");
-    bx_options.ata[channel].Oirq->set_options (bx_param_num_c::USE_SPIN_CONTROL);
-#else
-    bx_options.ata[channel].Opresent->set_format ("enabled: %s");
-    bx_options.ata[channel].Oioaddr1->set_format ("ioaddr1: 0x%x");
-    bx_options.ata[channel].Oioaddr2->set_format ("ioaddr2: 0x%x");
-    bx_options.ata[channel].Oirq->set_format ("irq: %d");
-#endif
-    bx_options.ata[channel].Oioaddr1->set_base (16);
-    bx_options.ata[channel].Oioaddr2->set_base (16);
-
-    for (Bit8u slave=0; slave<2; slave++) {
-
-      bx_options.atadevice[channel][slave].Opresent->set_ask_format (
-          "Device is enabled: [%s] ");
-      bx_options.atadevice[channel][slave].Otype->set_ask_format (
-          "Enter type of ATA device, disk or cdrom: [%s] ");
-      bx_options.atadevice[channel][slave].Omode->set_ask_format (
-          "Enter mode of ATA device, (flat, concat, etc.): [%s] ");
-      bx_options.atadevice[channel][slave].Opath->set_ask_format (
-          "Enter new filename: [%s] ");
-      bx_options.atadevice[channel][slave].Ocylinders->set_ask_format (
-          "Enter number of cylinders: [%d] ");
-      bx_options.atadevice[channel][slave].Oheads->set_ask_format (
-          "Enter number of heads: [%d] ");
-      bx_options.atadevice[channel][slave].Ospt->set_ask_format (
-          "Enter number of sectors per track: [%d] ");
-      bx_options.atadevice[channel][slave].Ostatus->set_ask_format (
-          "Is the device inserted or ejected? [%s] ");
-      bx_options.atadevice[channel][slave].Omodel->set_ask_format (
-          "Enter new model name: [%s]");
-      bx_options.atadevice[channel][slave].Otranslation->set_ask_format (
-          "Enter translation type: [%s]");
-      bx_options.atadevice[channel][slave].Obiosdetect->set_ask_format (
-          "Enter bios detection type: [%s]");
-      bx_options.atadevice[channel][slave].Ojournal->set_ask_format (
-          "Enter path of journal file: [%s]");
-
-#if BX_WITH_WX
-      bx_options.atadevice[channel][slave].Opresent->set_label (
-          "Enable this device?");
-      bx_options.atadevice[channel][slave].Otype->set_label (
-          "Type of ATA device:");
-      bx_options.atadevice[channel][slave].Omode->set_label (
-          "Type of disk image:");
-      bx_options.atadevice[channel][slave].Opath->set_label (
-          "Path or physical device name:");
-      bx_options.atadevice[channel][slave].Ocylinders->set_label (
-          "Cylinders:");
-      bx_options.atadevice[channel][slave].Oheads->set_label (
-          "Heads:");
-      bx_options.atadevice[channel][slave].Ospt->set_label (
-          "Sectors per track:");
-      bx_options.atadevice[channel][slave].Ostatus->set_label (
-          "Inserted?");
-      bx_options.atadevice[channel][slave].Omodel->set_label (
-          "Model name:");
-      bx_options.atadevice[channel][slave].Otranslation->set_label (
-          "Translation type:");
-      bx_options.atadevice[channel][slave].Obiosdetect->set_label (
-          "BIOS Detection:");
-      bx_options.atadevice[channel][slave].Ojournal->set_label (
-          "Path of journal file:");
-#else
-      bx_options.atadevice[channel][slave].Opresent->set_format ("enabled: %s");
-      bx_options.atadevice[channel][slave].Otype->set_format ("type %s");
-      bx_options.atadevice[channel][slave].Omode->set_format ("mode %s");
-      bx_options.atadevice[channel][slave].Opath->set_format ("path '%s'");
-      bx_options.atadevice[channel][slave].Ocylinders->set_format ("%d cylinders");
-      bx_options.atadevice[channel][slave].Oheads->set_format ("%d heads");
-      bx_options.atadevice[channel][slave].Ospt->set_format ("%d sectors/track");
-      bx_options.atadevice[channel][slave].Ostatus->set_format ("%s");
-      bx_options.atadevice[channel][slave].Omodel->set_format ("model '%s'");
-      bx_options.atadevice[channel][slave].Otranslation->set_format ("translation '%s'");
-      bx_options.atadevice[channel][slave].Obiosdetect->set_format ("biosdetect '%s'");
-      bx_options.atadevice[channel][slave].Ojournal->set_format ("journal is '%s'");
-#endif
-
-      bx_options.atadevice[channel][slave].Otype->set_handler (bx_param_handler);
-      bx_options.atadevice[channel][slave].Omode->set_handler (bx_param_handler);
-      bx_options.atadevice[channel][slave].Ostatus->set_handler (bx_param_handler);
-      bx_options.atadevice[channel][slave].Opath->set_handler (bx_param_string_handler);
-
-      // Set the enable_hanlders
-      bx_options.atadevice[channel][slave].Ojournal->set_enable_handler (bx_param_enable_handler);
-      bx_options.atadevice[channel][slave].Ostatus->set_enable_handler (bx_param_enable_handler);
-
-      }
-    }
-
-  bx_options.OnewHardDriveSupport = new bx_param_bool_c (BXP_NEWHARDDRIVESUPPORT,
-      "New hard drive support",
-      "Enables new features found on newer hard drives.",
-      1);
-
-  bx_options.Obootdrive = new bx_param_enum_c (BXP_BOOTDRIVE,
-      "bootdrive",
-      "Boot A, C or CD",
-      floppy_bootdisk_names,
-      BX_BOOT_FLOPPYA,
-      BX_BOOT_FLOPPYA);
-  bx_options.Obootdrive->set_format ("Boot from: %s drive");
-  bx_options.Obootdrive->set_ask_format ("Boot from floppy drive, hard drive or cdrom ? [%s] ");
-
-  bx_options.OfloppySigCheck = new bx_param_bool_c (BXP_FLOPPYSIGCHECK,
-      "Skip Floppy Boot Signature Check",
-      "Skips check for the 0xaa55 signature on floppy boot device.",
-      0);
-
-  // disk menu
-  bx_param_c *disk_menu_init_list[] = {
-    SIM->get_param (BXP_FLOPPYA),
-    SIM->get_param (BXP_FLOPPYB),
-    SIM->get_param (BXP_ATA0),
-    SIM->get_param (BXP_ATA0_MASTER),
-    SIM->get_param (BXP_ATA0_SLAVE),
-#if BX_MAX_ATA_CHANNEL>1
-    SIM->get_param (BXP_ATA1),
-    SIM->get_param (BXP_ATA1_MASTER),
-    SIM->get_param (BXP_ATA1_SLAVE),
-#endif
-#if BX_MAX_ATA_CHANNEL>2
-    SIM->get_param (BXP_ATA2),
-    SIM->get_param (BXP_ATA2_MASTER),
-    SIM->get_param (BXP_ATA2_SLAVE),
-#endif
-#if BX_MAX_ATA_CHANNEL>3
-    SIM->get_param (BXP_ATA3),
-    SIM->get_param (BXP_ATA3_MASTER),
-    SIM->get_param (BXP_ATA3_SLAVE),
-#endif
-    SIM->get_param (BXP_NEWHARDDRIVESUPPORT),
-    SIM->get_param (BXP_BOOTDRIVE),
-    SIM->get_param (BXP_FLOPPYSIGCHECK),
-    NULL
-  };
-  menu = new bx_list_c (BXP_MENU_DISK, "Bochs Disk Options", "diskmenu", disk_menu_init_list);
-  menu->get_options ()->set (menu->SHOW_PARENT);
-
-  // memory options menu
-  bx_options.memory.Osize = new bx_param_num_c (BXP_MEM_SIZE,
-      "megs",
-      "Amount of RAM in megabytes",
-      1, BX_MAX_BIT32U,
-      BX_DEFAULT_MEM_MEGS);
-  bx_options.memory.Osize->set_ask_format ("Enter memory size (MB): [%d] ");
-#if BX_WITH_WX
-  bx_options.memory.Osize->set_label ("Memory size (megabytes)");
-  bx_options.memory.Osize->set_options (bx_param_num_c::USE_SPIN_CONTROL);
-#else
-  bx_options.memory.Osize->set_format ("Memory size in megabytes: %d");
-#endif
-
-  // initialize serial and parallel port options
-#define PAR_SER_INIT_LIST_MAX \
-  ((BXP_PARAMS_PER_PARALLEL_PORT * BX_N_PARALLEL_PORTS) \
-  + (BXP_PARAMS_PER_SERIAL_PORT * BX_N_SERIAL_PORTS) \
-  + (BXP_PARAMS_PER_USB_HUB * BX_N_USB_HUBS))
-  bx_param_c *par_ser_init_list[1+PAR_SER_INIT_LIST_MAX];
-  bx_param_c **par_ser_ptr = &par_ser_init_list[0];
-
-  // parallel ports
-  for (i=0; i<BX_N_PARALLEL_PORTS; i++) {
-        sprintf (name, "Enable parallel port #%d", i+1);
-        sprintf (descr, "Controls whether parallel port #%d is installed or not", i+1);
-        bx_options.par[i].Oenabled = new bx_param_bool_c (
-                BXP_PARPORTx_ENABLED(i+1), 
-                strdup(name), 
-                strdup(descr), 
-                (i==0)? 1 : 0);  // only enable #1 by default
-        sprintf (name, "Parallel port #%d output file", i+1);
-        sprintf (descr, "Data written to parport#%d by the guest OS is written to this file", i+1);
-        bx_options.par[i].Ooutfile = new bx_param_filename_c (
-                BXP_PARPORTx_OUTFILE(i+1), 
-                strdup(name), 
-                strdup(descr),
-                "", BX_PATHNAME_LEN);
-        deplist = new bx_list_c (BXP_NULL, 1);
-        deplist->add (bx_options.par[i].Ooutfile);
-        bx_options.par[i].Oenabled->set_dependent_list (deplist);
-        // add to menu
-        *par_ser_ptr++ = bx_options.par[i].Oenabled;
-        *par_ser_ptr++ = bx_options.par[i].Ooutfile;
-  }
-
-  // serial ports
-  for (i=0; i<BX_N_SERIAL_PORTS; i++) {
-        // options for COM port
-        sprintf (name, "Enable serial port #%d (COM%d)", i+1, i+1);
-        sprintf (descr, "Controls whether COM%d is installed or not", i+1);
-        bx_options.com[i].Oenabled = new bx_param_bool_c (
-                BXP_COMx_ENABLED(i+1),
-                strdup(name), 
-                strdup(descr), 
-                (i==0)?1 : 0);  // only enable the first by default
-        sprintf (name, "Pathname of the serial device for COM%d", i+1);
-        sprintf (descr, "The path can be a real serial device or a pty (X/Unix only)");
-        bx_options.com[i].Odev = new bx_param_filename_c (
-                BXP_COMx_PATH(i+1),
-                strdup(name), 
-                strdup(descr), 
-                "", BX_PATHNAME_LEN);
-        deplist = new bx_list_c (BXP_NULL, 1);
-        deplist->add (bx_options.com[i].Odev);
-        bx_options.com[i].Oenabled->set_dependent_list (deplist);
-        // add to menu
-        *par_ser_ptr++ = bx_options.com[i].Oenabled;
-        *par_ser_ptr++ = bx_options.com[i].Odev;
-  }
-
-  // usb hubs
-  for (i=0; i<BX_N_USB_HUBS; i++) {
-        // options for USB hub
-        sprintf (name, "usb%d:enabled", i+1);
-        sprintf (descr, "Controls whether USB%d is installed or not", i+1);
-        sprintf (label, "Enable usb hub #%d (USB%d)", i+1, i+1);
-        bx_options.usb[i].Oenabled = new bx_param_bool_c (
-                BXP_USBx_ENABLED(i+1),
-                strdup(name), 
-                strdup(descr), 
-                (i==0)?1 : 0);  // only enable the first by default
-        bx_options.usb[i].Oioaddr = new bx_param_num_c (
-                BXP_USBx_IOADDR(i+1),
-                "usb:ioaddr",
-                "I/O base adress of USB hub",
-                0, 0xffe0,
-                (i==0)?0xff80 : 0);
-        bx_options.usb[i].Oirq = new bx_param_num_c (
-                BXP_USBx_IRQ(i+1),
-                "usb:irq",
-                "IRQ used by USB hub",
-                0, 15,
-                (i==0)?10 : 0);
-        deplist = new bx_list_c (BXP_NULL, 2);
-        deplist->add (bx_options.usb[i].Oioaddr);
-        deplist->add (bx_options.usb[i].Oirq);
-        bx_options.usb[i].Oenabled->set_dependent_list (deplist);
-        // add to menu
-        *par_ser_ptr++ = bx_options.usb[i].Oenabled;
-        *par_ser_ptr++ = bx_options.usb[i].Oioaddr;
-        *par_ser_ptr++ = bx_options.usb[i].Oirq;
-
-        bx_options.usb[i].Oioaddr->set_ask_format ("Enter new ioaddr: [0x%x] ");
-        bx_options.usb[i].Oioaddr->set_label ("I/O Address");
-        bx_options.usb[i].Oioaddr->set_base (16);
-        bx_options.usb[i].Oenabled->set_label (strdup(label));
-        bx_options.usb[i].Oirq->set_label ("USB IRQ");
-        bx_options.usb[i].Oirq->set_options (bx_param_num_c::USE_SPIN_CONTROL);
-  }
-  // add final NULL at the end, and build the menu
-  *par_ser_ptr = NULL;
-  menu = new bx_list_c (BXP_MENU_SERIAL_PARALLEL,
-          "Serial and Parallel Port Options",
-          "serial_parallel_menu",
-          par_ser_init_list);
-  menu->get_options ()->set (menu->SHOW_PARENT);
-
-  bx_options.rom.Opath = new bx_param_filename_c (BXP_ROM_PATH,
-      "romimage",
-      "Pathname of ROM image to load",
-      "", BX_PATHNAME_LEN);
-  bx_options.rom.Opath->set_format ("Name of ROM BIOS image: %s");
-  bx_options.rom.Oaddress = new bx_param_num_c (BXP_ROM_ADDRESS,
-      "romaddr",
-      "The address at which the ROM image should be loaded",
-      0, BX_MAX_BIT32U, 
-      0xf0000);
-  bx_options.rom.Oaddress->set_base (16);
-#if BX_WITH_WX
-  bx_options.rom.Opath->set_label ("ROM BIOS image");
-  bx_options.rom.Oaddress->set_label ("ROM BIOS address");
-#else
-  bx_options.rom.Oaddress->set_format ("ROM BIOS address: 0x%05x");
-#endif
-
-  bx_options.optrom[0].Opath = new bx_param_filename_c (BXP_OPTROM1_PATH,
-      "optional romimage #1",
-      "Pathname of optional ROM image #1 to load",
-      "", BX_PATHNAME_LEN);
-  bx_options.optrom[0].Opath->set_format ("Name of optional ROM image #1 : %s");
-  bx_options.optrom[0].Oaddress = new bx_param_num_c (BXP_OPTROM1_ADDRESS,
-      "optional romaddr #1",
-      "The address at which the optional ROM image #1 should be loaded",
-      0, BX_MAX_BIT32U, 
-      0);
-  bx_options.optrom[0].Oaddress->set_base (16);
-#if BX_WITH_WX
-  bx_options.optrom[0].Opath->set_label ("Optional ROM image #1");
-  bx_options.optrom[0].Oaddress->set_label ("Address");
-#else
-  bx_options.optrom[0].Oaddress->set_format ("optional ROM #1 address: 0x%05x");
-#endif
-
-  bx_options.optrom[1].Opath = new bx_param_filename_c (BXP_OPTROM2_PATH,
-      "optional romimage #2",
-      "Pathname of optional ROM image #2 to load",
-      "", BX_PATHNAME_LEN);
-  bx_options.optrom[1].Opath->set_format ("Name of optional ROM image #2 : %s");
-  bx_options.optrom[1].Oaddress = new bx_param_num_c (BXP_OPTROM2_ADDRESS,
-      "optional romaddr #2",
-      "The address at which the optional ROM image #2 should be loaded",
-      0, BX_MAX_BIT32U, 
-      0);
-  bx_options.optrom[1].Oaddress->set_base (16);
-#if BX_WITH_WX
-  bx_options.optrom[1].Opath->set_label ("Optional ROM image #2");
-  bx_options.optrom[1].Oaddress->set_label ("Address");
-#else
-  bx_options.optrom[1].Oaddress->set_format ("optional ROM #2 address: 0x%05x");
-#endif
-
-  bx_options.optrom[2].Opath = new bx_param_filename_c (BXP_OPTROM3_PATH,
-      "optional romimage #3",
-      "Pathname of optional ROM image #3 to load",
-      "", BX_PATHNAME_LEN);
-  bx_options.optrom[2].Opath->set_format ("Name of optional ROM image #3 : %s");
-  bx_options.optrom[2].Oaddress = new bx_param_num_c (BXP_OPTROM3_ADDRESS,
-      "optional romaddr #3",
-      "The address at which the optional ROM image #3 should be loaded",
-      0, BX_MAX_BIT32U, 
-      0);
-  bx_options.optrom[2].Oaddress->set_base (16);
-#if BX_WITH_WX
-  bx_options.optrom[2].Opath->set_label ("Optional ROM image #3");
-  bx_options.optrom[2].Oaddress->set_label ("Address");
-#else
-  bx_options.optrom[2].Oaddress->set_format ("optional ROM #3 address: 0x%05x");
-#endif
-
-  bx_options.optrom[3].Opath = new bx_param_filename_c (BXP_OPTROM4_PATH,
-      "optional romimage #4",
-      "Pathname of optional ROM image #4 to load",
-      "", BX_PATHNAME_LEN);
-  bx_options.optrom[3].Opath->set_format ("Name of optional ROM image #4 : %s");
-  bx_options.optrom[3].Oaddress = new bx_param_num_c (BXP_OPTROM4_ADDRESS,
-      "optional romaddr #4",
-      "The address at which the optional ROM image #4 should be loaded",
-      0, BX_MAX_BIT32U, 
-      0);
-  bx_options.optrom[3].Oaddress->set_base (16);
-#if BX_WITH_WX
-  bx_options.optrom[3].Opath->set_label ("Optional ROM image #4");
-  bx_options.optrom[3].Oaddress->set_label ("Address");
-#else
-  bx_options.optrom[3].Oaddress->set_format ("optional ROM #4 address: 0x%05x");
-#endif
-
-  bx_options.vgarom.Opath = new bx_param_filename_c (BXP_VGA_ROM_PATH,
-      "vgaromimage",
-      "Pathname of VGA ROM image to load",
-      "", BX_PATHNAME_LEN);
-  bx_options.vgarom.Opath->set_format ("Name of VGA BIOS image: %s");
-#if BX_WITH_WX
-  bx_options.vgarom.Opath->set_label ("VGA BIOS image");
-#endif
-  bx_param_c *memory_init_list[] = {
-    bx_options.memory.Osize,
-    bx_options.vgarom.Opath,
-    bx_options.rom.Opath,
-    bx_options.rom.Oaddress,
-    bx_options.optrom[0].Opath,
-    bx_options.optrom[0].Oaddress,
-    bx_options.optrom[1].Opath,
-    bx_options.optrom[1].Oaddress,
-    bx_options.optrom[2].Opath,
-    bx_options.optrom[2].Oaddress,
-    bx_options.optrom[3].Opath,
-    bx_options.optrom[3].Oaddress,
-    NULL
-  };
-  menu = new bx_list_c (BXP_MENU_MEMORY, "Bochs Memory Options", "memmenu", memory_init_list);
-  menu->get_options ()->set (menu->SHOW_PARENT);
-
-  // interface
-  bx_options.Ovga_update_interval = new bx_param_num_c (BXP_VGA_UPDATE_INTERVAL,
-      "VGA Update Interval",
-      "Number of microseconds between VGA updates",
-      1, BX_MAX_BIT32U,
-      30000);
-  bx_options.Ovga_update_interval->set_handler (bx_param_handler);
-  bx_options.Ovga_update_interval->set_runtime_param (1);
-  bx_options.Ovga_update_interval->set_ask_format ("Type a new value for VGA update interval: [%d] ");
-  bx_options.Omouse_enabled = new bx_param_bool_c (BXP_MOUSE_ENABLED,
-      "Enable the mouse",
-      "Controls whether the mouse sends events to the guest. The hardware emulation is always enabled.",
-      0);
-  bx_options.Omouse_enabled->set_handler (bx_param_handler);
-  bx_options.Omouse_enabled->set_runtime_param (1);
-  bx_options.Oips = new bx_param_num_c (BXP_IPS, 
-      "Emulated instructions per second (IPS)",
-      "Emulated instructions per second, used to calibrate bochs emulated time with wall clock time.",
-      1, BX_MAX_BIT32U,
-      500000);
-  bx_options.Otext_snapshot_check = new bx_param_bool_c (BXP_TEXT_SNAPSHOT_CHECK,
-      "Enable panic for use in bochs testing",
-      "Enable panic when text on screen matches snapchk.txt.\nUseful for regression testing.\nIn win32, turns off CR/LF in snapshots and cuts.",
-      0);
-  bx_options.Oprivate_colormap = new bx_param_bool_c (BXP_PRIVATE_COLORMAP,
-      "Use a private colormap",
-      "Request that the GUI create and use it's own non-shared colormap. This colormap will be used when in the bochs window. If not enabled, a shared colormap scheme may be used. Not implemented on all GUI's.",
-      0);
-#if BX_WITH_AMIGAOS
-  bx_options.Ofullscreen = new bx_param_bool_c (BXP_FULLSCREEN,
-      "Use full screen mode",
-      "When enabled, bochs occupies the whole screen instead of just a window.",
-      0);
-  bx_options.Oscreenmode = new bx_param_string_c (BXP_SCREENMODE,
-      "Screen mode name",
-      "Screen mode name",
-      "", BX_PATHNAME_LEN);
-  bx_options.Oscreenmode->set_handler (bx_param_string_handler);
-#endif
-  static char *config_interface_list[] = {
-    "textconfig",
-#if BX_WITH_WX
-    "wx",
-#endif
-    NULL
-  };
-  bx_options.Osel_config = new bx_param_enum_c (
-    BXP_SEL_CONFIG_INTERFACE,
-    "Configuration interface",
-    "Select configuration interface",
-    config_interface_list,
-    0,
-    0);
-  bx_options.Osel_config->set_by_name (BX_DEFAULT_CONFIG_INTERFACE);
-  bx_options.Osel_config->set_ask_format ("Choose which configuration interface to use: [%s] ");
-  // this is a list of gui libraries that are known to be available at
-  // compile time.  The one that is listed first will be the default,
-  // which is used unless the user overrides it on the command line or
-  // in a configuration file.
-  static char *display_library_list[] = {
-#if BX_WITH_X11
-    "x",
-#endif
-#if BX_WITH_WIN32
-    "win32",
-#endif
-#if BX_WITH_CARBON
-    "carbon",
-#endif
-#if BX_WITH_BEOS
-    "beos",
-#endif
-#if BX_WITH_MACOS
-    "macos",
-#endif
-#if BX_WITH_AMIGAOS
-    "amigaos",
-#endif
-#if BX_WITH_SDL
-    "sdl",
-#endif
-#if BX_WITH_SVGA
-    "svga",
-#endif
-#if BX_WITH_TERM
-    "term",
-#endif
-#if BX_WITH_RFB
-    "rfb",
-#endif
-#if BX_WITH_WX
-    "wx",
-#endif
-#if BX_WITH_NOGUI
-    "nogui",
-#endif
-    NULL
-  };
-  bx_options.Osel_displaylib = new bx_param_enum_c (BXP_SEL_DISPLAY_LIBRARY,
-    "VGA Display Library",
-    "Select VGA Display Library",
-    display_library_list,
-    0,
-    0);
-  bx_options.Osel_displaylib->set_by_name (BX_DEFAULT_DISPLAY_LIBRARY);
-  bx_options.Osel_displaylib->set_ask_format ("Choose which library to use for the Bochs display: [%s] ");
-  bx_param_c *interface_init_list[] = {
-    bx_options.Osel_config,
-    bx_options.Osel_displaylib,
-    bx_options.Ovga_update_interval,
-    bx_options.Omouse_enabled,
-    bx_options.Oips,
-    bx_options.Oprivate_colormap,
-#if BX_WITH_AMIGAOS
-    bx_options.Ofullscreen,
-    bx_options.Oscreenmode,
-#endif
-    NULL
-  };
-  menu = new bx_list_c (BXP_MENU_INTERFACE, "Bochs Interface Menu", "intfmenu", interface_init_list);
-  menu->get_options ()->set (menu->SHOW_PARENT);
-
-  // NE2K options
-  bx_options.ne2k.Opresent = new bx_param_bool_c (BXP_NE2K_PRESENT,
-      "Enable NE2K NIC emulation",
-      "Enables the NE2K NIC emulation",
-      0);
-  bx_options.ne2k.Oioaddr = new bx_param_num_c (BXP_NE2K_IOADDR,
-      "NE2K I/O Address",
-      "I/O base address of the emulated NE2K device",
-      0, 0xffff,
-      0x240);
-  bx_options.ne2k.Oioaddr->set_base (16);
-  bx_options.ne2k.Oirq = new bx_param_num_c (BXP_NE2K_IRQ,
-      "NE2K Interrupt",
-      "IRQ used by the NE2K device",
-      0, 15,
-      9);
-  bx_options.ne2k.Oirq->set_options (bx_param_num_c::USE_SPIN_CONTROL);
-  bx_options.ne2k.Omacaddr = new bx_param_string_c (BXP_NE2K_MACADDR,
-      "MAC Address",
-      "MAC address of the NE2K device. Don't use an address of a machine on your net.",
-      "\xfe\xfd\xde\xad\xbe\xef", 6);
-  bx_options.ne2k.Omacaddr->get_options ()->set (bx_options.ne2k.Omacaddr->RAW_BYTES);
-  bx_options.ne2k.Omacaddr->set_separator (':');
-  static char *eth_module_list[] = {
-    "null",
-#if defined(ETH_LINUX)
-    "linux",
-#endif
-#if HAVE_ETHERTAP
-    "tap",
-#endif
-#if HAVE_TUNTAP
-    "tuntap",
-#endif
-#if defined(ETH_WIN32)
-    "win32",
-#endif
-#if defined(ETH_FBSD)
-    "fbsd",
-#endif
-#ifdef ETH_ARPBACK
-    "arpback",
-#endif
-    NULL
-  };
-  bx_options.ne2k.Oethmod = new bx_param_enum_c (BXP_NE2K_ETHMOD,
-      "Ethernet module",
-      "Module used for the connection to the real net.",
-       eth_module_list,
-       0,
-       0);
-  bx_options.ne2k.Oethmod->set_by_name ("null");
-  bx_options.ne2k.Oethdev = new bx_param_string_c (BXP_NE2K_ETHDEV,
-      "Ethernet device",
-      "Device used for the connection to the real net. This is only valid if an ethernet module other than 'null' is used.",
-      "xl0", BX_PATHNAME_LEN);
-  bx_options.ne2k.Oscript = new bx_param_string_c (BXP_NE2K_SCRIPT,
-      "Device configuration script",
-      "Name of the script that is executed after Bochs initializes the network interface (optional).",
-      "none", BX_PATHNAME_LEN);
-#if !BX_WITH_WX
-  bx_options.ne2k.Oscript->set_ask_format ("Enter new script name, or 'none': [%s] ");
-#endif
-  bx_param_c *ne2k_init_list[] = {
-    bx_options.ne2k.Opresent,
-    bx_options.ne2k.Oioaddr,
-    bx_options.ne2k.Oirq,
-    bx_options.ne2k.Omacaddr,
-    bx_options.ne2k.Oethmod,
-    bx_options.ne2k.Oethdev,
-    bx_options.ne2k.Oscript,
-    NULL
-  };
-  menu = new bx_list_c (BXP_NE2K, "NE2K Configuration", "", ne2k_init_list);
-  menu->get_options ()->set (menu->SHOW_PARENT);
-  bx_param_c **ne2k_dependent_list = &ne2k_init_list[1];
-  bx_options.ne2k.Opresent->set_dependent_list (
-      new bx_list_c (BXP_NULL, "", "", ne2k_dependent_list));
-  bx_options.ne2k.Opresent->set_handler (bx_param_handler);
-  bx_options.ne2k.Opresent->set (0);
-
-  // SB16 options
-  bx_options.sb16.Opresent = new bx_param_bool_c (BXP_SB16_PRESENT,
-      "Enable SB16 emulation",
-      "Enables the SB16 emulation",
-      0);
-  bx_options.sb16.Omidifile = new bx_param_filename_c (BXP_SB16_MIDIFILE,
-      "MIDI file",
-      "The filename is where the MIDI data is sent. This can be device or just a file.",
-      "", BX_PATHNAME_LEN);
-  bx_options.sb16.Owavefile = new bx_param_filename_c (BXP_SB16_WAVEFILE,
-      "Wave file",
-      "This is the device/file where the wave output is stored",
-      "", BX_PATHNAME_LEN);
-  bx_options.sb16.Ologfile = new bx_param_filename_c (BXP_SB16_LOGFILE,
-      "Log file",
-      "The file to write the SB16 emulator messages to.",
-      "", BX_PATHNAME_LEN);
-  bx_options.sb16.Omidimode = new bx_param_num_c (BXP_SB16_MIDIMODE,
-      "Midi mode",
-      "Controls the MIDI output format.",
-      0, 3,
-      0);
-  bx_options.sb16.Owavemode = new bx_param_num_c (BXP_SB16_WAVEMODE,
-      "Wave mode",
-      "Controls the wave output format.",
-      0, 3,
-      0);
-  bx_options.sb16.Ologlevel = new bx_param_num_c (BXP_SB16_LOGLEVEL,
-      "Log mode",
-      "Controls how verbose the SB16 emulation is (0 = no log, 5 = all errors and infos).",
-      0, 5,
-      0);
-  bx_options.sb16.Odmatimer = new bx_param_num_c (BXP_SB16_DMATIMER,
-      "DMA timer",
-      "Microseconds per second for a DMA cycle.",
-      0, BX_MAX_BIT32U,
-      0);
-
-#if BX_WITH_WX
-  bx_options.sb16.Omidimode->set_options (bx_param_num_c::USE_SPIN_CONTROL);
-  bx_options.sb16.Owavemode->set_options (bx_param_num_c::USE_SPIN_CONTROL);
-  bx_options.sb16.Ologlevel->set_options (bx_param_num_c::USE_SPIN_CONTROL);
-#endif
-  bx_param_c *sb16_init_list[] = {
-    bx_options.sb16.Opresent,
-    bx_options.sb16.Omidimode,
-    bx_options.sb16.Omidifile,
-    bx_options.sb16.Owavemode,
-    bx_options.sb16.Owavefile,
-    bx_options.sb16.Ologlevel,
-    bx_options.sb16.Ologfile,
-    bx_options.sb16.Odmatimer,
-    NULL
-  };
-  menu = new bx_list_c (BXP_SB16, "SB16 Configuration", "", sb16_init_list);
-  menu->get_options ()->set (menu->SHOW_PARENT);
-  // sb16_dependent_list is a null-terminated list including all the
-  // sb16 fields except for the "present" field.  These will all be enabled/
-  // disabled according to the value of the present field.
-  bx_param_c **sb16_dependent_list = &sb16_init_list[1];
-  bx_options.sb16.Opresent->set_dependent_list (
-      new bx_list_c (BXP_NULL, "", "", sb16_dependent_list));
-
-  bx_options.log.Ofilename = new bx_param_filename_c (BXP_LOG_FILENAME,
-      "Log filename",
-      "Pathname of bochs log file",
-      "-", BX_PATHNAME_LEN);
-  bx_options.log.Ofilename->set_ask_format ("Enter log filename: [%s] ");
-
-  bx_options.log.Oprefix = new bx_param_string_c (BXP_LOG_PREFIX,
-      "Log output prefix",
-      "Prefix prepended to log output",
-      "%t%e%d", BX_PATHNAME_LEN);
-  bx_options.log.Oprefix->set_ask_format ("Enter log prefix: [%s] ");
-
-  bx_options.log.Odebugger_filename = new bx_param_filename_c (BXP_DEBUGGER_LOG_FILENAME,
-      "Debugger Log filename",
-      "Pathname of debugger log file",
-      "-", BX_PATHNAME_LEN);
-  bx_options.log.Odebugger_filename->set_ask_format ("Enter debugger log filename: [%s] ");
-
-  // loader
-  bx_options.load32bitOSImage.OwhichOS = new bx_param_enum_c (BXP_LOAD32BITOS_WHICH,
-      "Which operating system?",
-      "Which OS to boot",
-      loader_os_names,
-#ifdef BX_USE_VMX
-         Load32bitOSLinux,
-#else
-      Load32bitOSNone,
-#endif
-      Load32bitOSNone);
-  bx_options.load32bitOSImage.Opath = new bx_param_filename_c (BXP_LOAD32BITOS_PATH,
-      "Pathname of OS to load",
-      "Pathname of the 32-bit OS to load",
-      "", BX_PATHNAME_LEN);
-  bx_options.load32bitOSImage.Oiolog = new bx_param_filename_c (BXP_LOAD32BITOS_IOLOG,
-      "Pathname of I/O log file",
-      "I/O logfile used for initializing the hardware",
-      "", BX_PATHNAME_LEN);
-  bx_options.load32bitOSImage.Oinitrd = new bx_param_filename_c (BXP_LOAD32BITOS_INITRD,
-      "Pathname of initrd",
-      "Pathname of the initial ramdisk",
-      "", BX_PATHNAME_LEN);
-  bx_param_c *loader_init_list[] = {
-    bx_options.load32bitOSImage.OwhichOS,
-    bx_options.load32bitOSImage.Opath,
-    bx_options.load32bitOSImage.Oiolog,
-    bx_options.load32bitOSImage.Oinitrd,
-    NULL
-  };
-  bx_options.load32bitOSImage.OwhichOS->set_format ("os=%s");
-  bx_options.load32bitOSImage.Opath->set_format ("path=%s");
-  bx_options.load32bitOSImage.Oiolog->set_format ("iolog=%s");
-  bx_options.load32bitOSImage.Oinitrd->set_format ("initrd=%s");
-  bx_options.load32bitOSImage.OwhichOS->set_ask_format ("Enter OS to load: [%s] ");
-  bx_options.load32bitOSImage.Opath->set_ask_format ("Enter pathname of OS: [%s]");
-  bx_options.load32bitOSImage.Oiolog->set_ask_format ("Enter pathname of I/O log: [%s] ");
-  bx_options.load32bitOSImage.Oinitrd->set_ask_format ("Enter pathname of initrd: [%s] ");
-  menu = new bx_list_c (BXP_LOAD32BITOS, "32-bit OS Loader", "", loader_init_list);
-  menu->get_options ()->set (menu->SERIES_ASK);
-  bx_options.load32bitOSImage.OwhichOS->set_handler (bx_param_handler);
-#ifdef BX_USE_VMX
-  bx_options.load32bitOSImage.OwhichOS->set (Load32bitOSLinux);
-#else
-  bx_options.load32bitOSImage.OwhichOS->set (Load32bitOSNone);
-#endif
-
-  // clock
-  bx_options.clock.Otime0 = new bx_param_num_c (BXP_CLOCK_TIME0,
-      "clock:time0",
-      "Initial time for Bochs CMOS clock, used if you really want two runs to be identical",
-      0, BX_MAX_BIT32U,
-      BX_CLOCK_TIME0_LOCAL);
-  bx_options.clock.Osync = new bx_param_enum_c (BXP_CLOCK_SYNC,
-      "clock:sync",
-      "Host to guest time synchronization method",
-      clock_sync_names,
-      BX_CLOCK_SYNC_NONE,
-      BX_CLOCK_SYNC_NONE);
-  bx_param_c *clock_init_list[] = {
-    bx_options.clock.Osync,
-    bx_options.clock.Otime0,
-    NULL
-  };
-#if !BX_WITH_WX
-  bx_options.clock.Osync->set_format ("sync=%s");
-  bx_options.clock.Otime0->set_format ("initial time=%d");
-#endif
-  bx_options.clock.Otime0->set_ask_format ("Enter Initial CMOS time (1:localtime, 2:utc, other:time in seconds): [%d] ");
-  bx_options.clock.Osync->set_ask_format ("Enter Synchronisation method: [%s] ");
-  bx_options.clock.Otime0->set_label ("Initial CMOS time for Bochs\n(1:localtime, 2:utc, other:time in seconds)");
-  bx_options.clock.Osync->set_label ("Synchronisation method");
-  menu = new bx_list_c (BXP_CLOCK, "Clock parameters", "", clock_init_list);
-  menu->get_options ()->set (menu->SERIES_ASK);
-
-  // other
-  bx_options.Okeyboard_serial_delay = new bx_param_num_c (BXP_KBD_SERIAL_DELAY,
-      "Keyboard serial delay",
-      "Approximate time in microseconds that it takes one character to be transfered from the keyboard to controller over the serial path.",
-      1, BX_MAX_BIT32U,
-      20000);
-  bx_options.Okeyboard_paste_delay = new bx_param_num_c (BXP_KBD_PASTE_DELAY,
-      "Keyboard paste delay",
-      "Approximate time in microseconds between attemps to paste characters to the keyboard controller.",
-      1000, BX_MAX_BIT32U,
-      100000);
-  bx_options.Okeyboard_paste_delay->set_handler (bx_param_handler);
-  bx_options.Okeyboard_paste_delay->set_runtime_param (1);
-  bx_options.Ofloppy_command_delay = new bx_param_num_c (BXP_FLOPPY_CMD_DELAY,
-      "Floppy command delay",
-      "Time in microseconds to wait before completing some floppy commands such as read/write/seek/etc, which normally have a delay associated.  This used to be hardwired to 50,000 before.",
-      1, BX_MAX_BIT32U,
-      50000);
-  bx_options.Oi440FXSupport = new bx_param_bool_c (BXP_I440FX_SUPPORT,
-      "PCI i440FX Support",
-      "Controls whether to emulate the i440FX PCI chipset",
-      0);
-  bx_options.cmos.OcmosImage = new bx_param_bool_c (BXP_CMOS_IMAGE,
-      "Use a CMOS image",
-      "Controls the usage of a CMOS image",
-      0);
-  bx_options.cmos.Opath = new bx_param_filename_c (BXP_CMOS_PATH,
-      "Pathname of CMOS image",
-      "Pathname of CMOS image",
-      "", BX_PATHNAME_LEN);
-  deplist = new bx_list_c (BXP_NULL, 1);
-  deplist->add (bx_options.cmos.Opath);
-  bx_options.cmos.OcmosImage->set_dependent_list (deplist);
-
-  // Keyboard mapping
-  bx_options.keyboard.OuseMapping = new bx_param_bool_c(BXP_KEYBOARD_USEMAPPING,
-      "Use keyboard mapping",
-      "Controls whether to use the keyboard mapping feature",
-      0);
-  bx_options.keyboard.Okeymap = new bx_param_filename_c (BXP_KEYBOARD_MAP,
-      "Keymap filename",
-      "Pathname of the keymap file used",
-      "", BX_PATHNAME_LEN);
-  deplist = new bx_list_c (BXP_NULL, 1);
-  deplist->add (bx_options.keyboard.Okeymap);
-  bx_options.keyboard.OuseMapping->set_dependent_list (deplist);
-
- // Keyboard type
-  bx_options.Okeyboard_type = new bx_param_enum_c (BXP_KBD_TYPE,
-      "Keyboard type",
-      "Keyboard type reported by the 'identify keyboard' command",
-      keyboard_type_names,
-      BX_KBD_MF_TYPE,
-      BX_KBD_XT_TYPE);
-  bx_options.Okeyboard_type->set_ask_format ("Enter keyboard type: [%s] ");
-
-  // Userbutton shortcut
-  bx_options.Ouser_shortcut = new bx_param_string_c (BXP_USER_SHORTCUT,
-      "Userbutton shortcut",
-      "Defines the keyboard shortcut to be sent when you press the 'user' button in the headerbar.",
-      "none", 16);
-
-  // GDB stub
-  bx_options.gdbstub.port = 1234;
-  bx_options.gdbstub.text_base = 0;
-  bx_options.gdbstub.data_base = 0;
-  bx_options.gdbstub.bss_base = 0;
-
-  bx_param_c *keyboard_init_list[] = {
-      bx_options.Okeyboard_serial_delay,
-      bx_options.Okeyboard_paste_delay,
-      bx_options.keyboard.OuseMapping,
-      bx_options.keyboard.Okeymap,
-      bx_options.Okeyboard_type,
-      bx_options.Ouser_shortcut,
-      NULL
-  };
-  menu = new bx_list_c (BXP_MENU_KEYBOARD, "Configure Keyboard", "", keyboard_init_list);
-  menu->get_options ()->set (menu->SHOW_PARENT);
-
-  bx_param_c *other_init_list[] = {
-      bx_options.Ofloppy_command_delay,
-      bx_options.Oi440FXSupport,
-      bx_options.cmos.OcmosImage,
-      bx_options.cmos.Opath,
-      SIM->get_param (BXP_CLOCK),
-      SIM->get_param (BXP_LOAD32BITOS),
-      NULL
-  };
-  menu = new bx_list_c (BXP_MENU_MISC, "Configure Everything Else", "", other_init_list);
-  menu->get_options ()->set (menu->SHOW_PARENT);
-
-#if BX_WITH_WX
-  bx_param_c *other_init_list2[] = {
-//    bx_options.Osel_config,
-//    bx_options.Osel_displaylib,
-      bx_options.Ovga_update_interval,
-      bx_options.log.Oprefix,
-      bx_options.Omouse_enabled,
-      bx_options.OfloppySigCheck,
-      bx_options.Ofloppy_command_delay,
-      bx_options.OnewHardDriveSupport,
-      bx_options.Oprivate_colormap,
-#if BX_WITH_AMIGAOS
-      bx_options.Ofullscreen,
-      bx_options.Oscreenmode,
-#endif
-      bx_options.Oi440FXSupport,
-      bx_options.cmos.OcmosImage,
-      bx_options.cmos.Opath,
-      NULL
-  };
-  menu = new bx_list_c (BXP_MENU_MISC_2, "Other options", "", other_init_list2);
-#endif
-}
-
-void bx_reset_options ()
-{
-  // drives
-  bx_options.floppya.Opath->reset();
-  bx_options.floppya.Odevtype->reset();
-  bx_options.floppya.Otype->reset();
-  bx_options.floppya.Ostatus->reset();
-  bx_options.floppyb.Opath->reset();
-  bx_options.floppyb.Odevtype->reset();
-  bx_options.floppyb.Otype->reset();
-  bx_options.floppyb.Ostatus->reset();
-
-  for (Bit8u channel=0; channel<BX_MAX_ATA_CHANNEL; channel++) {
-    bx_options.ata[channel].Opresent->reset();
-    bx_options.ata[channel].Oioaddr1->reset();
-    bx_options.ata[channel].Oioaddr2->reset();
-    bx_options.ata[channel].Oirq->reset();
-
-    for (Bit8u slave=0; slave<2; slave++) {
-      bx_options.atadevice[channel][slave].Opresent->reset();
-      bx_options.atadevice[channel][slave].Otype->reset();
-      bx_options.atadevice[channel][slave].Omode->reset();
-      bx_options.atadevice[channel][slave].Opath->reset();
-      bx_options.atadevice[channel][slave].Ocylinders->reset();
-      bx_options.atadevice[channel][slave].Oheads->reset();
-      bx_options.atadevice[channel][slave].Ospt->reset();
-      bx_options.atadevice[channel][slave].Ostatus->reset();
-      bx_options.atadevice[channel][slave].Omodel->reset();
-      bx_options.atadevice[channel][slave].Obiosdetect->reset();
-      bx_options.atadevice[channel][slave].Otranslation->reset();
-      }
-    }
-  bx_options.OnewHardDriveSupport->reset();
-
-  // boot & memory
-  bx_options.Obootdrive->reset();
-  bx_options.OfloppySigCheck->reset();
-  bx_options.memory.Osize->reset();
-
-  // standard ports
-  bx_options.com[0].Oenabled->reset();
-  bx_options.com[0].Odev->reset();
-  bx_options.par[0].Oenabled->reset();
-  bx_options.par[0].Ooutfile->reset();
-
-  // rom images
-  bx_options.rom.Opath->reset();
-  bx_options.rom.Oaddress->reset();
-  bx_options.optrom[0].Opath->reset();
-  bx_options.optrom[0].Oaddress->reset();
-  bx_options.optrom[1].Opath->reset();
-  bx_options.optrom[1].Oaddress->reset();
-  bx_options.optrom[2].Opath->reset();
-  bx_options.optrom[2].Oaddress->reset();
-  bx_options.optrom[3].Opath->reset();
-  bx_options.optrom[3].Oaddress->reset();
-  bx_options.vgarom.Opath->reset();
-
-  // interface
-  bx_options.Ovga_update_interval->reset();
-  bx_options.Omouse_enabled->reset();
-  bx_options.Oips->reset();
-  bx_options.Oprivate_colormap->reset();
-#if BX_WITH_AMIGAOS
-  bx_options.Ofullscreen->reset();
-  bx_options.Oscreenmode->reset();
-#endif
-
-  // ne2k
-  bx_options.ne2k.Opresent->reset();
-  bx_options.ne2k.Oioaddr->reset();
-  bx_options.ne2k.Oirq->reset();
-  bx_options.ne2k.Omacaddr->reset();
-  bx_options.ne2k.Oethmod->reset();
-  bx_options.ne2k.Oethdev->reset();
-  bx_options.ne2k.Oscript->reset();
-
-  // SB16
-  bx_options.sb16.Opresent->reset();
-  bx_options.sb16.Omidifile->reset();
-  bx_options.sb16.Owavefile->reset();
-  bx_options.sb16.Ologfile->reset();
-  bx_options.sb16.Omidimode->reset();
-  bx_options.sb16.Owavemode->reset();
-  bx_options.sb16.Ologlevel->reset();
-  bx_options.sb16.Odmatimer->reset();
-
-  // logfile
-  bx_options.log.Ofilename->reset();
-  bx_options.log.Oprefix->reset();
-  bx_options.log.Odebugger_filename->reset();
-
-  // loader
-  bx_options.load32bitOSImage.OwhichOS->reset();
-  bx_options.load32bitOSImage.Opath->reset();
-  bx_options.load32bitOSImage.Oiolog->reset();
-  bx_options.load32bitOSImage.Oinitrd->reset();
-
-  // keyboard
-  bx_options.Okeyboard_serial_delay->reset();
-  bx_options.Okeyboard_paste_delay->reset();
-  bx_options.keyboard.OuseMapping->reset();
-  bx_options.keyboard.Okeymap->reset();
-  bx_options.Okeyboard_type->reset();
-  bx_options.Ouser_shortcut->reset();
-
-  // Clock
-  bx_options.clock.Otime0->reset();
-  bx_options.clock.Osync->reset();
-
-  // other
-  bx_options.Ofloppy_command_delay->reset();
-  bx_options.Oi440FXSupport->reset();
-  bx_options.cmos.OcmosImage->reset();
-  bx_options.cmos.Opath->reset();
-  bx_options.Otext_snapshot_check->reset();
-}
-
-void bx_print_header ()
-{
-  fprintf (stderr, "%s\n", divider);
-  char buffer[128];
-  sprintf (buffer, "Bochs x86 Emulator %s\n", VER_STRING);
-  bx_center_print (stderr, buffer, 72);
-  if (REL_STRING[0]) {
-    sprintf (buffer, "%s\n", REL_STRING);
-    bx_center_print (stderr, buffer, 72);
-  }
-  fprintf (stderr, "%s\n", divider);
-}
-
-#if BX_WITH_CARBON
-/* Original code by Darrell Walisser - dwaliss1@purdue.edu */
-
-static void setupWorkingDirectory (char *path)
-{
-    char parentdir[MAXPATHLEN];
-    char *c;
-    
-    strncpy ( parentdir, path, MAXPATHLEN );
-    c = (char*) parentdir;
-    
-    while (*c != '\0')     /* go to end */
-        c++;
-    
-    while (*c != '/')      /* back up to parent */
-        c--;
-    
-    *c = '\0';             /* cut off last part (binary name) */
-    
-        /* chdir to the binary app's parent */
-        int n;
-        n = chdir (parentdir);
-        if (n) BX_PANIC (("failed to change dir to parent"));
-        /* chdir to the .app's parent */
-        n = chdir ("../../../");
-    if (n) BX_PANIC (("failed to change to ../../.."));
-}
-
-/* Panic button to display fatal errors.
-  Completely self contained, can't rely on carbon.cc being available */
-static void carbonFatalDialog(const char *error, const char *exposition)
-{
-  DialogRef                     alertDialog;
-  CFStringRef                   cfError;
-  CFStringRef                   cfExposition;
-  DialogItemIndex               index;
-  AlertStdCFStringAlertParamRec alertParam = {0};
-  fprintf(stderr, "Entering carbonFatalDialog: %s\n", error);
-  
-  // Init libraries
-  InitCursor();
-  // Assemble dialog
-  cfError = CFStringCreateWithCString(NULL, error, kCFStringEncodingASCII);
-  if(exposition != NULL)
-  {
-    cfExposition = CFStringCreateWithCString(NULL, exposition, kCFStringEncodingASCII);
-  }
-  else { cfExposition = NULL; }
-  alertParam.version       = kStdCFStringAlertVersionOne;
-  alertParam.defaultText   = CFSTR("Quit");
-  alertParam.position      = kWindowDefaultPosition;
-  alertParam.defaultButton = kAlertStdAlertOKButton;
-  // Display Dialog
-  CreateStandardAlert(
-    kAlertStopAlert,
-    cfError,
-    cfExposition,       /* can be NULL */
-    &alertParam,             /* can be NULL */
-    &alertDialog);
-  RunStandardAlert( alertDialog, NULL, &index);
-  // Cleanup
-  CFRelease( cfError );
-  if( cfExposition != NULL ) { CFRelease( cfExposition ); }
-}
-#endif
-
-int bxmain () {
-#ifdef HAVE_LOCALE_H
-  // Initialize locale (for isprint() and other functions)
-  setlocale (LC_ALL, "");
-#endif
-  bx_user_quit = 0;
-  bx_init_siminterface ();   // create the SIM object
-
-  static jmp_buf context;
-  if (setjmp (context) == 0) {
-    SIM->set_quit_context (&context);
-    if (bx_init_main (bx_startup_flags.argc, bx_startup_flags.argv) < 0) 
-      return 0;
-    // read a param to decide which config interface to start.
-    // If one exists, start it.  If not, just begin.
-    bx_param_enum_c *ci_param = SIM->get_param_enum (BXP_SEL_CONFIG_INTERFACE);
-    char *ci_name = ci_param->get_choice (ci_param->get ());
-    if (!strcmp(ci_name, "textconfig")) {
-      init_text_config_interface ();   // in textconfig.h
-    }
-#if BX_WITH_WX
-    else if (!strcmp(ci_name, "wx")) {
-      PLUG_load_plugin(wx, PLUGTYPE_CORE);
-    }
-#endif
-    else {
-      BX_PANIC (("unsupported configuration interface '%s'", ci_name));
-    }
-    int status = SIM->configuration_interface (ci_name, CI_START);
-    if (status == CI_ERR_NO_TEXT_CONSOLE)
-      BX_PANIC (("Bochs needed the text console, but it was not usable"));
-    // user quit the config interface, so just quit
-  } else {
-    // quit via longjmp
-  }
-}
-
-// normal main function, presently in for all cases except for
-// wxWindows under win32.
-int main (int argc, char *argv[])
-{
-  daemon(0, 0);
-  bx_startup_flags.argc = argc;
-  bx_startup_flags.argv = argv;
-#if BX_WITH_SDL && defined(WIN32)
-  // if SDL/win32, try to create a console window.
-  RedirectIOToConsole ();
-#endif
-  return bxmain ();
-}
-
-void
-print_usage ()
-{
-  fprintf(stderr, 
-    "Usage: bochs [flags] [bochsrc options]\n\n"
-    "  -n               no configuration file\n"
-    "  -f configfile    specify configuration file\n"
-    "  -q               quick start (skip configuration interface)\n"
-    "  --help           display this help and exit\n\n"
-    "For information on Bochs configuration file arguments, see the\n"
-#if (!defined(WIN32)) && !BX_WITH_MACOS
-    "bochsrc section in the user documentation or the man page of bochsrc.\n");
-#else
-    "bochsrc section in the user documentation.\n");
-#endif
-}
-
-#ifdef BX_USE_VMX
-int domid = -1;
-unsigned long megabytes = 0;
-#endif
-int
-bx_init_main (int argc, char *argv[])
-{
-  // To deal with initialization order problems inherent in C++, use the macros
-  // SAFE_GET_IOFUNC and SAFE_GET_GENLOG to retrieve "io" and "genlog" in all
-  // constructors or functions called by constructors.  The macros test for
-  // NULL and create the object if necessary, then return it.  Ensure that io
-  // and genlog get created, by making one reference to each macro right here.
-  // All other code can reference io and genlog directly.  Because these
-  // objects are required for logging, and logging is so fundamental to
-  // knowing what the program is doing, they are never free()d.
-  SAFE_GET_IOFUNC();  // never freed
-  SAFE_GET_GENLOG();  // never freed
-
-  // initalization must be done early because some destructors expect
-  // the bx_options to exist by the time they are called.
-  bx_init_bx_dbg ();
-  bx_init_options ();
-
-  bx_print_header ();
-
-#ifdef BX_USE_VMX
-  xc_handle = xc_interface_open();
-  SIM->get_param_enum(BXP_BOCHS_START)->set (BX_QUICK_START);
-#else
-  SIM->get_param_enum(BXP_BOCHS_START)->set (BX_RUN_START);
-#endif
-
-  // interpret the args that start with -, like -q, -f, etc.
-  int arg = 1, load_rcfile=1;
-  while (arg < argc) {
-    // parse next arg
-    if (!strcmp ("--help", argv[arg]) || !strncmp ("-h", argv[arg], 2)) {
-      print_usage();
-      SIM->quit_sim (0);
-    }
-    else if (!strcmp ("-n", argv[arg])) {
-      load_rcfile = 0;
-    }
-    else if (!strcmp ("-q", argv[arg])) {
-      SIM->get_param_enum(BXP_BOCHS_START)->set (BX_QUICK_START);
-    }
-    else if (!strcmp ("-f", argv[arg])) {
-      if (++arg >= argc) BX_PANIC(("-f must be followed by a filename"));
-      else bochsrc_filename = argv[arg];
-    }
-    else if (!strcmp ("-qf", argv[arg])) {
-      SIM->get_param_enum(BXP_BOCHS_START)->set (BX_QUICK_START);
-      if (++arg >= argc) BX_PANIC(("-qf must be followed by a filename"));
-      else bochsrc_filename = argv[arg];
-    }
-#ifdef BX_USE_VMX
-    else if (!strcmp ("-p", argv[arg])) {
-    //get the polling port
-    extern int ioreq_port;
-      if (++arg >= argc) BX_PANIC(("-p must be followed by a polling port"));
-      else sscanf(argv[arg], "%d", &ioreq_port);
-    }
-    else if (!strcmp ("-d", argv[arg])) {
-    //get the domain id
-      if (++arg >= argc) BX_PANIC(("-d must be followed by domainid"));
-      else sscanf(argv[arg], "%d", &domid);
-    }
-    else if (!strcmp ("-m", argv[arg])) {
-    //get the maxmem
-      if (++arg >= argc) 
-                 BX_PANIC(("-m must be followed by maxmem in megabytes"));
-      else sscanf(argv[arg], "%d", &megabytes);
-    }
-
-#endif
-    else if (argv[arg][0] == '-') {
-      print_usage();
-      BX_PANIC (("command line arg '%s' was not understood", argv[arg]));
-    }
-    else {
-      // the arg did not start with -, so stop interpreting flags
-      break;
-    }
-    arg++;
-  }
-
-  int norcfile = 1;
-
-  if (load_rcfile) {
-    /* parse configuration file and command line arguments */
-#ifdef WIN32
-    if (bochsrc_filename != NULL) {
-      lstrcpy(bx_startup_flags.initial_dir, bochsrc_filename);
-    } else {
-      bx_startup_flags.initial_dir[0] = 0;
-    }
-#endif
-    if (bochsrc_filename == NULL) bochsrc_filename = bx_find_bochsrc ();
-    if (bochsrc_filename)
-      norcfile = bx_read_configuration (bochsrc_filename);
-  }
-
-  // parse the rest of the command line.  This is done after reading the
-  // configuration file so that the command line arguments can override
-  // the settings from the file.
-  if (bx_parse_cmdline (arg, argc, argv)) {
-    BX_PANIC(("There were errors while parsing the command line"));
-    return -1;
-  }
-  // initialize plugin system. This must happen before we attempt to
-  // load any modules.
-  plugin_startup();
-  return 0;
-}
-
-bx_bool load_and_init_display_lib () {
-  if (bx_gui != NULL) {
-    // bx_gui has already been filled in.  This happens when you start
-    // the simulation for the second time.
-    // Also, if you load wxWindows as the configuration interface.  Its
-    // plugin_init will install wxWindows as the bx_gui.
-    return true;
-  }
-  BX_ASSERT (bx_gui == NULL);
-  bx_param_enum_c *ci_param = SIM->get_param_enum (BXP_SEL_CONFIG_INTERFACE);
-  char *ci_name = ci_param->get_choice (ci_param->get ());
-  bx_param_enum_c *gui_param = SIM->get_param_enum(BXP_SEL_DISPLAY_LIBRARY);
-  char *gui_name = gui_param->get_choice (gui_param->get ());
-  if (!strcmp(ci_name, "wx")) {
-    BX_ERROR(("change of the config interface to wx not implemented yet"));
-  }
-  if (!strcmp (gui_name, "wx")) {
-    // they must not have used wx as the configuration interface, or bx_gui
-    // would already be initialized.  Sorry, it doesn't work that way.
-    BX_ERROR (("wxWindows was not used as the configuration interface, so it cannot be used as the display library"));
-    // choose another, hopefully different!
-    gui_param->set (0);
-    gui_name = gui_param->get_choice (gui_param->get ());
-    if (!strcmp (gui_name, "wx")) {
-      BX_PANIC (("no alternative display libraries are available"));
-      return false;
-    }
-    BX_ERROR (("changing display library to '%s' instead", gui_name));
-  }
-#if BX_WITH_NOGUI
-  if (!strcmp (gui_name, "nogui")) 
-    PLUG_load_plugin (nogui, PLUGTYPE_OPTIONAL);
-#endif
-#if BX_WITH_RFB
-  if (!strcmp (gui_name, "rfb")) 
-    PLUG_load_plugin (rfb, PLUGTYPE_OPTIONAL);
-#endif
-#if BX_WITH_X11
-  if (!strcmp (gui_name, "x")) 
-    PLUG_load_plugin (x, PLUGTYPE_OPTIONAL);
-#endif
-#if BX_WITH_TERM
-  if (!strcmp (gui_name, "term"))
-    PLUG_load_plugin (term, PLUGTYPE_OPTIONAL);
-#endif
-
-#if BX_GUI_SIGHANDLER
-  // set the flag for guis requiring a GUI sighandler.
-  // useful when guis are compiled as plugins
-  // only term for now
-  if (!strcmp (gui_name, "term")) {
-    bx_gui_sighandler = 1;
-    }
-#endif
-
-  BX_ASSERT (bx_gui != NULL);
-  return true;
-}
-
-int
-bx_begin_simulation (int argc, char *argv[])
-{
-  // deal with gui selection
-  if (!load_and_init_display_lib ()) {
-    BX_PANIC (("no gui module was loaded"));
-    return 0;
-  }
-#if BX_GDBSTUB
-  // If using gdbstub, it will take control and call
-  // bx_init_hardware() and cpu_loop()
-  bx_gdbstub_init (argc, argv);
-#elif BX_DEBUGGER
-  // If using the debugger, it will take control and call
-  // bx_init_hardware() and cpu_loop()
-  bx_dbg_main(argc, argv);
-#else
-
-  bx_init_hardware();
-
-  if (bx_options.load32bitOSImage.OwhichOS->get ()) {
-    void bx_load32bitOSimagehack(void);
-    bx_load32bitOSimagehack();
-    }
-
-  SIM->set_init_done (1);
-
-  // update headerbar buttons since drive status can change during init
-  bx_gui->update_drive_status_buttons ();
-
-  // The set handler for mouse_enabled does not actually update the gui
-  // until init_done is set.  This forces the set handler to be called,
-  // which sets up the mouse enabled GUI-specific stuff correctly.
-  // Not a great solution but it works. BBD
-  bx_options.Omouse_enabled->set (bx_options.Omouse_enabled->get ());
-
-  if (BX_SMP_PROCESSORS == 1) {
-    // only one processor, run as fast as possible by not messing with
-    // quantums and loops.
-    BX_CPU(0)->cpu_loop(1);
-        // for one processor, the only reason for cpu_loop to return is
-        // that kill_bochs_request was set by the GUI interface.
-  } else {
-    // SMP simulation: do a few instructions on each processor, then switch
-    // to another.  Increasing quantum speeds up overall performance, but
-    // reduces granularity of synchronization between processors.
-    int processor = 0;
-    int quantum = 5;
-    while (1) {
-      // do some instructions in each processor
-      BX_CPU(processor)->cpu_loop(quantum);
-      processor = (processor+1) % BX_SMP_PROCESSORS;
-          if (BX_CPU(0)->kill_bochs_request) 
-            break;
-      if (processor == 0) 
-            BX_TICKN(quantum);
-    }
-  }
-#endif
-  BX_INFO (("cpu loop quit, shutting down simulator"));
-  bx_atexit ();
-  return(0);
-}
-
-
-int
-bx_read_configuration (char *rcfile)
-{
-  // parse rcfile first, then parse arguments in order.
-  BX_INFO (("reading configuration from %s", rcfile));
-  if (parse_bochsrc(rcfile) < 0) {
-    BX_PANIC (("reading from %s failed", rcfile));
-    return -1;
-  }
-  // update log actions
-  for (int level=0; level<N_LOGLEV; level++) {
-    int action = SIM->get_default_log_action (level);
-    io->set_log_action (level, action);
-  }
-  return 0;
-}
-
-int bx_parse_cmdline (int arg, int argc, char *argv[])
-{
-  //if (arg < argc) BX_INFO (("parsing command line arguments"));
-
-  while (arg < argc) {
-    BX_INFO (("parsing arg %d, %s", arg, argv[arg]));
-    parse_line_unformatted("cmdline args", argv[arg]);
-    arg++;
-  }
-  // update log actions
-  for (int level=0; level<N_LOGLEV; level++) {
-    int action = SIM->get_default_log_action (level);
-    io->set_log_action (level, action);
-  }
-  return 0;
-}
-
-  int
-bx_init_hardware()
-{
-  // all configuration has been read, now initialize everything.
-
-  if (SIM->get_param_enum(BXP_BOCHS_START)->get ()==BX_QUICK_START) {
-    for (int level=0; level<N_LOGLEV; level++) {
-      int action = SIM->get_default_log_action (level);
-#if !BX_USE_CONFIG_INTERFACE
-      if (action == ACT_ASK) action = ACT_FATAL;
-#endif
-      io->set_log_action (level, action);
-    }
-  }
-
-  bx_pc_system.init_ips(bx_options.Oips->get ());
-
-  if(bx_options.log.Ofilename->getptr()[0]!='-') {
-    BX_INFO (("using log file %s", bx_options.log.Ofilename->getptr ()));
-    io->init_log(bx_options.log.Ofilename->getptr ());
-  }
-
-  io->set_log_prefix(bx_options.log.Oprefix->getptr());
-
-  // Output to the log file the cpu settings
-  // This will by handy for bug reports
-  BX_INFO(("Bochs x86 Emulator %s", VER_STRING));
-  BX_INFO(("  %s", REL_STRING));
-  BX_INFO(("System configuration"));
-  BX_INFO(("  processors: %d",BX_SMP_PROCESSORS));
-  BX_INFO(("  A20 line support: %s",BX_SUPPORT_A20?"yes":"no"));
-  BX_INFO(("  APIC support: %s",BX_SUPPORT_APIC?"yes":"no"));
-
-#ifndef BX_USE_VMX
-  BX_INFO(("CPU configuration"));
-  BX_INFO(("  level: %d",BX_CPU_LEVEL));
-  BX_INFO(("  fpu support: %s",BX_SUPPORT_FPU?"yes":"no"));
-  BX_INFO(("  paging support: %s, tlb enabled: %s",BX_SUPPORT_PAGING?"yes":"no",BX_USE_TLB?"yes":"no"));
-  BX_INFO(("  mmx support: %s",BX_SUPPORT_MMX?"yes":"no"));
-  BX_INFO(("  sse support: %s",BX_SUPPORT_SSE==2?"2":BX_SUPPORT_SSE==1?"1":"no"));
-  BX_INFO(("  v8086 mode support: %s",BX_SUPPORT_V8086_MODE?"yes":"no"));
-  BX_INFO(("  3dnow! support: %s",BX_SUPPORT_3DNOW?"yes":"no"));
-  BX_INFO(("  PAE support: %s",BX_SupportPAE?"yes":"no"));
-  BX_INFO(("  PGE support: %s",BX_SupportGlobalPages?"yes":"no"));
-  BX_INFO(("  PSE support: %s",BX_SUPPORT_4MEG_PAGES?"yes":"no"));
-  BX_INFO(("  x86-64 support: %s",BX_SUPPORT_X86_64?"yes":"no"));
-  BX_INFO(("  SEP support: %s",BX_SUPPORT_SEP?"yes":"no"));
-  BX_INFO(("Optimization configuration"));
-  BX_INFO(("  Guest2HostTLB support: %s",BX_SupportGuest2HostTLB?"yes":"no"));
-  BX_INFO(("  RepeatSpeedups support: %s",BX_SupportRepeatSpeedups?"yes":"no"));
-  BX_INFO(("  Icache support: %s",BX_SupportICache?"yes":"no"));
-  BX_INFO(("  Host Asm support: %s",BX_SupportHostAsms?"yes":"no"));
-#endif /* BX_USE_VMX */
-
-  // set up memory and CPU objects
-#if BX_SUPPORT_APIC
-  bx_generic_apic_c::reset_all_ids ();
-#endif
-
-#ifndef BX_USE_VMX
-  // Check if there is a romimage
-  if (strcmp(bx_options.rom.Opath->getptr (),"") == 0) {
-    BX_ERROR(("No romimage to load. Is your bochsrc file loaded/valid ?"));
-  }
-
-#if BX_SMP_PROCESSORS==1
-  BX_MEM(0)->init_memory(bx_options.memory.Osize->get () * 1024*1024);
-
-  // First load the optional ROM images
-  if (strcmp(bx_options.optrom[0].Opath->getptr (),"") !=0 )
-    BX_MEM(0)->load_ROM(bx_options.optrom[0].Opath->getptr (), bx_options.optrom[0].Oaddress->get (), 2);
-  if (strcmp(bx_options.optrom[1].Opath->getptr (),"") !=0 )
-    BX_MEM(0)->load_ROM(bx_options.optrom[1].Opath->getptr (), bx_options.optrom[1].Oaddress->get (), 2);
-  if (strcmp(bx_options.optrom[2].Opath->getptr (),"") !=0 )
-    BX_MEM(0)->load_ROM(bx_options.optrom[2].Opath->getptr (), bx_options.optrom[2].Oaddress->get (), 2);
-  if (strcmp(bx_options.optrom[3].Opath->getptr (),"") !=0 )
-    BX_MEM(0)->load_ROM(bx_options.optrom[3].Opath->getptr (), bx_options.optrom[3].Oaddress->get (), 2);
-
-  // Then Load the BIOS and VGABIOS
-  BX_MEM(0)->load_ROM(bx_options.rom.Opath->getptr (), bx_options.rom.Oaddress->get (), 0);
-  BX_MEM(0)->load_ROM(bx_options.vgarom.Opath->getptr (), 0xc0000, 1);
-
-  BX_CPU(0)->init (BX_MEM(0));
-  BX_CPU(0)->set_cpu_id(0);
-#if BX_SUPPORT_APIC
-  BX_CPU(0)->local_apic.set_id (0);
-#endif
-  BX_INSTR_INIT(0);
-  BX_CPU(0)->reset(BX_RESET_HARDWARE);
-#else
-  // SMP initialization
-  bx_mem_array[0] = new BX_MEM_C ();
-  bx_mem_array[0]->init_memory(bx_options.memory.Osize->get () * 1024*1024);
-
-  // First load the optional ROM images
-  if (strcmp(bx_options.optrom[0].Opath->getptr (),"") !=0 )
-    bx_mem_array[0]->load_ROM(bx_options.optrom[0].Opath->getptr (), bx_options.optrom[0].Oaddress->get (), 2);
-  if (strcmp(bx_options.optrom[1].Opath->getptr (),"") !=0 )
-    bx_mem_array[0]->load_ROM(bx_options.optrom[1].Opath->getptr (), bx_options.optrom[1].Oaddress->get (), 2);
-  if (strcmp(bx_options.optrom[2].Opath->getptr (),"") !=0 )
-    bx_mem_array[0]->load_ROM(bx_options.optrom[2].Opath->getptr (), bx_options.optrom[2].Oaddress->get (), 2);
-  if (strcmp(bx_options.optrom[3].Opath->getptr (),"") !=0 )
-    bx_mem_array[0]->load_ROM(bx_options.optrom[3].Opath->getptr (), bx_options.optrom[3].Oaddress->get (), 2);
-
-  // Then Load the BIOS and VGABIOS
-  bx_mem_array[0]->load_ROM(bx_options.rom.Opath->getptr (), bx_options.rom.Oaddress->get (), 0);
-  bx_mem_array[0]->load_ROM(bx_options.vgarom.Opath->getptr (), 0xc0000, 1);
-
-  for (int i=0; i<BX_SMP_PROCESSORS; i++) {
-    BX_CPU(i) = new BX_CPU_C;
-    BX_CPU(i)->init (bx_mem_array[0]);
-    // assign apic ID from the index of this loop
-    // if !BX_SUPPORT_APIC, this will not compile.
-    BX_CPU(i)->set_cpu_id(i);
-    BX_CPU(i)->local_apic.set_id (i);
-    BX_INSTR_INIT(i);
-    BX_CPU(i)->reset(BX_RESET_HARDWARE);
-  }
-#endif
-#else
-    // Assume UP for now for VMX
-    bx_mem.init_memory(megabytes * 1024 * 1024);
-    bx_cpu.init(&bx_mem);
-#endif // BX_USE_VMX
-
-#if BX_DEBUGGER == 0
-  DEV_init_devices();
-  DEV_reset_devices(BX_RESET_HARDWARE);
-  bx_gui->init_signal_handlers ();
-  bx_pc_system.start_timers();
-#endif
-  BX_DEBUG(("bx_init_hardware is setting signal handlers"));
-// if not using debugger, then we can take control of SIGINT.
-#if !BX_DEBUGGER
-  signal(SIGINT, bx_signal_handler);
-#endif
-
-#if BX_SHOW_IPS
-#ifndef __MINGW32__
-  signal(SIGALRM, bx_signal_handler);
-#endif
-  alarm( 1 );
-#endif
-
-  return(0);
-}
-
-
-
-  void
-bx_init_bx_dbg (void)
-{
-  bx_dbg.floppy = 0;
-  bx_dbg.keyboard = 0;
-  bx_dbg.video = 0;
-  bx_dbg.disk = 0;
-  bx_dbg.pit = 0;
-  bx_dbg.pic = 0;
-  bx_dbg.bios = 0;
-  bx_dbg.cmos = 0;
-  bx_dbg.a20 = 0;
-  bx_dbg.interrupts = 0;
-  bx_dbg.exceptions = 0;
-  bx_dbg.unsupported = 0;
-  bx_dbg.temp = 0;
-  bx_dbg.reset = 0;
-  bx_dbg.mouse = 0;
-  bx_dbg.io = 0;
-  bx_dbg.debugger = 0;
-  bx_dbg.xms = 0;
-  bx_dbg.v8086 = 0;
-  bx_dbg.paging = 0;
-  bx_dbg.creg = 0;
-  bx_dbg.dreg = 0;
-  bx_dbg.dma = 0;
-  bx_dbg.unsupported_io = 0;
-  bx_dbg.record_io = 0;
-  bx_dbg.serial = 0;
-  bx_dbg.cdrom = 0;
-#ifdef MAGIC_BREAKPOINT
-  bx_dbg.magic_break_enabled = 0;
-#endif
-
-}
-
-
-int
-bx_atexit(void)
-{
-  static bx_bool been_here = 0;
-  if (been_here) return 1;   // protect from reentry
-  been_here = 1;
-
-  // in case we ended up in simulation mode, change back to config mode
-  // so that the user can see any messages left behind on the console.
-  SIM->set_display_mode (DISP_MODE_CONFIG);
-
-#if BX_PROVIDE_DEVICE_MODELS==1
-  bx_pc_system.exit();
-#endif
-
-#if BX_DEBUGGER == 0
-  if (SIM && SIM->get_init_done ()) {
-    for (int cpu=0; cpu<BX_SMP_PROCESSORS; cpu++)
-      if (BX_CPU(cpu)) BX_CPU(cpu)->atexit();
-  }
-#endif
-
-#if BX_PCI_SUPPORT
-  if (bx_options.Oi440FXSupport->get ()) {
-    bx_devices.pluginPciBridge->print_i440fx_state();
-    }
-#endif
-
-  // restore signal handling to defaults
-#if !BX_DEBUGGER
-  BX_INFO (("restoring default signal behavior"));
-  signal(SIGINT, SIG_DFL);
-#endif
-
-#if BX_SHOW_IPS
-#ifndef __MINGW32__
-  signal(SIGALRM, SIG_DFL);
-#endif
-#endif
-        return 0;
-}
-
-#if BX_PROVIDE_MAIN
-
-char *
-bx_find_bochsrc ()
-{
-  FILE *fd = NULL;
-  char rcfile[512];
-  Bit32u retry = 0, found = 0;
-  // try several possibilities for the bochsrc before giving up
-  while (!found) {
-    rcfile[0] = 0;
-    switch (retry++) {
-    case 0: strcpy (rcfile, ".bochsrc"); break;
-    case 1: strcpy (rcfile, "bochsrc"); break;
-    case 2: strcpy (rcfile, "bochsrc.txt"); break;
-#ifdef WIN32
-    case 3: strcpy (rcfile, "bochsrc.bxrc"); break;
-#elif !BX_WITH_MACOS
-      // only try this on unix
-    case 3:
-      {
-      char *ptr = getenv("HOME");
-      if (ptr) snprintf (rcfile, sizeof(rcfile), "%s/.bochsrc", ptr);
-      }
-      break;
-     case 4: strcpy (rcfile, "/etc/bochsrc"); break;
-#endif
-    default:
-      return NULL;
-    }
-    if (rcfile[0]) {
-      BX_DEBUG (("looking for configuration in %s", rcfile));
-      fd = fopen(rcfile, "r");
-      if (fd) found = 1;
-    }
-  }
-  assert (fd != NULL && rcfile[0] != 0);
-  fclose (fd);
-  return strdup (rcfile);
-}
-
-  static int
-parse_bochsrc(char *rcfile)
-{
-  FILE *fd = NULL;
-  char *ret;
-  char line[512];
-
-  // try several possibilities for the bochsrc before giving up
-
-  bochsrc_include_count++;
-
-  fd = fopen (rcfile, "r");
-  if (fd == NULL) return -1;
-
-  int retval = 0;
-  do {
-    ret = fgets(line, sizeof(line)-1, fd);
-    line[sizeof(line) - 1] = '\0';
-    int len = strlen(line);
-    if (len>0)
-      line[len-1] = '\0';
-    if ((ret != NULL) && strlen(line)) {
-      if (parse_line_unformatted(rcfile, line) < 0) {
-        retval = -1;
-        break;  // quit parsing after first error
-        }
-      }
-    } while (!feof(fd));
-  fclose(fd);
-  bochsrc_include_count--;
-  return retval;
-}
-
-  static Bit32s
-parse_line_unformatted(char *context, char *line)
-{
-#define MAX_PARAMS_LEN 40
-  char *ptr;
-  unsigned i, string_i;
-  char string[512];
-  char *params[MAX_PARAMS_LEN];
-  int num_params;
-  bx_bool inquotes = 0;
-  bx_bool comment = 0;
-
-  memset(params, 0, sizeof(params));
-  if (line == NULL) return 0;
-
-  // if passed nothing but whitespace, just return
-  for (i=0; i<strlen(line); i++) {
-    if (!isspace(line[i])) break;
-    }
-  if (i>=strlen(line))
-    return 0;
-
-  num_params = 0;
-
-  if (!strncmp(line, "#include", 8))
-    ptr = strtok(line, " ");
-  else
-    ptr = strtok(line, ":");
-  while ((ptr) && (!comment)) {
-    string_i = 0;
-    for (i=0; i<strlen(ptr); i++) {
-      if (ptr[i] == '"')
-        inquotes = !inquotes;
-      else if ((ptr[i] == '#') && (strncmp(line+i, "#include", 8)) && !inquotes) {
-        comment = 1;
-        break;
-      } else {
-#if BX_HAVE_GETENV
-        // substitute environment variables.
-        if (ptr[i] == '$') {
-          char varname[512];
-          char *pv = varname;
-          char *value;
-          *pv = 0;
-          i++;
-          while (isalpha(ptr[i]) || ptr[i]=='_') {
-            *pv = ptr[i]; pv++; i++;
-          }
-          *pv = 0;
-          if (strlen(varname)<1 || !(value = getenv(varname))) {
-              BX_PANIC (("could not look up environment variable '%s'", varname));
-          } else {
-            // append value to the string
-            for (pv=value; *pv; pv++)
-                string[string_i++] = *pv;
-          }
-        }
-#endif
-        if (!isspace(ptr[i]) || inquotes) {
-          string[string_i++] = ptr[i];
-        }
-      }
-    }
-    string[string_i] = '\0';
-    if (string_i == 0) break;
-    if ( params[num_params] != NULL )
-    {
-        free(params[num_params]);
-        params[num_params] = NULL;
-    }
-    if ( num_params < MAX_PARAMS_LEN )
-    {
-    params[num_params++] = strdup (string);
-    ptr = strtok(NULL, ",");
-  }
-    else
-    {
-        BX_PANIC (("too many parameters, max is %d\n", MAX_PARAMS_LEN));
-    }
-  }
-  Bit32s retval = parse_line_formatted(context, num_params, &params[0]);
-  for (i=0; i < MAX_PARAMS_LEN; i++)
-  {
-    if ( params[i] != NULL )
-    {
-        free(params[i]);
-        params[i] = NULL;
-    }
-  }
-  return retval;
-}
-
-// These macros are called for all parse errors, so that we can easily
-// change the behavior of all occurrences.
-#define PARSE_ERR(x)  \
-  do { BX_PANIC(x); return -1; } while (0)
-#define PARSE_WARN(x)  \
-  BX_ERROR(x)
-
-  static Bit32s
-parse_line_formatted(char *context, int num_params, char *params[])
-{
-  int i;
-
-  if (num_params < 1) return 0;
-  if (num_params < 2) {
-    PARSE_ERR(("%s: a bochsrc option needs at least one parameter", context));
-  }
-
-  if (!strcmp(params[0], "#include")) {
-    if (num_params != 2) {
-      PARSE_ERR(("%s: ignoring malformed #include directive.", context));
-      }
-    if (!strcmp(params[1], context)) {
-      PARSE_ERR(("%s: cannot include this file again.", context));
-      }
-    if (bochsrc_include_count == 2) {
-      PARSE_ERR(("%s: include directive in an included file not supported yet.", context));
-      }
-    bx_read_configuration(params[1]);
-    }
-  else if (!strcmp(params[0], "floppya")) {
-    for (i=1; i<num_params; i++) {
-      if (!strncmp(params[i], "2_88=", 5)) {
-        bx_options.floppya.Opath->set (&params[i][5]);
-        bx_options.floppya.Otype->set (BX_FLOPPY_2_88);
-        }
-      else if (!strncmp(params[i], "1_44=", 5)) {
-        bx_options.floppya.Opath->set (&params[i][5]);
-        bx_options.floppya.Otype->set (BX_FLOPPY_1_44);
-        }
-      else if (!strncmp(params[i], "1_2=", 4)) {
-        bx_options.floppya.Opath->set (&params[i][4]);
-        bx_options.floppya.Otype->set (BX_FLOPPY_1_2);
-        }
-      else if (!strncmp(params[i], "720k=", 5)) {
-        bx_options.floppya.Opath->set (&params[i][5]);
-        bx_options.floppya.Otype->set (BX_FLOPPY_720K);
-        }
-      else if (!strncmp(params[i], "360k=", 5)) {
-        bx_options.floppya.Opath->set (&params[i][5]);
-        bx_options.floppya.Otype->set (BX_FLOPPY_360K);
-        }
-      // use CMOS reserved types?
-      else if (!strncmp(params[i], "160k=", 5)) {
-        bx_options.floppya.Opath->set (&params[i][5]);
-        bx_options.floppya.Otype->set (BX_FLOPPY_160K);
-        }
-      else if (!strncmp(params[i], "180k=", 5)) {
-        bx_options.floppya.Opath->set (&params[i][5]);
-        bx_options.floppya.Otype->set (BX_FLOPPY_180K);
-        }
-      else if (!strncmp(params[i], "320k=", 5)) {
-        bx_options.floppya.Opath->set (&params[i][5]);
-        bx_options.floppya.Otype->set (BX_FLOPPY_320K);
-        }
-      else if (!strncmp(params[i], "status=ejected", 14)) {
-        bx_options.floppya.Ostatus->set (BX_EJECTED);
-        }
-      else if (!strncmp(params[i], "status=inserted", 15)) {
-        bx_options.floppya.Ostatus->set (BX_INSERTED);
-        }
-      else {
-        PARSE_ERR(("%s: floppya attribute '%s' not understood.", context,
-          params[i]));
-        }
-      }
-    }
-   else if (!strcmp(params[0], "gdbstub_port"))
-     {
-       if (num_params != 2)
-         {
-            fprintf(stderr, ".bochsrc: gdbstub_port directive: wrong # args.\n");
-            exit(1);
-         }
-       bx_options.gdbstub.port = atoi(params[1]);
-     }
-   else if (!strcmp(params[0], "gdbstub_text_base"))
-     {
-       if (num_params != 2)
-         {
-            fprintf(stderr, ".bochsrc: gdbstub_text_base directive: wrong # args.\n");
-            exit(1);
-         }
-       bx_options.gdbstub.text_base = atoi(params[1]);
-     }
-   else if (!strcmp(params[0], "gdbstub_data_base"))
-     {
-       if (num_params != 2)
-         {
-            fprintf(stderr, ".bochsrc: gdbstub_data_base directive: wrong # args.\n");
-            exit(1);
-         }
-       bx_options.gdbstub.data_base = atoi(params[1]);
-     }
-   else if (!strcmp(params[0], "gdbstub_bss_base"))
-     {
-       if (num_params != 2)
-         {
-            fprintf(stderr, ".bochsrc: gdbstub_bss_base directive: wrong # args.\n");
-            exit(1);
-         }
-       bx_options.gdbstub.bss_base = atoi(params[1]);
-     }
-
-  else if (!strcmp(params[0], "floppyb")) {
-    for (i=1; i<num_params; i++) {
-      if (!strncmp(params[i], "2_88=", 5)) {
-        bx_options.floppyb.Opath->set (&params[i][5]);
-        bx_options.floppyb.Otype->set (BX_FLOPPY_2_88);
-        }
-      else if (!strncmp(params[i], "1_44=", 5)) {
-        bx_options.floppyb.Opath->set (&params[i][5]);
-        bx_options.floppyb.Otype->set (BX_FLOPPY_1_44);
-        }
-      else if (!strncmp(params[i], "1_2=", 4)) {
-        bx_options.floppyb.Opath->set (&params[i][4]);
-        bx_options.floppyb.Otype->set (BX_FLOPPY_1_2);
-        }
-      else if (!strncmp(params[i], "720k=", 5)) {
-        bx_options.floppyb.Opath->set (&params[i][5]);
-        bx_options.floppyb.Otype->set (BX_FLOPPY_720K);
-        }
-      else if (!strncmp(params[i], "360k=", 5)) {
-        bx_options.floppyb.Opath->set (&params[i][5]);
-        bx_options.floppyb.Otype->set (BX_FLOPPY_360K);
-        }
-      // use CMOS reserved types?
-      else if (!strncmp(params[i], "160k=", 5)) {
-        bx_options.floppyb.Opath->set (&params[i][5]);
-        bx_options.floppyb.Otype->set (BX_FLOPPY_160K);
-        }
-      else if (!strncmp(params[i], "180k=", 5)) {
-        bx_options.floppyb.Opath->set (&params[i][5]);
-        bx_options.floppyb.Otype->set (BX_FLOPPY_180K);
-        }
-      else if (!strncmp(params[i], "320k=", 5)) {
-        bx_options.floppyb.Opath->set (&params[i][5]);
-        bx_options.floppyb.Otype->set (BX_FLOPPY_320K);
-        }
-      else if (!strncmp(params[i], "status=ejected", 14)) {
-        bx_options.floppyb.Ostatus->set (BX_EJECTED);
-        }
-      else if (!strncmp(params[i], "status=inserted", 15)) {
-        bx_options.floppyb.Ostatus->set (BX_INSERTED);
-        }
-      else {
-        PARSE_ERR(("%s: floppyb attribute '%s' not understood.", context,
-          params[i]));
-        }
-      }
-    }
-
-  else if ((!strncmp(params[0], "ata", 3)) && (strlen(params[0]) == 4)) {
-    Bit8u channel = params[0][3];
-
-    if ((channel < '0') || (channel > '9')) {
-      PARSE_ERR(("%s: ataX directive malformed.", context));
-      }
-    channel-='0';
-    if (channel >= BX_MAX_ATA_CHANNEL) {
-      PARSE_ERR(("%s: ataX directive malformed.", context));
-      }
-
-    if ((num_params < 2) || (num_params > 5)) {
-      PARSE_ERR(("%s: ataX directive malformed.", context));
-      }
-
-    if (strncmp(params[1], "enabled=", 8)) {
-      PARSE_ERR(("%s: ataX directive malformed.", context));
-      }
-    else {
-      bx_options.ata[channel].Opresent->set (atol(&params[1][8]));
-      }
-
-    if (num_params > 2) {
-      if (strncmp(params[2], "ioaddr1=", 8)) {
-        PARSE_ERR(("%s: ataX directive malformed.", context));
-        }
-      else {
-        if ( (params[2][8] == '0') && (params[2][9] == 'x') )
-          bx_options.ata[channel].Oioaddr1->set (strtoul (&params[2][8], NULL, 16));
-        else
-          bx_options.ata[channel].Oioaddr1->set (strtoul (&params[2][8], NULL, 10));
-        }
-      }
-
-    if (num_params > 3) {
-      if (strncmp(params[3], "ioaddr2=", 8)) {
-        PARSE_ERR(("%s: ataX directive malformed.", context));
-        }
-      else {
-        if ( (params[3][8] == '0') && (params[3][9] == 'x') )
-          bx_options.ata[channel].Oioaddr2->set (strtoul (&params[3][8], NULL, 16));
-        else
-          bx_options.ata[channel].Oioaddr2->set (strtoul (&params[3][8], NULL, 10));
-        }
-      }
-
-    if (num_params > 4) {
-      if (strncmp(params[4], "irq=", 4)) {
-        PARSE_ERR(("%s: ataX directive malformed.", context));
-        }
-      else {
-        bx_options.ata[channel].Oirq->set (atol(&params[4][4]));
-        }
-      }
-    }
-
-  // ataX-master, ataX-slave
-  else if ((!strncmp(params[0], "ata", 3)) && (strlen(params[0]) > 4)) {
-    Bit8u channel = params[0][3], slave = 0;
-
-    if ((channel < '0') || (channel > '9')) {
-      PARSE_ERR(("%s: ataX-master/slave directive malformed.", context));
-      }
-    channel-='0';
-    if (channel >= BX_MAX_ATA_CHANNEL) {
-      PARSE_ERR(("%s: ataX-master/slave directive malformed.", context));
-      }
-
-    if ((strcmp(&params[0][4], "-slave")) &&
-        (strcmp(&params[0][4], "-master"))) {
-      PARSE_ERR(("%s: ataX-master/slave directive malformed.", context));
-      }
-
-    if (!strcmp(&params[0][4], "-slave")) {
-      slave = 1;
-      }
-
-    // This was originally meant to warn users about both diskc
-    // and ata0-master defined, but it also prevent users to
-    // override settings on the command line 
-    // (see [ 661010 ] cannot override ata-settings from cmdline)
-    // if (bx_options.atadevice[channel][slave].Opresent->get()) {
-    //   BX_INFO(("%s: %s device of ata channel %d already defined.", context, slave?"slave":"master",channel));
-    //   }
-
-    for (i=1; i<num_params; i++) {
-      if (!strcmp(params[i], "type=disk")) {
-        bx_options.atadevice[channel][slave].Otype->set (BX_ATA_DEVICE_DISK);
-        }
-      else if (!strcmp(params[i], "type=cdrom")) {
-        bx_options.atadevice[channel][slave].Otype->set (BX_ATA_DEVICE_CDROM);
-        }
-      else if (!strcmp(params[i], "mode=flat")) {
-        bx_options.atadevice[channel][slave].Omode->set (BX_ATA_MODE_FLAT);
-        }
-      else if (!strcmp(params[i], "mode=concat")) {
-        bx_options.atadevice[channel][slave].Omode->set (BX_ATA_MODE_CONCAT);
-        }
-      else if (!strcmp(params[i], "mode=external")) {
-        bx_options.atadevice[channel][slave].Omode->set (BX_ATA_MODE_EXTDISKSIM);
-        }
-      else if (!strcmp(params[i], "mode=dll")) {
-        bx_options.atadevice[channel][slave].Omode->set (BX_ATA_MODE_DLL_HD);
-        }
-      else if (!strcmp(params[i], "mode=sparse")) {
-        bx_options.atadevice[channel][slave].Omode->set (BX_ATA_MODE_SPARSE);
-        }
-      else if (!strcmp(params[i], "mode=vmware3")) {
-        bx_options.atadevice[channel][slave].Omode->set (BX_ATA_MODE_VMWARE3);
-        }
-//      else if (!strcmp(params[i], "mode=split")) {
-//        bx_options.atadevice[channel][slave].Omode->set (BX_ATA_MODE_SPLIT);
-//        }
-      else if (!strcmp(params[i], "mode=undoable")) {
-        bx_options.atadevice[channel][slave].Omode->set (BX_ATA_MODE_UNDOABLE);
-        }
-      else if (!strcmp(params[i], "mode=growing")) {
-        bx_options.atadevice[channel][slave].Omode->set (BX_ATA_MODE_GROWING);
-        }
-      else if (!strcmp(params[i], "mode=volatile")) {
-        bx_options.atadevice[channel][slave].Omode->set (BX_ATA_MODE_VOLATILE);
-        }
-//      else if (!strcmp(params[i], "mode=z-undoable")) {
-//        bx_options.atadevice[channel][slave].Omode->set (BX_ATA_MODE_Z_UNDOABLE);
-//        }
-//      else if (!strcmp(params[i], "mode=z-volatile")) {
-//        bx_options.atadevice[channel][slave].Omode->set (BX_ATA_MODE_Z_VOLATILE);
-//        }
-      else if (!strncmp(params[i], "path=", 5)) {
-        bx_options.atadevice[channel][slave].Opath->set (&params[i][5]);
-        }
-      else if (!strncmp(params[i], "cylinders=", 10)) {
-        bx_options.atadevice[channel][slave].Ocylinders->set (atol(&params[i][10]));
-        }
-      else if (!strncmp(params[i], "heads=", 6)) {
-        bx_options.atadevice[channel][slave].Oheads->set (atol(&params[i][6]));
-        }
-      else if (!strncmp(params[i], "spt=", 4)) {
-        bx_options.atadevice[channel][slave].Ospt->set (atol(&params[i][4]));
-        }
-      else if (!strncmp(params[i], "model=", 6)) {
-        bx_options.atadevice[channel][slave].Omodel->set(&params[i][6]);
-        }
-      else if (!strcmp(params[i], "biosdetect=none")) {
-        bx_options.atadevice[channel][slave].Obiosdetect->set(BX_ATA_BIOSDETECT_NONE);
-        }
-      else if (!strcmp(params[i], "biosdetect=cmos")) {
-        bx_options.atadevice[channel][slave].Obiosdetect->set(BX_ATA_BIOSDETECT_CMOS);
-        }
-      else if (!strcmp(params[i], "biosdetect=auto")) {
-        bx_options.atadevice[channel][slave].Obiosdetect->set(BX_ATA_BIOSDETECT_AUTO);
-        }
-      else if (!strcmp(params[i], "translation=none")) {
-        bx_options.atadevice[channel][slave].Otranslation->set(BX_ATA_TRANSLATION_NONE);
-        }
-      else if (!strcmp(params[i], "translation=lba")) {
-        bx_options.atadevice[channel][slave].Otranslation->set(BX_ATA_TRANSLATION_LBA);
-        }
-      else if (!strcmp(params[i], "translation=large")) { 
-        bx_options.atadevice[channel][slave].Otranslation->set(BX_ATA_TRANSLATION_LARGE);
-        }
-      else if (!strcmp(params[i], "translation=echs")) { // synonym of large
-        bx_options.atadevice[channel][slave].Otranslation->set(BX_ATA_TRANSLATION_LARGE);
-        }
-      else if (!strcmp(params[i], "translation=rechs")) {
-        bx_options.atadevice[channel][slave].Otranslation->set(BX_ATA_TRANSLATION_RECHS);
-        }
-      else if (!strcmp(params[i], "translation=auto")) {
-        bx_options.atadevice[channel][slave].Otranslation->set(BX_ATA_TRANSLATION_AUTO);
-        }
-      else if (!strcmp(params[i], "status=ejected")) {
-        bx_options.atadevice[channel][slave].Ostatus->set(BX_EJECTED);
-        }
-      else if (!strcmp(params[i], "status=inserted")) {
-        bx_options.atadevice[channel][slave].Ostatus->set(BX_INSERTED);
-        }
-      else if (!strncmp(params[i], "journal=", 8)) {
-        bx_options.atadevice[channel][slave].Ojournal->set(&params[i][8]);
-        }
-      else {
-        PARSE_ERR(("%s: ataX-master/slave directive malformed.", context));
-        }
-      }
-
-    // Enables the ata device
-    bx_options.atadevice[channel][slave].Opresent->set(1);
-
-    // if enabled, check if device ok
-    if (bx_options.atadevice[channel][slave].Opresent->get() == 1) {
-      if (bx_options.atadevice[channel][slave].Otype->get() == BX_ATA_DEVICE_DISK) {
-        if (strlen(bx_options.atadevice[channel][slave].Opath->getptr()) ==0)
-          PARSE_WARN(("%s: ataX-master/slave has empty path", context));
-        if ((bx_options.atadevice[channel][slave].Ocylinders->get() == 0) ||
-            (bx_options.atadevice[channel][slave].Oheads->get() ==0 ) ||
-            (bx_options.atadevice[channel][slave].Ospt->get() == 0)) {
-          PARSE_WARN(("%s: ataX-master/slave cannot have zero cylinders, heads, or sectors/track", context));
-          }
-        }
-      else if (bx_options.atadevice[channel][slave].Otype->get() == BX_ATA_DEVICE_CDROM) {
-        if (strlen(bx_options.atadevice[channel][slave].Opath->getptr()) == 0) {
-          PARSE_WARN(("%s: ataX-master/slave has empty path", context));
-          }
-        }
-      else {
-        PARSE_WARN(("%s: ataX-master/slave: type should be specified", context));
-        }
-      }
-    }
-
-  // Legacy disk options emulation
-  else if (!strcmp(params[0], "diskc")) { // DEPRECATED
-    BX_INFO(("WARNING: diskc directive is deprecated, use ata0-master: instead"));
-    if (bx_options.atadevice[0][0].Opresent->get()) {
-      PARSE_ERR(("%s: master device of ata channel 0 already defined.", context));
-      }
-    if (num_params != 5) {
-      PARSE_ERR(("%s: diskc directive malformed.", context));
-      }
-    if (strncmp(params[1], "file=", 5) ||
-        strncmp(params[2], "cyl=", 4) ||
-        strncmp(params[3], "heads=", 6) ||
-        strncmp(params[4], "spt=", 4)) {
-      PARSE_ERR(("%s: diskc directive malformed.", context));
-      }
-    bx_options.ata[0].Opresent->set(1);
-    bx_options.atadevice[0][0].Otype->set (BX_ATA_DEVICE_DISK);
-    bx_options.atadevice[0][0].Opath->set (&params[1][5]);
-    bx_options.atadevice[0][0].Ocylinders->set (atol(&params[2][4]));
-    bx_options.atadevice[0][0].Oheads->set     (atol(&params[3][6]));
-    bx_options.atadevice[0][0].Ospt->set       (atol(&params[4][4]));
-    bx_options.atadevice[0][0].Opresent->set (1);
-    }
-  else if (!strcmp(params[0], "diskd")) { // DEPRECATED
-    BX_INFO(("WARNING: diskd directive is deprecated, use ata0-slave: instead"));
-    if (bx_options.atadevice[0][1].Opresent->get()) {
-      PARSE_ERR(("%s: slave device of ata channel 0 already defined.", context));
-      }
-    if (num_params != 5) {
-      PARSE_ERR(("%s: diskd directive malformed.", context));
-      }
-    if (strncmp(params[1], "file=", 5) ||
-        strncmp(params[2], "cyl=", 4) ||
-        strncmp(params[3], "heads=", 6) ||
-        strncmp(params[4], "spt=", 4)) {
-      PARSE_ERR(("%s: diskd directive malformed.", context));
-      }
-    bx_options.ata[0].Opresent->set(1);
-    bx_options.atadevice[0][1].Otype->set (BX_ATA_DEVICE_DISK);
-    bx_options.atadevice[0][1].Opath->set (&params[1][5]);
-    bx_options.atadevice[0][1].Ocylinders->set (atol( &params[2][4]));
-    bx_options.atadevice[0][1].Oheads->set     (atol( &params[3][6]));
-    bx_options.atadevice[0][1].Ospt->set       (atol( &params[4][4]));
-    bx_options.atadevice[0][1].Opresent->set (1);
-    }
-  else if (!strcmp(params[0], "cdromd")) { // DEPRECATED
-    BX_INFO(("WARNING: cdromd directive is deprecated, use ata0-slave: instead"));
-    if (bx_options.atadevice[0][1].Opresent->get()) {
-      PARSE_ERR(("%s: slave device of ata channel 0 already defined.", context));
-      }
-    if (num_params != 3) {
-      PARSE_ERR(("%s: cdromd directive malformed.", context));
-      }
-    if (strncmp(params[1], "dev=", 4) || strncmp(params[2], "status=", 7)) {
-      PARSE_ERR(("%s: cdromd directive malformed.", context));
-      }
-    bx_options.ata[0].Opresent->set(1);
-    bx_options.atadevice[0][1].Otype->set (BX_ATA_DEVICE_CDROM);
-    bx_options.atadevice[0][1].Opath->set (&params[1][4]);
-    if (!strcmp(params[2], "status=inserted"))
-      bx_options.atadevice[0][1].Ostatus->set (BX_INSERTED);
-    else if (!strcmp(params[2], "status=ejected"))
-      bx_options.atadevice[0][1].Ostatus->set (BX_EJECTED);
-    else {
-      PARSE_ERR(("%s: cdromd directive malformed.", context));
-      }
-    bx_options.atadevice[0][1].Opresent->set (1);
-    }
-
-  else if (!strcmp(params[0], "boot")) {
-    if (!strcmp(params[1], "a")) {
-      bx_options.Obootdrive->set (BX_BOOT_FLOPPYA);
-    } else if (!strcmp(params[1], "floppy")) {
-      bx_options.Obootdrive->set (BX_BOOT_FLOPPYA);
-    } else if (!strcmp(params[1], "c")) {
-      bx_options.Obootdrive->set (BX_BOOT_DISKC);
-    } else if (!strcmp(params[1], "disk")) {
-      bx_options.Obootdrive->set (BX_BOOT_DISKC);
-    } else if (!strcmp(params[1], "cdrom")) {
-      bx_options.Obootdrive->set (BX_BOOT_CDROM);
-    } else {
-      PARSE_ERR(("%s: boot directive with unknown boot device '%s'.  use 'floppy', 'disk' or 'cdrom'.", context, params[1]));
-      }
-    }
-
-  else if (!strcmp(params[0], "com1")) {
-    for (i=1; i<num_params; i++) {
-      if (!strncmp(params[i], "enabled=", 8)) {
-        bx_options.com[0].Oenabled->set (atol(&params[i][8]));
-        }
-      else if (!strncmp(params[i], "dev=", 4)) {
-        bx_options.com[0].Odev->set (&params[i][4]);
-        bx_options.com[0].Oenabled->set (1);
-        }
-      else {
-        PARSE_ERR(("%s: unknown parameter for com1 ignored.", context));
-        }
-      }
-    }
-#if 0
-  else if (!strcmp(params[0], "com2")) {
-    for (i=1; i<num_params; i++) {
-      if (!strncmp(params[i], "enabled=", 8)) {
-        bx_options.com[1].Oenabled->set (atol(&params[i][8]));
-        }
-      else if (!strncmp(params[i], "dev=", 4)) {
-        bx_options.com[1].Odev->set (&params[i][4]);
-        bx_options.com[1].Oenabled->set (1);
-        }
-      else {
-        PARSE_ERR(("%s: unknown parameter for com2 ignored.", context));
-        }
-      }
-    }
-  else if (!strcmp(params[0], "com3")) {
-    for (i=1; i<num_params; i++) {
-      if (!strncmp(params[i], "enabled=", 8)) {
-        bx_options.com[2].Oenabled->set (atol(&params[i][8]));
-        }
-      else if (!strncmp(params[i], "dev=", 4)) {
-        bx_options.com[2].Odev->set (&params[i][4]);
-        bx_options.com[2].Oenabled->set (1);
-        }
-      else {
-        PARSE_ERR(("%s: unknown parameter for com3 ignored.", context));
-        }
-      }
-    }
-  else if (!strcmp(params[0], "com4")) {
-    for (i=1; i<num_params; i++) {
-      if (!strncmp(params[i], "enabled=", 8)) {
-        bx_options.com[3].Oenabled->set (atol(&params[i][8]));
-        }
-      else if (!strncmp(params[i], "dev=", 4)) {
-        bx_options.com[3].Odev->set (&params[i][4]);
-        bx_options.com[3].Oenabled->set (1);
-        }
-      else {
-        PARSE_ERR(("%s: unknown parameter for com4 ignored.", context));
-        }
-      }
-    }
-#endif
-  else if (!strcmp(params[0], "usb1")) {
-    for (i=1; i<num_params; i++) {
-      if (!strncmp(params[i], "enabled=", 8)) {
-        bx_options.usb[0].Oenabled->set (atol(&params[i][8]));
-        }
-      else if (!strncmp(params[i], "ioaddr=", 7)) {
-        if ( (params[i][7] == '0') && (params[i][8] == 'x') )
-          bx_options.usb[0].Oioaddr->set (strtoul (&params[i][7], NULL, 16));
-        else
-          bx_options.usb[0].Oioaddr->set (strtoul (&params[i][7], NULL, 10));
-        bx_options.usb[0].Oenabled->set (1);
-        }
-      else if (!strncmp(params[i], "irq=", 4)) {
-        bx_options.usb[0].Oirq->set (atol(&params[i][4]));
-        }
-      else {
-        PARSE_ERR(("%s: unknown parameter for usb1 ignored.", context));
-        }
-      }
-    }
-  else if (!strcmp(params[0], "floppy_bootsig_check")) {
-    if (num_params != 2) {
-      PARSE_ERR(("%s: floppy_bootsig_check directive malformed.", context));
-      }
-    if (strncmp(params[1], "disabled=", 9)) {
-      PARSE_ERR(("%s: floppy_bootsig_check directive malformed.", context));
-      }
-    if (params[1][9] == '0')
-      bx_options.OfloppySigCheck->set (0);
-    else if (params[1][9] == '1')
-      bx_options.OfloppySigCheck->set (1);
-    else {
-      PARSE_ERR(("%s: floppy_bootsig_check directive malformed.", context));
-      }
-    }
-  else if (!strcmp(params[0], "log")) {
-    if (num_params != 2) {
-      PARSE_ERR(("%s: log directive has wrong # args.", context));
-      }
-    bx_options.log.Ofilename->set (params[1]);
-    }
-  else if (!strcmp(params[0], "logprefix")) {
-    if (num_params != 2) {
-      PARSE_ERR(("%s: logprefix directive has wrong # args.", context));
-      }
-    bx_options.log.Oprefix->set (params[1]);
-    }
-  else if (!strcmp(params[0], "debugger_log")) {
-    if (num_params != 2) {
-      PARSE_ERR(("%s: debugger_log directive has wrong # args.", context));
-      }
-    bx_options.log.Odebugger_filename->set (params[1]);
-    }
-  else if (!strcmp(params[0], "panic")) {
-    if (num_params != 2) {
-      PARSE_ERR(("%s: panic directive malformed.", context));
-      }
-    if (strncmp(params[1], "action=", 7)) {
-      PARSE_ERR(("%s: panic directive malformed.", context));
-      }
-    char *action = 7 + params[1];
-    if (!strcmp(action, "fatal"))
-      SIM->set_default_log_action (LOGLEV_PANIC, ACT_FATAL);
-    else if (!strcmp (action, "report"))
-      SIM->set_default_log_action (LOGLEV_PANIC, ACT_REPORT);
-    else if (!strcmp (action, "ignore"))
-      SIM->set_default_log_action (LOGLEV_PANIC, ACT_IGNORE);
-    else if (!strcmp (action, "ask"))
-      SIM->set_default_log_action (LOGLEV_PANIC, ACT_ASK);
-    else {
-      PARSE_ERR(("%s: panic directive malformed.", context));
-      }
-    }
-  else if (!strcmp(params[0], "pass")) {
-    if (num_params != 2) {
-      PARSE_ERR(("%s: pass directive malformed.", context));
-      }
-    if (strncmp(params[1], "action=", 7)) {
-      PARSE_ERR(("%s: pass directive malformed.", context));
-      }
-    char *action = 7 + params[1];
-    if (!strcmp(action, "fatal"))
-      SIM->set_default_log_action (LOGLEV_PASS, ACT_FATAL);
-    else if (!strcmp (action, "report"))
-      SIM->set_default_log_action (LOGLEV_PASS, ACT_REPORT);
-    else if (!strcmp (action, "ignore"))
-      SIM->set_default_log_action (LOGLEV_PASS, ACT_IGNORE);
-    else if (!strcmp (action, "ask"))
-      SIM->set_default_log_action (LOGLEV_PASS, ACT_ASK);
-    else {
-      PARSE_ERR(("%s: pass directive malformed.", context));
-      }
-    }
-  else if (!strcmp(params[0], "error")) {
-    if (num_params != 2) {
-      PARSE_ERR(("%s: error directive malformed.", context));
-      }
-    if (strncmp(params[1], "action=", 7)) {
-      PARSE_ERR(("%s: error directive malformed.", context));
-      }
-    char *action = 7 + params[1];
-    if (!strcmp(action, "fatal"))
-      SIM->set_default_log_action (LOGLEV_ERROR, ACT_FATAL);
-    else if (!strcmp (action, "report"))
-      SIM->set_default_log_action (LOGLEV_ERROR, ACT_REPORT);
-    else if (!strcmp (action, "ignore"))
-      SIM->set_default_log_action (LOGLEV_ERROR, ACT_IGNORE);
-    else if (!strcmp (action, "ask"))
-      SIM->set_default_log_action (LOGLEV_ERROR, ACT_ASK);
-    else {
-      PARSE_ERR(("%s: error directive malformed.", context));
-      }
-    }
-  else if (!strcmp(params[0], "info")) {
-    if (num_params != 2) {
-      PARSE_ERR(("%s: info directive malformed.", context));
-      }
-    if (strncmp(params[1], "action=", 7)) {
-      PARSE_ERR(("%s: info directive malformed.", context));
-      }
-    char *action = 7 + params[1];
-    if (!strcmp(action, "fatal"))
-      SIM->set_default_log_action (LOGLEV_INFO, ACT_FATAL);
-    else if (!strcmp (action, "report"))
-      SIM->set_default_log_action (LOGLEV_INFO, ACT_REPORT);
-    else if (!strcmp (action, "ignore"))
-      SIM->set_default_log_action (LOGLEV_INFO, ACT_IGNORE);
-    else if (!strcmp (action, "ask"))
-      SIM->set_default_log_action (LOGLEV_INFO, ACT_ASK);
-    else {
-      PARSE_ERR(("%s: info directive malformed.", context));
-      }
-    }
-  else if (!strcmp(params[0], "debug")) {
-    if (num_params != 2) {
-      PARSE_ERR(("%s: debug directive malformed.", context));
-      }
-    if (strncmp(params[1], "action=", 7)) {
-      PARSE_ERR(("%s: debug directive malformed.", context));
-      }
-    char *action = 7 + params[1];
-    if (!strcmp(action, "fatal"))
-      SIM->set_default_log_action (LOGLEV_DEBUG, ACT_FATAL);
-    else if (!strcmp (action, "report"))
-      SIM->set_default_log_action (LOGLEV_DEBUG, ACT_REPORT);
-    else if (!strcmp (action, "ignore"))
-      SIM->set_default_log_action (LOGLEV_DEBUG, ACT_IGNORE);
-    else if (!strcmp (action, "ask"))
-      SIM->set_default_log_action (LOGLEV_DEBUG, ACT_ASK);
-    else {
-      PARSE_ERR(("%s: debug directive malformed.", context));
-      }
-    }
-  else if (!strcmp(params[0], "romimage")) {
-    if (num_params != 3) {
-      PARSE_ERR(("%s: romimage directive: wrong # args.", context));
-      }
-    if (strncmp(params[1], "file=", 5)) {
-      PARSE_ERR(("%s: romimage directive malformed.", context));
-      }
-    if (strncmp(params[2], "address=", 8)) {
-      PARSE_ERR(("%s: romimage directive malformed.", context));
-      }
-    bx_options.rom.Opath->set (&params[1][5]);
-    if ( (params[2][8] == '0') && (params[2][9] == 'x') )
-      bx_options.rom.Oaddress->set (strtoul (&params[2][8], NULL, 16));
-    else
-      bx_options.rom.Oaddress->set (strtoul (&params[2][8], NULL, 10));
-    }
-  else if (!strcmp(params[0], "optromimage1")) {
-    if (num_params != 3) {
-      PARSE_ERR(("%s: optromimage1 directive: wrong # args.", context));
-      }
-    if (strncmp(params[1], "file=", 5)) {
-      PARSE_ERR(("%s: optromimage1 directive malformed.", context));
-      }
-    if (strncmp(params[2], "address=", 8)) {
-      PARSE_ERR(("%s: optromimage2 directive malformed.", context));
-      }
-    bx_options.optrom[0].Opath->set (&params[1][5]);
-    if ( (params[2][8] == '0') && (params[2][9] == 'x') )
-      bx_options.optrom[0].Oaddress->set (strtoul (&params[2][8], NULL, 16));
-    else
-      bx_options.optrom[0].Oaddress->set (strtoul (&params[2][8], NULL, 10));
-    }
-  else if (!strcmp(params[0], "optromimage2")) {
-    if (num_params != 3) {
-      PARSE_ERR(("%s: optromimage2 directive: wrong # args.", context));
-      }
-    if (strncmp(params[1], "file=", 5)) {
-      PARSE_ERR(("%s: optromimage2 directive malformed.", context));
-      }
-    if (strncmp(params[2], "address=", 8)) {
-      PARSE_ERR(("%s: optromimage2 directive malformed.", context));
-      }
-    bx_options.optrom[1].Opath->set (&params[1][5]);
-    if ( (params[2][8] == '0') && (params[2][9] == 'x') )
-      bx_options.optrom[1].Oaddress->set (strtoul (&params[2][8], NULL, 16));
-    else
-      bx_options.optrom[1].Oaddress->set (strtoul (&params[2][8], NULL, 10));
-    }
-  else if (!strcmp(params[0], "optromimage3")) {
-    if (num_params != 3) {
-      PARSE_ERR(("%s: optromimage3 directive: wrong # args.", context));
-      }
-    if (strncmp(params[1], "file=", 5)) {
-      PARSE_ERR(("%s: optromimage3 directive malformed.", context));
-      }
-    if (strncmp(params[2], "address=", 8)) {
-      PARSE_ERR(("%s: optromimage2 directive malformed.", context));
-      }
-    bx_options.optrom[2].Opath->set (&params[1][5]);
-    if ( (params[2][8] == '0') && (params[2][9] == 'x') )
-      bx_options.optrom[2].Oaddress->set (strtoul (&params[2][8], NULL, 16));
-    else
-      bx_options.optrom[2].Oaddress->set (strtoul (&params[2][8], NULL, 10));
-    }
-  else if (!strcmp(params[0], "optromimage4")) {
-    if (num_params != 3) {
-      PARSE_ERR(("%s: optromimage4 directive: wrong # args.", context));
-      }
-    if (strncmp(params[1], "file=", 5)) {
-      PARSE_ERR(("%s: optromimage4 directive malformed.", context));
-      }
-    if (strncmp(params[2], "address=", 8)) {
-      PARSE_ERR(("%s: optromimage2 directive malformed.", context));
-      }
-    bx_options.optrom[3].Opath->set (&params[1][5]);
-    if ( (params[2][8] == '0') && (params[2][9] == 'x') )
-      bx_options.optrom[3].Oaddress->set (strtoul (&params[2][8], NULL, 16));
-    else
-      bx_options.optrom[3].Oaddress->set (strtoul (&params[2][8], NULL, 10));
-    }
-  else if (!strcmp(params[0], "vgaromimage")) {
-    if (num_params != 2) {
-      PARSE_ERR(("%s: vgaromimage directive: wrong # args.", context));
-      }
-    bx_options.vgarom.Opath->set (params[1]);
-    }
-  else if (!strcmp(params[0], "vga_update_interval")) {
-    if (num_params != 2) {
-      PARSE_ERR(("%s: vga_update_interval directive: wrong # args.", context));
-      }
-    bx_options.Ovga_update_interval->set (atol(params[1]));
-    if (bx_options.Ovga_update_interval->get () < 50000) {
-      BX_INFO(("%s: vga_update_interval seems awfully small!", context));
-      }
-    }
-  else if (!strcmp(params[0], "keyboard_serial_delay")) {
-    if (num_params != 2) {
-      PARSE_ERR(("%s: keyboard_serial_delay directive: wrong # args.", context));
-      }
-    bx_options.Okeyboard_serial_delay->set (atol(params[1]));
-    if (bx_options.Okeyboard_serial_delay->get () < 5) {
-      PARSE_ERR (("%s: keyboard_serial_delay not big enough!", context));
-      }
-    }
-  else if (!strcmp(params[0], "keyboard_paste_delay")) {
-    if (num_params != 2) {
-      PARSE_ERR(("%s: keyboard_paste_delay directive: wrong # args.", context));
-      }
-    bx_options.Okeyboard_paste_delay->set (atol(params[1]));
-    if (bx_options.Okeyboard_paste_delay->get () < 1000) {
-      PARSE_ERR (("%s: keyboard_paste_delay not big enough!", context));
-      }
-    }
-  else if (!strcmp(params[0], "megs")) {
-    if (num_params != 2) {
-      PARSE_ERR(("%s: megs directive: wrong # args.", context));
-      }
-    bx_options.memory.Osize->set (atol(params[1]));
-    }
-  else if (!strcmp(params[0], "floppy_command_delay")) {
-    if (num_params != 2) {
-      PARSE_ERR(("%s: floppy_command_delay directive: wrong # args.", context));
-      }
-    bx_options.Ofloppy_command_delay->set (atol(params[1]));
-    if (bx_options.Ofloppy_command_delay->get () < 100) {
-      PARSE_ERR(("%s: floppy_command_delay not big enough!", context));
-      }
-    }
-  else if (!strcmp(params[0], "ips")) {
-    if (num_params != 2) {
-      PARSE_ERR(("%s: ips directive: wrong # args.", context));
-      }
-    bx_options.Oips->set (atol(params[1]));
-    if (bx_options.Oips->get () < BX_MIN_IPS) {
-      BX_ERROR(("%s: WARNING: ips is AWFULLY low!", context));
-      }
-    }
-  else if (!strcmp(params[0], "pit")) { // Deprecated
-    if (num_params != 2) {
-      PARSE_ERR(("%s: pit directive: wrong # args.", context));
-      }
-    BX_INFO(("WARNING: pit directive is deprecated, use clock: instead"));
-    if (!strncmp(params[1], "realtime=", 9)) {
-      switch (params[1][9]) {
-        case '0': 
-          BX_INFO(("WARNING: not disabling realtime pit"));
-          break;
-        case '1': bx_options.clock.Osync->set (BX_CLOCK_SYNC_REALTIME); break;
-        default: PARSE_ERR(("%s: pit expected realtime=[0|1] arg", context));
-        }
-      }
-    else PARSE_ERR(("%s: pit expected realtime=[0|1] arg", context));
-    }
-  else if (!strcmp(params[0], "max_ips")) {
-    if (num_params != 2) {
-      PARSE_ERR(("%s: max_ips directive: wrong # args.", context));
-      }
-    BX_INFO(("WARNING: max_ips not implemented"));
-    }
-  else if (!strcmp(params[0], "text_snapshot_check")) {
-    if (num_params != 2) {
-      PARSE_ERR(("%s: text_snapshot_check directive: wrong # args.", context));
-      }
-    if (!strncmp(params[1], "enable", 6)) {
-      bx_options.Otext_snapshot_check->set (1);
-      }
-    else if (!strncmp(params[1], "disable", 7)) {
-      bx_options.Otext_snapshot_check->set (0);
-      }
-    else bx_options.Otext_snapshot_check->set (!!(atol(params[1])));
-    }
-  else if (!strcmp(params[0], "mouse")) {
-    if (num_params != 2) {
-      PARSE_ERR(("%s: mouse directive malformed.", context));
-      }
-    if (strncmp(params[1], "enabled=", 8)) {
-      PARSE_ERR(("%s: mouse directive malformed.", context));
-      }
-    if (params[1][8] == '0' || params[1][8] == '1')
-      bx_options.Omouse_enabled->set (params[1][8] - '0');
-    else
-      PARSE_ERR(("%s: mouse directive malformed.", context));
-    }
-  else if (!strcmp(params[0], "private_colormap")) {
-    if (num_params != 2) {
-      PARSE_ERR(("%s: private_colormap directive malformed.", context));
-      }
-    if (strncmp(params[1], "enabled=", 8)) {
-      PARSE_ERR(("%s: private_colormap directive malformed.", context));
-      }
-    if (params[1][8] == '0' || params[1][8] == '1')
-      bx_options.Oprivate_colormap->set (params[1][8] - '0');
-    else {
-      PARSE_ERR(("%s: private_colormap directive malformed.", context));
-      }
-    }
-  else if (!strcmp(params[0], "fullscreen")) {
-#if BX_WITH_AMIGAOS
-    if (num_params != 2) {
-      PARSE_ERR(("%s: fullscreen directive malformed.", context));
-      }
-    if (strncmp(params[1], "enabled=", 8)) {
-      PARSE_ERR(("%s: fullscreen directive malformed.", context));
-      }
-    if (params[1][8] == '0' || params[1][8] == '1') {
-      bx_options.Ofullscreen->set (params[1][8] - '0');
-    } else {
-      PARSE_ERR(("%s: fullscreen directive malformed.", context));
-      }
-#endif
-    }
-  else if (!strcmp(params[0], "screenmode")) {
-#if BX_WITH_AMIGAOS
-    if (num_params != 2) {
-      PARSE_ERR(("%s: screenmode directive malformed.", context));
-      }
-    if (strncmp(params[1], "name=", 5)) {
-      PARSE_ERR(("%s: screenmode directive malformed.", context));
-      }
-    bx_options.Oscreenmode->set (strdup(&params[1][5]));
-#endif
-    }
-
-  else if (!strcmp(params[0], "sb16")) {
-    for (i=1; i<num_params; i++) {
-      if (!strncmp(params[i], "midi=", 5)) {
-        bx_options.sb16.Omidifile->set (strdup(&params[i][5]));
-        }
-      else if (!strncmp(params[i], "midimode=", 9)) {
-        bx_options.sb16.Omidimode->set (atol(&params[i][9]));
-        }
-      else if (!strncmp(params[i], "wave=", 5)) {
-        bx_options.sb16.Owavefile->set (strdup(&params[i][5]));
-        }
-      else if (!strncmp(params[i], "wavemode=", 9)) {
-        bx_options.sb16.Owavemode->set (atol(&params[i][9]));
-        }
-      else if (!strncmp(params[i], "log=", 4)) {
-        bx_options.sb16.Ologfile->set (strdup(&params[i][4]));
-        }
-      else if (!strncmp(params[i], "loglevel=", 9)) {
-        bx_options.sb16.Ologlevel->set (atol(&params[i][9]));
-        }
-      else if (!strncmp(params[i], "dmatimer=", 9)) {
-        bx_options.sb16.Odmatimer->set (atol(&params[i][9]));
-        }
-      }
-    if (bx_options.sb16.Odmatimer->get () > 0)
-      bx_options.sb16.Opresent->set (1);
-    }
-
-  else if (!strcmp(params[0], "parport1")) {
-    for (i=1; i<num_params; i++) {
-      if (!strncmp(params[i], "enabled=", 8)) {
-        bx_options.par[0].Oenabled->set (atol(&params[i][8]));
-        }
-      else if (!strncmp(params[i], "file=", 5)) {
-        bx_options.par[0].Ooutfile->set (strdup(&params[i][5]));
-        bx_options.par[0].Oenabled->set (1);
-        }
-      else {
-        BX_ERROR(("%s: unknown parameter for parport1 ignored.", context));
-        }
-    }
-  }
-
-#if 0
-  else if (!strcmp(params[0], "parport2")) {
-    for (i=1; i<num_params; i++) {
-      if (!strncmp(params[i], "enabled=", 8)) {
-        bx_options.par[1].Oenabled->set (atol(&params[i][8]));
-        }
-      else if (!strncmp(params[i], "file=", 5)) {
-        bx_options.par[1].Ooutfile->set (strdup(&params[i][5]));
-        bx_options.par[1].Oenabled->set (1);
-        }
-      else {
-        BX_ERROR(("%s: unknown parameter for parport2 ignored.", context));
-        }
-    }
-  }
-#endif
-
-  else if (!strcmp(params[0], "i440fxsupport")) {
-    if (num_params != 2) {
-      PARSE_ERR(("%s: i440FXSupport directive malformed.", context));
-      }
-    if (strncmp(params[1], "enabled=", 8)) {
-      PARSE_ERR(("%s: i440FXSupport directive malformed.", context));
-      }
-    if (params[1][8] == '0')
-      bx_options.Oi440FXSupport->set (0);
-    else if (params[1][8] == '1')
-      bx_options.Oi440FXSupport->set (1);
-    else {
-      PARSE_ERR(("%s: i440FXSupport directive malformed.", context));
-      }
-    }
-  else if (!strcmp(params[0], "newharddrivesupport")) {
-    if (num_params != 2) {
-      PARSE_ERR(("%s: newharddrivesupport directive malformed.", context));
-      }
-    if (strncmp(params[1], "enabled=", 8)) {
-      PARSE_ERR(("%s: newharddrivesupport directive malformed.", context));
-      }
-    if (params[1][8] == '0')
-      bx_options.OnewHardDriveSupport->set (0);
-    else if (params[1][8] == '1')
-      bx_options.OnewHardDriveSupport->set (1);
-    else {
-      PARSE_ERR(("%s: newharddrivesupport directive malformed.", context));
-      }
-    }
-  else if (!strcmp(params[0], "cmosimage")) {
-    if (num_params != 2) {
-      PARSE_ERR(("%s: cmosimage directive: wrong # args.", context));
-      }
-    bx_options.cmos.Opath->set (strdup(params[1]));
-    bx_options.cmos.OcmosImage->set (1);                // CMOS Image is true
-    }
-  else if (!strcmp(params[0], "time0")) { // Deprectated
-    BX_INFO(("WARNING: time0 directive is deprecated, use clock: instead"));
-    if (num_params != 2) {
-      PARSE_ERR(("%s: time0 directive: wrong # args.", context));
-      }
-    bx_options.clock.Otime0->set (atoi(params[1]));
-    }
-  else if (!strcmp(params[0], "clock")) {
-    for (i=1; i<num_params; i++) {
-      if (!strncmp(params[i], "sync=", 5)) {
-        bx_options.clock.Osync->set_by_name (&params[i][5]);
-        }
-      else if (!strcmp(params[i], "time0=local")) {
-        bx_options.clock.Otime0->set (BX_CLOCK_TIME0_LOCAL);
-        }
-      else if (!strcmp(params[i], "time0=utc")) {
-        bx_options.clock.Otime0->set (BX_CLOCK_TIME0_UTC);
-        }
-      else if (!strncmp(params[i], "time0=", 6)) {
-        bx_options.clock.Otime0->set (atoi(&params[i][6]));
-        }
-      else {
-        BX_ERROR(("%s: unknown parameter for clock ignored.", context));
-        }
-      }
-    }
-#ifdef MAGIC_BREAKPOINT
-  else if (!strcmp(params[0], "magic_break")) {
-    if (num_params != 2) {
-      PARSE_ERR(("%s: magic_break directive: wrong # args.", context));
-      }
-    if (strncmp(params[1], "enabled=", 8)) {
-      PARSE_ERR(("%s: magic_break directive malformed.", context));
-      }
-    if (params[1][8] == '0') {
-      BX_INFO(("Ignoring magic break points"));
-      bx_dbg.magic_break_enabled = 0;
-      }
-    else if (params[1][8] == '1') {
-      BX_INFO(("Stopping on magic break points"));
-      bx_dbg.magic_break_enabled = 1;
-      }
-    else {
-      PARSE_ERR(("%s: magic_break directive malformed.", context));
-      }
-    }
-#endif
-  else if (!strcmp(params[0], "ne2k")) {
-    int tmp[6];
-    char tmpchar[6];
-    int valid = 0;
-    int n;
-    if (!bx_options.ne2k.Opresent->get ()) {
-      bx_options.ne2k.Oethmod->set_by_name ("null");
-      }
-    for (i=1; i<num_params; i++) {
-      if (!strncmp(params[i], "ioaddr=", 7)) {
-        bx_options.ne2k.Oioaddr->set (strtoul(&params[i][7], NULL, 16));
-        valid |= 0x01;
-        }
-      else if (!strncmp(params[i], "irq=", 4)) {
-        bx_options.ne2k.Oirq->set (atol(&params[i][4]));
-        valid |= 0x02;
-        }
-      else if (!strncmp(params[i], "mac=", 4)) {
-        n = sscanf(&params[i][4], "%x:%x:%x:%x:%x:%x",
-                   &tmp[0],&tmp[1],&tmp[2],&tmp[3],&tmp[4],&tmp[5]);
-        if (n != 6) {
-          PARSE_ERR(("%s: ne2k mac address malformed.", context));
-        }
-        for (n=0;n<6;n++)
-          tmpchar[n] = (unsigned char)tmp[n];
-        bx_options.ne2k.Omacaddr->set (tmpchar);
-        valid |= 0x04;
-        }
-      else if (!strncmp(params[i], "ethmod=", 7)) {
-        if (!bx_options.ne2k.Oethmod->set_by_name (strdup(&params[i][7])))
-          PARSE_ERR(("%s: ethernet module '%s' not available", context, strdup(&params[i][7])));
-        }
-      else if (!strncmp(params[i], "ethdev=", 7)) {
-        bx_options.ne2k.Oethdev->set (strdup(&params[i][7]));
-        }
-      else if (!strncmp(params[i], "script=", 7)) {
-        bx_options.ne2k.Oscript->set (strdup(&params[i][7]));
-        }
-      else {
-        PARSE_ERR(("%s: ne2k directive malformed.", context));
-        }
-    }
-    if (!bx_options.ne2k.Opresent->get ()) {
-      if (valid == 0x07) {
-        bx_options.ne2k.Opresent->set (1);
-        }
-      else {
-        PARSE_ERR(("%s: ne2k directive incomplete (ioaddr, irq and mac are required)", context));
-        }
-      }
-    }
-
-  else if (!strcmp(params[0], "load32bitOSImage")) {
-    if ( (num_params!=4) && (num_params!=5) ) {
-      PARSE_ERR(("%s: load32bitOSImage directive: wrong # args.", context));
-      }
-    if (strncmp(params[1], "os=", 3)) {
-      PARSE_ERR(("%s: load32bitOSImage: directive malformed.", context));
-      }
-    if (!strcmp(&params[1][3], "nullkernel")) {
-      bx_options.load32bitOSImage.OwhichOS->set (Load32bitOSNullKernel);
-      }
-    else if (!strcmp(&params[1][3], "linux")) {
-      bx_options.load32bitOSImage.OwhichOS->set (Load32bitOSLinux);
-      }
-    else {
-      PARSE_ERR(("%s: load32bitOSImage: unsupported OS.", context));
-      }
-    if (strncmp(params[2], "path=", 5)) {
-      PARSE_ERR(("%s: load32bitOSImage: directive malformed.", context));
-      }
-    if (strncmp(params[3], "iolog=", 6)) {
-      PARSE_ERR(("%s: load32bitOSImage: directive malformed.", context));
-      }
-    bx_options.load32bitOSImage.Opath->set (strdup(&params[2][5]));
-    bx_options.load32bitOSImage.Oiolog->set (strdup(&params[3][6]));
-    if (num_params == 5) {
-      if (strncmp(params[4], "initrd=", 7)) {
-        PARSE_ERR(("%s: load32bitOSImage: directive malformed.", context));
-        }
-      bx_options.load32bitOSImage.Oinitrd->set (strdup(&params[4][7]));
-      }
-    }
-  else if (!strcmp(params[0], "keyboard_type")) {
-    if (num_params != 2) {
-      PARSE_ERR(("%s: keyboard_type directive: wrong # args.", context));
-      }
-    if(strcmp(params[1],"xt")==0){
-      bx_options.Okeyboard_type->set (BX_KBD_XT_TYPE);
-      }
-    else if(strcmp(params[1],"at")==0){
-      bx_options.Okeyboard_type->set (BX_KBD_AT_TYPE);
-      }
-    else if(strcmp(params[1],"mf")==0){
-      bx_options.Okeyboard_type->set (BX_KBD_MF_TYPE);
-      }
-    else{
-      PARSE_ERR(("%s: keyboard_type directive: wrong arg %s.", context,params[1]));
-      }
-    }
-
-  else if (!strcmp(params[0], "keyboard_mapping")
-         ||!strcmp(params[0], "keyboardmapping")) {
-    for (i=1; i<num_params; i++) {
-      if (!strncmp(params[i], "enabled=", 8)) {
-        bx_options.keyboard.OuseMapping->set (atol(&params[i][8]));
-        }
-      else if (!strncmp(params[i], "map=", 4)) {
-        bx_options.keyboard.Okeymap->set (strdup(&params[i][4]));
-        }
-      }
-    }
-  else if (!strcmp(params[0], "user_shortcut")) {
-    if (num_params != 2) {
-      PARSE_ERR(("%s: user_shortcut directive: wrong # args.", context));
-      }
-    if(!strncmp(params[1], "keys=", 4)) {
-      bx_options.Ouser_shortcut->set (strdup(&params[1][5]));
-      }
-    }
-  else if (!strcmp(params[0], "config_interface")) {
-    if (num_params != 2) {
-      PARSE_ERR(("%s: config_interface directive: wrong # args.", context));
-      }
-    if (!bx_options.Osel_config->set_by_name (params[1]))
-      PARSE_ERR(("%s: config_interface '%s' not available", context, params[1]));
-    }
-  else if (!strcmp(params[0], "display_library")) {
-    if (num_params != 2) {
-      PARSE_ERR(("%s: display_library directive: wrong # args.", context));
-      }
-    if (!bx_options.Osel_displaylib->set_by_name (params[1]))
-      PARSE_ERR(("%s: display library '%s' not available", context, params[1]));
-    }
-  else {
-    PARSE_ERR(( "%s: directive '%s' not understood", context, params[0]));
-    }
-  return 0;
-}
-
-static char *fdtypes[] = {
-  "none", "1_2", "1_44", "2_88", "720k", "360k", "160k", "180k", "320k"
-};
-
-
-int 
-bx_write_floppy_options (FILE *fp, int drive, bx_floppy_options *opt)
-{
-  BX_ASSERT (drive==0 || drive==1);
-  if (opt->Otype->get () == BX_FLOPPY_NONE) {
-    fprintf (fp, "# no floppy%c\n", (char)'a'+drive);
-    return 0;
-  }
-  BX_ASSERT (opt->Otype->get () > BX_FLOPPY_NONE && opt->Otype->get () <= BX_FLOPPY_LAST);
-  fprintf (fp, "floppy%c: %s=\"%s\", status=%s\n", 
-    (char)'a'+drive, 
-    fdtypes[opt->Otype->get () - BX_FLOPPY_NONE],
-    opt->Opath->getptr (),
-    opt->Ostatus->get ()==BX_EJECTED ? "ejected" : "inserted");
-  return 0;
-}
-
-int 
-bx_write_ata_options (FILE *fp, Bit8u channel, bx_ata_options *opt)
-{
-  fprintf (fp, "ata%d: enabled=%d", channel, opt->Opresent->get());
-
-  if (opt->Opresent->get()) {
-    fprintf (fp, ", ioaddr1=0x%x, ioaddr2=0x%x, irq=%d", opt->Oioaddr1->get(), 
-      opt->Oioaddr2->get(), opt->Oirq->get());
-    }
-
-  fprintf (fp, "\n");
-  return 0;
-}
-
-int 
-bx_write_atadevice_options (FILE *fp, Bit8u channel, Bit8u drive, bx_atadevice_options *opt)
-{
-  if (opt->Opresent->get()) {
-    fprintf (fp, "ata%d-%s: ", channel, drive==0?"master":"slave");
-
-    if (opt->Otype->get() == BX_ATA_DEVICE_DISK) {
-      fprintf (fp, "type=disk");
-
-      switch(opt->Omode->get()) {
-        case BX_ATA_MODE_FLAT:
-          fprintf (fp, ", mode=flat");
-          break;
-        case BX_ATA_MODE_CONCAT:
-          fprintf (fp, ", mode=concat");
-          break;
-        case BX_ATA_MODE_EXTDISKSIM:
-          fprintf (fp, ", mode=external");
-          break;
-        case BX_ATA_MODE_DLL_HD:
-          fprintf (fp, ", mode=dll");
-          break;
-        case BX_ATA_MODE_SPARSE:
-          fprintf (fp, ", mode=sparse");
-          break;
-        case BX_ATA_MODE_VMWARE3:
-          fprintf (fp, ", mode=vmware3");
-          break;
-//        case BX_ATA_MODE_SPLIT:
-//          fprintf (fp, ", mode=split");
-//          break;
-        case BX_ATA_MODE_UNDOABLE:
-          fprintf (fp, ", mode=undoable");
-          break;
-        case BX_ATA_MODE_GROWING:
-          fprintf (fp, ", mode=growing");
-          break;
-        case BX_ATA_MODE_VOLATILE:
-          fprintf (fp, ", mode=volatile");
-          break;
-//        case BX_ATA_MODE_Z_UNDOABLE:
-//          fprintf (fp, ", mode=z-undoable");
-//          break;
-//        case BX_ATA_MODE_Z_VOLATILE:
-//          fprintf (fp, ", mode=z-volatile");
-//          break;
-        }
-
-      switch(opt->Otranslation->get()) {
-        case BX_ATA_TRANSLATION_NONE:
-          fprintf (fp, ", translation=none");
-          break;
-        case BX_ATA_TRANSLATION_LBA:
-          fprintf (fp, ", translation=lba");
-          break;
-        case BX_ATA_TRANSLATION_LARGE:
-          fprintf (fp, ", translation=large");
-          break;
-        case BX_ATA_TRANSLATION_RECHS:
-          fprintf (fp, ", translation=rechs");
-          break;
-        case BX_ATA_TRANSLATION_AUTO:
-          fprintf (fp, ", translation=auto");
-          break;
-        }
-
-      fprintf (fp, ", path=\"%s\", cylinders=%d, heads=%d, spt=%d",
-          opt->Opath->getptr(), 
-          opt->Ocylinders->get(), opt->Oheads->get(), opt->Ospt->get());
-
-      if (opt->Ojournal->getptr() != NULL)
-        if ( strcmp(opt->Ojournal->getptr(), "") != 0)
-          fprintf (fp, ", journal=\"%s\"", opt->Ojournal->getptr());
-
-      }
-    else if (opt->Otype->get() == BX_ATA_DEVICE_CDROM) {
-      fprintf (fp, "type=cdrom, path=\"%s\", status=%s", 
-        opt->Opath->getptr(), 
-        opt->Ostatus->get ()==BX_EJECTED ? "ejected" : "inserted");
-      }
-
-    switch(opt->Obiosdetect->get()) {
-      case BX_ATA_BIOSDETECT_NONE:
-        fprintf (fp, ", biosdetect=none");
-        break;
-      case BX_ATA_BIOSDETECT_CMOS:
-        fprintf (fp, ", biosdetect=cmos");
-        break;
-      case BX_ATA_BIOSDETECT_AUTO:
-        fprintf (fp, ", biosdetect=auto");
-        break;
-      }
-    if (strlen(opt->Omodel->getptr())>0) {
-        fprintf (fp, ", model=\"%s\"", opt->Omodel->getptr());
-      }
-
-    fprintf (fp, "\n");
-  }
-  return 0;
-}
-
-int
-bx_write_parport_options (FILE *fp, bx_parport_options *opt, int n)
-{
-  fprintf (fp, "parport%d: enabled=%d", n, opt->Oenabled->get ());
-  if (opt->Oenabled->get ()) {
-    fprintf (fp, ", file=\"%s\"", opt->Ooutfile->getptr ());
-  }
-  fprintf (fp, "\n");
-  return 0;
-}
-
-int
-bx_write_serial_options (FILE *fp, bx_serial_options *opt, int n)
-{
-  fprintf (fp, "com%d: enabled=%d", n, opt->Oenabled->get ());
-  if (opt->Oenabled->get ()) {
-    fprintf (fp, ", dev=\"%s\"", opt->Odev->getptr ());
-  }
-  fprintf (fp, "\n");
-  return 0;
-}
-
-int
-bx_write_usb_options (FILE *fp, bx_usb_options *opt, int n)
-{
-  fprintf (fp, "usb%d: enabled=%d", n, opt->Oenabled->get ());
-  if (opt->Oenabled->get ()) {
-    fprintf (fp, ", ioaddr=0x%04x, irq=%d", opt->Oioaddr->get (),
-      opt->Oirq->get ());
-  }
-  fprintf (fp, "\n");
-  return 0;
-}
-
-int
-bx_write_sb16_options (FILE *fp, bx_sb16_options *opt)
-{
-  if (!opt->Opresent->get ()) {
-    fprintf (fp, "# no sb16\n");
-    return 0;
-  }
-  fprintf (fp, "sb16: midimode=%d, midi=%s, wavemode=%d, wave=%s, loglevel=%d, log=%s, dmatimer=%d\n", opt->Omidimode->get (), opt->Omidifile->getptr (), opt->Owavemode->get (), opt->Owavefile->getptr (), opt->Ologlevel->get (), opt->Ologfile->getptr (), opt->Odmatimer->get ());
-  return 0;
-}
-
-int
-bx_write_ne2k_options (FILE *fp, bx_ne2k_options *opt)
-{
-  if (!opt->Opresent->get ()) {
-    fprintf (fp, "# no ne2k\n");
-    return 0;
-  }
-  char *ptr = opt->Omacaddr->getptr ();
-  fprintf (fp, "ne2k: ioaddr=0x%x, irq=%d, mac=%02x:%02x:%02x:%02x:%02x:%02x, ethmod=%s, ethdev=%s, script=%s\n",
-      opt->Oioaddr->get (), 
-      opt->Oirq->get (),
-      (unsigned int)(0xff & ptr[0]),
-      (unsigned int)(0xff & ptr[1]),
-      (unsigned int)(0xff & ptr[2]),
-      (unsigned int)(0xff & ptr[3]),
-      (unsigned int)(0xff & ptr[4]),
-      (unsigned int)(0xff & ptr[5]),
-      opt->Oethmod->get_choice(opt->Oethmod->get()),
-      opt->Oethdev->getptr (),
-      opt->Oscript->getptr ());
-  return 0;
-}
-
-int
-bx_write_loader_options (FILE *fp, bx_load32bitOSImage_t *opt)
-{
-  if (opt->OwhichOS->get () == 0) {
-    fprintf (fp, "# no loader\n");
-    return 0;
-  }
-  BX_ASSERT(opt->OwhichOS->get () == Load32bitOSLinux || opt->OwhichOS->get () == Load32bitOSNullKernel);
-  fprintf (fp, "load32bitOSImage: os=%s, path=%s, iolog=%s, initrd=%s\n",
-      (opt->OwhichOS->get () == Load32bitOSLinux) ? "linux" : "nullkernel",
-      opt->Opath->getptr (),
-      opt->Oiolog->getptr (),
-      opt->Oinitrd->getptr ());
-  return 0;
-}
-
-int
-bx_write_clock_options (FILE *fp, bx_clock_options *opt)
-{
-  fprintf (fp, "clock: ");
-
-  switch (opt->Osync->get()) {
-    case BX_CLOCK_SYNC_NONE:
-      fprintf (fp, "sync=none");
-      break;
-    case BX_CLOCK_SYNC_REALTIME:
-      fprintf (fp, "sync=realtime");
-      break;
-    case BX_CLOCK_SYNC_SLOWDOWN:
-      fprintf (fp, "sync=slowdown");
-      break;
-    case BX_CLOCK_SYNC_BOTH:
-      fprintf (fp, "sync=both");
-      break;
-    default:
-      BX_PANIC(("Unknown value for sync method"));
-  }
-
-  switch (opt->Otime0->get()) {
-    case 0: break;
-    case BX_CLOCK_TIME0_LOCAL: 
-      fprintf (fp, ", time0=local");
-      break;
-    case BX_CLOCK_TIME0_UTC: 
-      fprintf (fp, ", time0=utc");
-      break;
-    default: 
-      fprintf (fp, ", time0=%u", opt->Otime0->get());
-  }
-
-  fprintf (fp, "\n");
-  return 0;
-}
-
-int
-bx_write_log_options (FILE *fp, bx_log_options *opt)
-{
-  fprintf (fp, "log: %s\n", opt->Ofilename->getptr ());
-  fprintf (fp, "logprefix: %s\n", opt->Oprefix->getptr ());
-  fprintf (fp, "debugger_log: %s\n", opt->Odebugger_filename->getptr ());
-  fprintf (fp, "panic: action=%s\n",
-      io->getaction(logfunctions::get_default_action (LOGLEV_PANIC)));
-  fprintf (fp, "error: action=%s\n",
-      io->getaction(logfunctions::get_default_action (LOGLEV_ERROR)));
-  fprintf (fp, "info: action=%s\n",
-      io->getaction(logfunctions::get_default_action (LOGLEV_INFO)));
-  fprintf (fp, "debug: action=%s\n",
-      io->getaction(logfunctions::get_default_action (LOGLEV_DEBUG)));
-  fprintf (fp, "pass: action=%s\n",
-      io->getaction(logfunctions::get_default_action (LOGLEV_PASS)));
-  return 0;
-}
-
-int
-bx_write_keyboard_options (FILE *fp, bx_keyboard_options *opt)
-{
-  fprintf (fp, "keyboard_mapping: enabled=%d, map=%s\n", opt->OuseMapping->get(), opt->Okeymap->getptr());
-  return 0;
-}
-
-// return values:
-//   0: written ok
-//  -1: failed
-//  -2: already exists, and overwrite was off
-int
-bx_write_configuration (char *rc, int overwrite)
-{
-  BX_INFO (("write configuration to %s\n", rc));
-  // check if it exists.  If so, only proceed if overwrite is set.
-  FILE *fp = fopen (rc, "r");
-  if (fp != NULL) {
-    fclose (fp);
-    if (!overwrite) return -2;
-  }
-  fp = fopen (rc, "w");
-  if (fp == NULL) return -1;
-  // finally it's open and we can start writing.
-  fprintf (fp, "# configuration file generated by Bochs\n");
-  fprintf (fp, "config_interface: %s\n", bx_options.Osel_config->get_choice(bx_options.Osel_config->get()));
-  fprintf (fp, "display_library: %s\n", bx_options.Osel_displaylib->get_choice(bx_options.Osel_displaylib->get()));
-  fprintf (fp, "megs: %d\n", bx_options.memory.Osize->get ());
-  if (strlen (bx_options.rom.Opath->getptr ()) > 0)
-    fprintf (fp, "romimage: file=%s, address=0x%05x\n", bx_options.rom.Opath->getptr(), (unsigned int)bx_options.rom.Oaddress->get ());
-  else
-    fprintf (fp, "# no romimage\n");
-  if (strlen (bx_options.vgarom.Opath->getptr ()) > 0)
-    fprintf (fp, "vgaromimage: %s\n", bx_options.vgarom.Opath->getptr ());
-  else
-    fprintf (fp, "# no vgaromimage\n");
-  int bootdrive = bx_options.Obootdrive->get ();
-  fprintf (fp, "boot: %s\n", (bootdrive==BX_BOOT_FLOPPYA) ? "floppy" : (bootdrive==BX_BOOT_DISKC) ? "disk" : "cdrom");
-  // it would be nice to put this type of function as methods on
-  // the structs like bx_floppy_options::print or something.
-  bx_write_floppy_options (fp, 0, &bx_options.floppya);
-  bx_write_floppy_options (fp, 1, &bx_options.floppyb);
-  for (Bit8u channel=0; channel<BX_MAX_ATA_CHANNEL; channel++) {
-    bx_write_ata_options (fp, channel, &bx_options.ata[channel]);
-    bx_write_atadevice_options (fp, channel, 0, &bx_options.atadevice[channel][0]);
-    bx_write_atadevice_options (fp, channel, 1, &bx_options.atadevice[channel][1]);
-    }
-  if (strlen (bx_options.optrom[0].Opath->getptr ()) > 0)
-    fprintf (fp, "optromimage1: file=%s, address=0x%05x\n", bx_options.optrom[0].Opath->getptr(), (unsigned int)bx_options.optrom[0].Oaddress->get ());
-  if (strlen (bx_options.optrom[1].Opath->getptr ()) > 0)
-    fprintf (fp, "optromimage2: file=%s, address=0x%05x\n", bx_options.optrom[1].Opath->getptr(), (unsigned int)bx_options.optrom[1].Oaddress->get ());
-  if (strlen (bx_options.optrom[2].Opath->getptr ()) > 0)
-    fprintf (fp, "optromimage3: file=%s, address=0x%05x\n", bx_options.optrom[2].Opath->getptr(), (unsigned int)bx_options.optrom[2].Oaddress->get ());
-  if (strlen (bx_options.optrom[3].Opath->getptr ()) > 0)
-    fprintf (fp, "optromimage4: file=%s, address=0x%05x\n", bx_options.optrom[3].Opath->getptr(), (unsigned int)bx_options.optrom[3].Oaddress->get ());
-  bx_write_parport_options (fp, &bx_options.par[0], 1);
-  //bx_write_parport_options (fp, &bx_options.par[1], 2);
-  bx_write_serial_options (fp, &bx_options.com[0], 1);
-  //bx_write_serial_options (fp, &bx_options.com[1], 2);
-  //bx_write_serial_options (fp, &bx_options.com[2], 3);
-  //bx_write_serial_options (fp, &bx_options.com[3], 4);
-  bx_write_usb_options (fp, &bx_options.usb[0], 1);
-  bx_write_sb16_options (fp, &bx_options.sb16);
-  fprintf (fp, "floppy_bootsig_check: disabled=%d\n", bx_options.OfloppySigCheck->get ());
-  fprintf (fp, "vga_update_interval: %u\n", bx_options.Ovga_update_interval->get ());
-  fprintf (fp, "keyboard_serial_delay: %u\n", bx_options.Okeyboard_serial_delay->get ());
-  fprintf (fp, "keyboard_paste_delay: %u\n", bx_options.Okeyboard_paste_delay->get ());
-  fprintf (fp, "floppy_command_delay: %u\n", bx_options.Ofloppy_command_delay->get ());
-  fprintf (fp, "ips: %u\n", bx_options.Oips->get ());
-  fprintf (fp, "text_snapshot_check: %d\n", bx_options.Otext_snapshot_check->get ());
-  fprintf (fp, "mouse: enabled=%d\n", bx_options.Omouse_enabled->get ());
-  fprintf (fp, "private_colormap: enabled=%d\n", bx_options.Oprivate_colormap->get ());
-#if BX_WITH_AMIGAOS
-  fprintf (fp, "fullscreen: enabled=%d\n", bx_options.Ofullscreen->get ());
-  fprintf (fp, "screenmode: name=\"%s\"\n", bx_options.Oscreenmode->getptr ());
-#endif
-  fprintf (fp, "i440fxsupport: enabled=%d\n", bx_options.Oi440FXSupport->get ());
-  bx_write_clock_options (fp, &bx_options.clock);
-  bx_write_ne2k_options (fp, &bx_options.ne2k);
-  fprintf (fp, "newharddrivesupport: enabled=%d\n", bx_options.OnewHardDriveSupport->get ());
-  bx_write_loader_options (fp, &bx_options.load32bitOSImage);
-  bx_write_log_options (fp, &bx_options.log);
-  bx_write_keyboard_options (fp, &bx_options.keyboard);
-  fprintf (fp, "keyboard_type: %s\n", bx_options.Okeyboard_type->get ()==BX_KBD_XT_TYPE?"xt":
-                                       bx_options.Okeyboard_type->get ()==BX_KBD_AT_TYPE?"at":"mf");
-  fprintf (fp, "user_shortcut: keys=%s\n", bx_options.Ouser_shortcut->getptr ());
-  if (strlen (bx_options.cmos.Opath->getptr ()) > 0)
-    fprintf (fp, "cmosimage: %s\n", bx_options.cmos.Opath->getptr());
-  else
-    fprintf (fp, "# no cmosimage\n");
-  fclose (fp);
-  return 0;
-}
-#endif // #if BX_PROVIDE_MAIN
-
-  void
-bx_signal_handler( int signum)
-{
-  // in a multithreaded environment, a signal such as SIGINT can be sent to all
-  // threads.  This function is only intended to handle signals in the
-  // simulator thread.  It will simply return if called from any other thread.
-  // Otherwise the BX_PANIC() below can be called in multiple threads at
-  // once, leading to multiple threads trying to display a dialog box,
-  // leading to GUI deadlock.
-  if (!SIM->is_sim_thread ()) {
-    BX_INFO (("bx_signal_handler: ignored sig %d because it wasn't called from the simulator thread", signum));
-    return;
-  }
-#if BX_GUI_SIGHANDLER
-  if (bx_gui_sighandler) {
-    // GUI signal handler gets first priority, if the mask says it's wanted
-    if ((1<<signum) & bx_gui->get_sighandler_mask ()) {
-      bx_gui->sighandler (signum);
-      return;
-    }
-  }
-#endif
-
-#if BX_SHOW_IPS
-  extern unsigned long ips_count;
-
-  if (signum == SIGALRM ) {
-    BX_INFO(("ips = %lu", ips_count));
-    ips_count = 0;
-#ifndef __MINGW32__
-    signal(SIGALRM, bx_signal_handler);
-    alarm( 1 );
-#endif
-    return;
-    }
-#endif
-
-#if BX_GUI_SIGHANDLER
-  if (bx_gui_sighandler) {
-    if ((1<<signum) & bx_gui->get_sighandler_mask ()) {
-      bx_gui->sighandler (signum);
-      return;
-    }
-  }
-#endif
-  BX_PANIC(("SIGNAL %u caught", signum));
-}
-
diff --git a/tools/ioemu/iodev/ne2k.cc b/tools/ioemu/iodev/ne2k.cc
deleted file mode 100644 (file)
index d6e0ac4..0000000
+++ /dev/null
@@ -1,1608 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: ne2k.cc,v 1.56.2.1 2004/02/02 22:37:22 cbothamy Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-// Peter Grehan (grehan@iprg.nokia.com) coded all of this
-// NE2000/ether stuff.
-
-// Define BX_PLUGGABLE in files that can be compiled into plugins.  For
-// platforms that require a special tag on exported symbols, BX_PLUGGABLE 
-// is used to know when we are exporting symbols and when we are importing.
-#define BX_PLUGGABLE
-#include "bochs.h"
-#if BX_NE2K_SUPPORT
-
-//Never completely fill the ne2k ring so that we never
-// hit the unclear completely full buffer condition.
-#define BX_NE2K_NEVER_FULL_RING (1)
-
-#define LOG_THIS theNE2kDevice->
-
-bx_ne2k_c *theNE2kDevice = NULL;
-
-  int
-libne2k_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
-{
-  theNE2kDevice = new bx_ne2k_c ();
-  bx_devices.pluginNE2kDevice = theNE2kDevice;
-  BX_REGISTER_DEVICE_DEVMODEL(plugin, type, theNE2kDevice, BX_PLUGIN_NE2K);
-  return(0); // Success
-}
-
-  void
-libne2k_LTX_plugin_fini(void)
-{
-}
-  
-bx_ne2k_c::bx_ne2k_c(void)
-{
-  put("NE2K");
-  settype(NE2KLOG);
-  s.tx_timer_index = BX_NULL_TIMER_HANDLE;
-}
-
-
-bx_ne2k_c::~bx_ne2k_c(void)
-{
-  // nothing for now
-}
-
-//
-// reset - restore state to power-up, cancelling all i/o
-//
-void
-bx_ne2k_c::reset(unsigned type)
-{
-  BX_DEBUG (("reset"));
-  // Zero out registers and memory
-  memset( & BX_NE2K_THIS s.CR,  0, sizeof(BX_NE2K_THIS s.CR) );
-  memset( & BX_NE2K_THIS s.ISR, 0, sizeof(BX_NE2K_THIS s.ISR));
-  memset( & BX_NE2K_THIS s.IMR, 0, sizeof(BX_NE2K_THIS s.IMR));
-  memset( & BX_NE2K_THIS s.DCR, 0, sizeof(BX_NE2K_THIS s.DCR));
-  memset( & BX_NE2K_THIS s.TCR, 0, sizeof(BX_NE2K_THIS s.TCR));
-  memset( & BX_NE2K_THIS s.TSR, 0, sizeof(BX_NE2K_THIS s.TSR));
-  memset( & BX_NE2K_THIS s.RCR, 0, sizeof(BX_NE2K_THIS s.RCR));
-  memset( & BX_NE2K_THIS s.RSR, 0, sizeof(BX_NE2K_THIS s.RSR));
-  BX_NE2K_THIS s.local_dma  = 0;
-  BX_NE2K_THIS s.page_start = 0;
-  BX_NE2K_THIS s.page_stop  = 0;
-  BX_NE2K_THIS s.bound_ptr  = 0;
-  BX_NE2K_THIS s.tx_page_start = 0;
-  BX_NE2K_THIS s.num_coll   = 0;
-  BX_NE2K_THIS s.tx_bytes   = 0;
-  BX_NE2K_THIS s.fifo       = 0;
-  BX_NE2K_THIS s.remote_dma = 0;
-  BX_NE2K_THIS s.remote_start = 0;
-  BX_NE2K_THIS s.remote_bytes = 0;
-  BX_NE2K_THIS s.tallycnt_0 = 0;
-  BX_NE2K_THIS s.tallycnt_1 = 0;
-  BX_NE2K_THIS s.tallycnt_2 = 0;
-
-  memset( & BX_NE2K_THIS s.physaddr, 0, sizeof(BX_NE2K_THIS s.physaddr));
-  memset( & BX_NE2K_THIS s.mchash, 0, sizeof(BX_NE2K_THIS s.mchash));
-  BX_NE2K_THIS s.curr_page = 0;
-
-  BX_NE2K_THIS s.rempkt_ptr   = 0;
-  BX_NE2K_THIS s.localpkt_ptr = 0;
-  BX_NE2K_THIS s.address_cnt  = 0;
-
-  memset( & BX_NE2K_THIS s.mem, 0, sizeof(BX_NE2K_THIS s.mem));
-  
-  // Set power-up conditions
-  BX_NE2K_THIS s.CR.stop      = 1;
-    BX_NE2K_THIS s.CR.rdma_cmd  = 4;
-  BX_NE2K_THIS s.ISR.reset    = 1;
-  BX_NE2K_THIS s.DCR.longaddr = 1;
-  DEV_pic_lower_irq(BX_NE2K_THIS s.base_irq);
-}
-
-//
-// read_cr/write_cr - utility routines for handling reads/writes to
-// the Command Register
-//
-Bit32u
-bx_ne2k_c::read_cr(void)
-{
-  Bit32u val = 
-         (((BX_NE2K_THIS s.CR.pgsel    & 0x03) << 6) |
-         ((BX_NE2K_THIS s.CR.rdma_cmd & 0x07) << 3) |
-         (BX_NE2K_THIS s.CR.tx_packet << 2) |
-         (BX_NE2K_THIS s.CR.start     << 1) |
-         (BX_NE2K_THIS s.CR.stop));
-  BX_DEBUG(("read CR returns 0x%08x", val));
-  return val;
-}
-
-void
-bx_ne2k_c::write_cr(Bit32u value)
-{
-  BX_DEBUG(("wrote 0x%02x to CR", value));
-
-  // Validate remote-DMA
-  if ((value & 0x38) == 0x00) {
-    BX_DEBUG(("CR write - invalid rDMA value 0"));
-    value |= 0x20; /* dma_cmd == 4 is a safe default */
-  }
-
-  // Check for s/w reset
-  if (value & 0x01) {
-    BX_NE2K_THIS s.ISR.reset = 1;
-    BX_NE2K_THIS s.CR.stop   = 1;
-  } else {
-    BX_NE2K_THIS s.CR.stop = 0;
-  }
-
-  BX_NE2K_THIS s.CR.rdma_cmd = (value & 0x38) >> 3;
-
-  // If start command issued, the RST bit in the ISR
-  // must be cleared
-  if ((value & 0x02) && !BX_NE2K_THIS s.CR.start) {
-    BX_NE2K_THIS s.ISR.reset = 0;
-  }
-
-  BX_NE2K_THIS s.CR.start = ((value & 0x02) == 0x02);
-  BX_NE2K_THIS s.CR.pgsel = (value & 0xc0) >> 6;
-
-    // Check for send-packet command
-    if (BX_NE2K_THIS s.CR.rdma_cmd == 3) {
-       // Set up DMA read from receive ring
-       BX_NE2K_THIS s.remote_start = BX_NE2K_THIS s.remote_dma = BX_NE2K_THIS s.bound_ptr * 256;
-       BX_NE2K_THIS s.remote_bytes = *((Bit16u*) & BX_NE2K_THIS s.mem[BX_NE2K_THIS s.bound_ptr * 256 + 2 - BX_NE2K_MEMSTART]);
-       BX_INFO(("Sending buffer #x%x length %d",
-                 BX_NE2K_THIS s.remote_start,
-                 BX_NE2K_THIS s.remote_bytes));
-    }
-
-  // Check for start-tx
-    if ((value & 0x04) && BX_NE2K_THIS s.TCR.loop_cntl) {
-       if (BX_NE2K_THIS s.TCR.loop_cntl != 1) {
-           BX_INFO(("Loop mode %d not supported.", BX_NE2K_THIS s.TCR.loop_cntl));
-       } else {
-           rx_frame (& BX_NE2K_THIS s.mem[BX_NE2K_THIS s.tx_page_start*256 - BX_NE2K_MEMSTART],
-                     BX_NE2K_THIS s.tx_bytes);
-       }
-    } else if (value & 0x04) {
-    if (BX_NE2K_THIS s.CR.stop || !BX_NE2K_THIS s.CR.start)
-      BX_PANIC(("CR write - tx start, dev in reset"));
-    
-    if (BX_NE2K_THIS s.tx_bytes == 0)
-      BX_PANIC(("CR write - tx start, tx bytes == 0"));
-
-#ifdef notdef    
-    // XXX debug stuff
-    printf("packet tx (%d bytes):\t", BX_NE2K_THIS s.tx_bytes);
-    for (int i = 0; i < BX_NE2K_THIS s.tx_bytes; i++) {
-      printf("%02x ", BX_NE2K_THIS s.mem[BX_NE2K_THIS s.tx_page_start*256 - 
-                               BX_NE2K_MEMSTART + i]);
-      if (i && (((i+1) % 16) == 0)) 
-       printf("\t");
-    }
-    printf("");
-#endif    
-
-    // Send the packet to the system driver
-    BX_NE2K_THIS ethdev->sendpkt(& BX_NE2K_THIS s.mem[BX_NE2K_THIS s.tx_page_start*256 - BX_NE2K_MEMSTART], BX_NE2K_THIS s.tx_bytes);
-
-    // some more debug
-    if (BX_NE2K_THIS s.tx_timer_active)
-      BX_PANIC(("CR write, tx timer still active"));
-    
-    // Schedule a timer to trigger a tx-complete interrupt
-    // The number of microseconds is the bit-time / 10.
-    // The bit-time is the preamble+sfd (64 bits), the
-    // inter-frame gap (96 bits), the CRC (4 bytes), and the
-    // the number of bits in the frame (s.tx_bytes * 8).
-    //
-    bx_pc_system.activate_timer(BX_NE2K_THIS s.tx_timer_index,
-                               (64 + 96 + 4*8 + BX_NE2K_THIS s.tx_bytes*8)/10,
-                               0); // not continuous
-  }
-
-  // Linux probes for an interrupt by setting up a remote-DMA read
-  // of 0 bytes with remote-DMA completion interrupts enabled.
-  // Detect this here
-  if (BX_NE2K_THIS s.CR.rdma_cmd == 0x01 &&
-      BX_NE2K_THIS s.CR.start &&
-      BX_NE2K_THIS s.remote_bytes == 0) {
-    BX_NE2K_THIS s.ISR.rdma_done = 1;
-    if (BX_NE2K_THIS s.IMR.rdma_inte) {
-      DEV_pic_raise_irq(BX_NE2K_THIS s.base_irq);
-    }
-  }
-}
-
-//
-// chipmem_read/chipmem_write - access the 64K private RAM.
-// The ne2000 memory is accessed through the data port of
-// the asic (offset 0) after setting up a remote-DMA transfer.
-// Both byte and word accesses are allowed.
-// The first 16 bytes contains the MAC address at even locations,
-// and there is 16K of buffer memory starting at 16K
-//
-Bit32u BX_CPP_AttrRegparmN(2)
-bx_ne2k_c::chipmem_read(Bit32u address, unsigned int io_len)
-{
-  Bit32u retval = 0;
-
-  if ((io_len == 2) && (address & 0x1)) 
-    BX_PANIC(("unaligned chipmem word read"));
-
-  // ROM'd MAC address
-  if ((address >=0) && (address <= 31)) {
-    retval = BX_NE2K_THIS s.macaddr[address];
-    if (io_len == 2) {
-      retval |= (BX_NE2K_THIS s.macaddr[address + 1] << 8);
-    }
-    return (retval);
-  }
-
-  if ((address >= BX_NE2K_MEMSTART) && (address < BX_NE2K_MEMEND)) {
-    retval = BX_NE2K_THIS s.mem[address - BX_NE2K_MEMSTART];
-    if (io_len == 2) {
-      retval |= (BX_NE2K_THIS s.mem[address - BX_NE2K_MEMSTART + 1] << 8);
-    }
-    return (retval);
-  }
-
-  BX_DEBUG(("out-of-bounds chipmem read, %04X", address));
-
-  return (0xff);
-}
-
-void BX_CPP_AttrRegparmN(3)
-bx_ne2k_c::chipmem_write(Bit32u address, Bit32u value, unsigned io_len)
-{
-  if ((io_len == 2) && (address & 0x1)) 
-    BX_PANIC(("unaligned chipmem word write"));
-
-  if ((address >= BX_NE2K_MEMSTART) && (address < BX_NE2K_MEMEND)) {
-    BX_NE2K_THIS s.mem[address - BX_NE2K_MEMSTART] = value & 0xff;
-    if (io_len == 2)
-      BX_NE2K_THIS s.mem[address - BX_NE2K_MEMSTART + 1] = value >> 8;
-  } else
-    BX_DEBUG(("out-of-bounds chipmem write, %04X", address));
-}
-
-//
-// asic_read/asic_write - This is the high 16 bytes of i/o space
-// (the lower 16 bytes is for the DS8390). Only two locations
-// are used: offset 0, which is used for data transfer, and
-// offset 0xf, which is used to reset the device.
-// The data transfer port is used to as 'external' DMA to the
-// DS8390. The chip has to have the DMA registers set up, and
-// after that, insw/outsw instructions can be used to move
-// the appropriate number of bytes to/from the device.
-//
-Bit32u BX_CPP_AttrRegparmN(2)
-bx_ne2k_c::asic_read(Bit32u offset, unsigned int io_len)
-{
-  Bit32u retval = 0;
-
-  switch (offset) {
-  case 0x0:  // Data register
-    //
-    // A read remote-DMA command must have been issued,
-    // and the source-address and length registers must  
-    // have been initialised.
-    //
-    if (io_len > BX_NE2K_THIS s.remote_bytes)
-      {
-       BX_ERROR(("ne2K: dma read underrun iolen=%d remote_bytes=%d",io_len,BX_NE2K_THIS s.remote_bytes));
-       //return 0;
-      }
-
-    //BX_INFO(("ne2k read DMA: addr=%4x remote_bytes=%d",BX_NE2K_THIS s.remote_dma,BX_NE2K_THIS s.remote_bytes));
-    retval = chipmem_read(BX_NE2K_THIS s.remote_dma, io_len);
-    //
-    // The 8390 bumps the address and decreases the byte count
-    // by the selected word size after every access, not by
-    // the amount of data requested by the host (io_len).
-    //
-    BX_NE2K_THIS s.remote_dma += (BX_NE2K_THIS s.DCR.wdsize + 1);
-    if (BX_NE2K_THIS s.remote_dma == BX_NE2K_THIS s.page_stop << 8) {
-      BX_NE2K_THIS s.remote_dma = BX_NE2K_THIS s.page_start << 8;
-    }
-    // keep s.remote_bytes from underflowing
-    if (BX_NE2K_THIS s.remote_bytes > 1)
-      BX_NE2K_THIS s.remote_bytes -= (BX_NE2K_THIS s.DCR.wdsize + 1);
-    else
-      BX_NE2K_THIS s.remote_bytes = 0;
-
-       // If all bytes have been written, signal remote-DMA complete
-       if (BX_NE2K_THIS s.remote_bytes == 0) {
-           BX_NE2K_THIS s.ISR.rdma_done = 1;
-           if (BX_NE2K_THIS s.IMR.rdma_inte) {
-               DEV_pic_raise_irq(BX_NE2K_THIS s.base_irq);
-           }
-       }
-    break;
-
-  case 0xf:  // Reset register
-    theNE2kDevice->reset(BX_RESET_SOFTWARE);
-    break;
-
-  default:
-    BX_INFO(("asic read invalid address %04x", (unsigned) offset));
-    break;
-  }
-
-  return (retval);
-}
-
-void
-bx_ne2k_c::asic_write(Bit32u offset, Bit32u value, unsigned io_len)
-{
-  BX_DEBUG(("asic write addr=0x%02x, value=0x%04x", (unsigned) offset, (unsigned) value));
-  switch (offset) {
-  case 0x0:  // Data register - see asic_read for a description
-
-    if ((io_len == 2) && (BX_NE2K_THIS s.DCR.wdsize == 0)) {
-      BX_PANIC(("dma write length 2 on byte mode operation"));
-      break;
-    }
-
-    if (BX_NE2K_THIS s.remote_bytes == 0)
-      BX_PANIC(("ne2K: dma write, byte count 0"));
-
-    chipmem_write(BX_NE2K_THIS s.remote_dma, value, io_len);
-    // is this right ??? asic_read uses DCR.wordsize
-    BX_NE2K_THIS s.remote_dma   += io_len;
-    if (BX_NE2K_THIS s.remote_dma == BX_NE2K_THIS s.page_stop << 8) {
-      BX_NE2K_THIS s.remote_dma = BX_NE2K_THIS s.page_start << 8;
-    }
-
-    BX_NE2K_THIS s.remote_bytes -= io_len;
-    if (BX_NE2K_THIS s.remote_bytes > BX_NE2K_MEMSIZ)
-      BX_NE2K_THIS s.remote_bytes = 0;
-
-    // If all bytes have been written, signal remote-DMA complete
-    if (BX_NE2K_THIS s.remote_bytes == 0) {
-      BX_NE2K_THIS s.ISR.rdma_done = 1;
-      if (BX_NE2K_THIS s.IMR.rdma_inte) {
-         DEV_pic_raise_irq(BX_NE2K_THIS s.base_irq);
-      }
-    }
-    break;
-
-  case 0xf:  // Reset register
-    theNE2kDevice->reset(BX_RESET_SOFTWARE);
-    break;
-
-  default: // this is invalid, but happens under win95 device detection
-    BX_INFO(("asic write invalid address %04x, ignoring", (unsigned) offset));
-    break ;
-  }
-}
-
-//
-// page0_read/page0_write - These routines handle reads/writes to
-// the 'zeroth' page of the DS8390 register file
-//
-Bit32u
-bx_ne2k_c::page0_read(Bit32u offset, unsigned int io_len)
-{
-  BX_DEBUG(("page 0 read from port %04x, len=%u", (unsigned) offset,
-          (unsigned) io_len));
-  if (io_len > 1) {
-    BX_ERROR(("bad length! page 0 read from port %04x, len=%u", (unsigned) offset,
-             (unsigned) io_len)); /* encountered with win98 hardware probe */
-       return 0;
-  }
-
-
-  switch (offset) {
-  case 0x0:  // CR
-    return (read_cr());
-    break;
-    
-  case 0x1:  // CLDA0
-    return (BX_NE2K_THIS s.local_dma & 0xff);
-    break;
-
-  case 0x2:  // CLDA1
-    return (BX_NE2K_THIS s.local_dma >> 8);
-    break;
-
-  case 0x3:  // BNRY
-    return (BX_NE2K_THIS s.bound_ptr);
-    break;
-
-  case 0x4:  // TSR
-    return ((BX_NE2K_THIS s.TSR.ow_coll    << 7) |
-           (BX_NE2K_THIS s.TSR.cd_hbeat   << 6) |
-           (BX_NE2K_THIS s.TSR.fifo_ur    << 5) |
-           (BX_NE2K_THIS s.TSR.no_carrier << 4) |
-           (BX_NE2K_THIS s.TSR.aborted    << 3) |
-           (BX_NE2K_THIS s.TSR.collided   << 2) |
-           (BX_NE2K_THIS s.TSR.tx_ok));
-    break;
-
-  case 0x5:  // NCR
-    return (BX_NE2K_THIS s.num_coll);
-    break;
-    
-  case 0x6:  // FIFO
-    // reading FIFO is only valid in loopback mode
-    BX_ERROR(("reading FIFO not supported yet"));
-    return (BX_NE2K_THIS s.fifo);
-    break;
-
-  case 0x7:  // ISR
-    return ((BX_NE2K_THIS s.ISR.reset     << 7) |
-           (BX_NE2K_THIS s.ISR.rdma_done << 6) |
-           (BX_NE2K_THIS s.ISR.cnt_oflow << 5) |
-           (BX_NE2K_THIS s.ISR.overwrite << 4) |
-           (BX_NE2K_THIS s.ISR.tx_err    << 3) |
-           (BX_NE2K_THIS s.ISR.rx_err    << 2) |
-           (BX_NE2K_THIS s.ISR.pkt_tx    << 1) |
-           (BX_NE2K_THIS s.ISR.pkt_rx));
-    break;
-    
-  case 0x8:  // CRDA0
-    return (BX_NE2K_THIS s.remote_dma & 0xff);
-    break;
-
-  case 0x9:  // CRDA1
-    return (BX_NE2K_THIS s.remote_dma >> 8);
-    break;
-
-  case 0xa:  // reserved
-    BX_INFO(("reserved read - page 0, 0xa"));
-    return (0xff);
-    break;
-
-  case 0xb:  // reserved
-    BX_INFO(("reserved read - page 0, 0xb"));
-    return (0xff);
-    break;
-    
-  case 0xc:  // RSR
-    return ((BX_NE2K_THIS s.RSR.deferred    << 7) |
-           (BX_NE2K_THIS s.RSR.rx_disabled << 6) |
-           (BX_NE2K_THIS s.RSR.rx_mbit     << 5) |
-           (BX_NE2K_THIS s.RSR.rx_missed   << 4) |
-           (BX_NE2K_THIS s.RSR.fifo_or     << 3) |
-           (BX_NE2K_THIS s.RSR.bad_falign  << 2) |
-           (BX_NE2K_THIS s.RSR.bad_crc     << 1) |
-           (BX_NE2K_THIS s.RSR.rx_ok));
-    break;
-    
-  case 0xd:  // CNTR0
-    return (BX_NE2K_THIS s.tallycnt_0);
-    break;
-
-  case 0xe:  // CNTR1
-    return (BX_NE2K_THIS s.tallycnt_1);
-    break;
-
-  case 0xf:  // CNTR2
-    return (BX_NE2K_THIS s.tallycnt_2);
-    break;
-
-  default:
-    BX_PANIC(("page 0 offset %04x out of range", (unsigned) offset));
-  }
-
-  return(0);
-}
-
-void
-bx_ne2k_c::page0_write(Bit32u offset, Bit32u value, unsigned io_len)
-{
-  BX_DEBUG(("page 0 write to port %04x, len=%u", (unsigned) offset,
-          (unsigned) io_len));
-
-  // It appears to be a common practice to use outw on page0 regs...
-
-  // break up outw into two outb's
-  if (io_len == 2) {
-    page0_write(offset, (value & 0xff), 1);
-    page0_write(offset + 1, ((value >> 8) & 0xff), 1);
-    return;
-  }
-
-  switch (offset) {
-  case 0x0:  // CR
-    write_cr(value);
-    break;
-
-  case 0x1:  // PSTART
-    BX_NE2K_THIS s.page_start = value;
-    break;
-
-  case 0x2:  // PSTOP
-       // BX_INFO(("Writing to PSTOP: %02x", value));
-    BX_NE2K_THIS s.page_stop = value;
-    break;
-
-  case 0x3:  // BNRY
-    BX_NE2K_THIS s.bound_ptr = value;
-    break;
-
-  case 0x4:  // TPSR
-    BX_NE2K_THIS s.tx_page_start = value;
-    break;
-
-  case 0x5:  // TBCR0
-    // Clear out low byte and re-insert
-    BX_NE2K_THIS s.tx_bytes &= 0xff00;
-    BX_NE2K_THIS s.tx_bytes |= (value & 0xff);
-    break;
-
-  case 0x6:  // TBCR1
-    // Clear out high byte and re-insert
-    BX_NE2K_THIS s.tx_bytes &= 0x00ff;
-    BX_NE2K_THIS s.tx_bytes |= ((value & 0xff) << 8);
-    break;
-
-  case 0x7:  // ISR
-    value &= 0x7f;  // clear RST bit - status-only bit
-    // All other values are cleared iff the ISR bit is 1
-    BX_NE2K_THIS s.ISR.pkt_rx    &= ~((bx_bool)((value & 0x01) == 0x01));
-    BX_NE2K_THIS s.ISR.pkt_tx    &= ~((bx_bool)((value & 0x02) == 0x02));
-    BX_NE2K_THIS s.ISR.rx_err    &= ~((bx_bool)((value & 0x04) == 0x04));
-    BX_NE2K_THIS s.ISR.tx_err    &= ~((bx_bool)((value & 0x08) == 0x08));
-    BX_NE2K_THIS s.ISR.overwrite &= ~((bx_bool)((value & 0x10) == 0x10));
-    BX_NE2K_THIS s.ISR.cnt_oflow &= ~((bx_bool)((value & 0x20) == 0x20));
-    BX_NE2K_THIS s.ISR.rdma_done &= ~((bx_bool)((value & 0x40) == 0x40));
-    value = ((BX_NE2K_THIS s.ISR.rdma_done << 6) |
-             (BX_NE2K_THIS s.ISR.cnt_oflow << 5) |
-             (BX_NE2K_THIS s.ISR.overwrite << 4) |
-             (BX_NE2K_THIS s.ISR.tx_err    << 3) |
-             (BX_NE2K_THIS s.ISR.rx_err    << 2) |
-             (BX_NE2K_THIS s.ISR.pkt_tx    << 1) |
-             (BX_NE2K_THIS s.ISR.pkt_rx));
-    value &= ((BX_NE2K_THIS s.IMR.rdma_inte << 6) |
-              (BX_NE2K_THIS s.IMR.cofl_inte << 5) |
-              (BX_NE2K_THIS s.IMR.overw_inte << 4) |
-              (BX_NE2K_THIS s.IMR.txerr_inte << 3) |
-              (BX_NE2K_THIS s.IMR.rxerr_inte << 2) |
-              (BX_NE2K_THIS s.IMR.tx_inte << 1) |
-              (BX_NE2K_THIS s.IMR.rx_inte));
-    if (value == 0)
-      DEV_pic_lower_irq(BX_NE2K_THIS s.base_irq);
-    break;
-
-  case 0x8:  // RSAR0
-    // Clear out low byte and re-insert
-    BX_NE2K_THIS s.remote_start &= 0xff00;
-    BX_NE2K_THIS s.remote_start |= (value & 0xff);
-    BX_NE2K_THIS s.remote_dma = BX_NE2K_THIS s.remote_start;
-    break;
-
-  case 0x9:  // RSAR1
-    // Clear out high byte and re-insert
-    BX_NE2K_THIS s.remote_start &= 0x00ff;
-    BX_NE2K_THIS s.remote_start |= ((value & 0xff) << 8);
-    BX_NE2K_THIS s.remote_dma = BX_NE2K_THIS s.remote_start;
-    break;
-
-  case 0xa:  // RBCR0
-    // Clear out low byte and re-insert
-    BX_NE2K_THIS s.remote_bytes &= 0xff00;
-    BX_NE2K_THIS s.remote_bytes |= (value & 0xff);
-    break;
-
-  case 0xb:  // RBCR1
-    // Clear out high byte and re-insert
-    BX_NE2K_THIS s.remote_bytes &= 0x00ff;
-    BX_NE2K_THIS s.remote_bytes |= ((value & 0xff) << 8);
-    break;
-
-  case 0xc:  // RCR
-    // Check if the reserved bits are set
-    if (value & 0xc0)
-      BX_INFO(("RCR write, reserved bits set"));
-
-    // Set all other bit-fields
-    BX_NE2K_THIS s.RCR.errors_ok = ((value & 0x01) == 0x01);
-    BX_NE2K_THIS s.RCR.runts_ok  = ((value & 0x02) == 0x02);
-    BX_NE2K_THIS s.RCR.broadcast = ((value & 0x04) == 0x04);
-    BX_NE2K_THIS s.RCR.multicast = ((value & 0x08) == 0x08);
-    BX_NE2K_THIS s.RCR.promisc   = ((value & 0x10) == 0x10);
-    BX_NE2K_THIS s.RCR.monitor   = ((value & 0x20) == 0x20);
-
-    // Monitor bit is a little suspicious...
-    if (value & 0x20)
-      BX_INFO(("RCR write, monitor bit set!"));
-    break;
-
-  case 0xd:  // TCR
-    // Check reserved bits
-    if (value & 0xe0)
-      BX_ERROR(("TCR write, reserved bits set"));
-
-    // Test loop mode (not supported)
-    if (value & 0x06) {
-      BX_NE2K_THIS s.TCR.loop_cntl = (value & 0x6) >> 1;
-      BX_INFO(("TCR write, loop mode %d not supported", BX_NE2K_THIS s.TCR.loop_cntl));
-    } else {
-      BX_NE2K_THIS s.TCR.loop_cntl = 0;
-    }
-
-    // Inhibit-CRC not supported.
-    if (value & 0x01)
-      BX_PANIC(("TCR write, inhibit-CRC not supported"));
-
-    // Auto-transmit disable very suspicious
-    if (value & 0x08)
-      BX_PANIC(("TCR write, auto transmit disable not supported"));
-
-    // Allow collision-offset to be set, although not used
-    BX_NE2K_THIS s.TCR.coll_prio = ((value & 0x08) == 0x08);
-    break;
-
-  case 0xe:  // DCR
-    // the loopback mode is not suppported yet
-    if (!(value & 0x08)) {
-      BX_ERROR(("DCR write, loopback mode selected"));
-    }
-    // It is questionable to set longaddr and auto_rx, since they
-    // aren't supported on the ne2000. Print a warning and continue
-    if (value & 0x04)
-      BX_INFO(("DCR write - LAS set ???"));
-    if (value & 0x10)
-      BX_INFO(("DCR write - AR set ???"));
-
-    // Set other values.
-    BX_NE2K_THIS s.DCR.wdsize   = ((value & 0x01) == 0x01);
-    BX_NE2K_THIS s.DCR.endian   = ((value & 0x02) == 0x02);
-    BX_NE2K_THIS s.DCR.longaddr = ((value & 0x04) == 0x04); // illegal ?
-    BX_NE2K_THIS s.DCR.loop     = ((value & 0x08) == 0x08);
-    BX_NE2K_THIS s.DCR.auto_rx  = ((value & 0x10) == 0x10); // also illegal ?
-    BX_NE2K_THIS s.DCR.fifo_size = (value & 0x50) >> 5;
-    break;
-
-  case 0xf:  // IMR
-    // Check for reserved bit
-    if (value & 0x80)
-      BX_PANIC(("IMR write, reserved bit set"));
-
-    // Set other values
-    BX_NE2K_THIS s.IMR.rx_inte    = ((value & 0x01) == 0x01);
-    BX_NE2K_THIS s.IMR.tx_inte    = ((value & 0x02) == 0x02);
-    BX_NE2K_THIS s.IMR.rxerr_inte = ((value & 0x04) == 0x04);
-    BX_NE2K_THIS s.IMR.txerr_inte = ((value & 0x08) == 0x08);
-    BX_NE2K_THIS s.IMR.overw_inte = ((value & 0x10) == 0x10);
-    BX_NE2K_THIS s.IMR.cofl_inte  = ((value & 0x20) == 0x20);
-    BX_NE2K_THIS s.IMR.rdma_inte  = ((value & 0x40) == 0x40);
-    break;
-
-  default:
-    BX_PANIC(("page 0 write, bad offset %0x", offset));
-  }
-}
-
-
-//
-// page1_read/page1_write - These routines handle reads/writes to
-// the first page of the DS8390 register file
-//
-Bit32u
-bx_ne2k_c::page1_read(Bit32u offset, unsigned int io_len)
-{
-  BX_DEBUG(("page 1 read from port %04x, len=%u", (unsigned) offset,
-          (unsigned) io_len));
-  if (io_len > 1)
-    BX_PANIC(("bad length! page 1 read from port %04x, len=%u", (unsigned) offset,
-             (unsigned) io_len));
-
-  switch (offset) {
-  case 0x0:  // CR
-    return (read_cr());
-    break;
-    
-  case 0x1:  // PAR0-5
-  case 0x2:
-  case 0x3:
-  case 0x4:
-  case 0x5:
-  case 0x6:
-    return (BX_NE2K_THIS s.physaddr[offset - 1]);
-    break;
-
-  case 0x7:  // CURR
-      BX_DEBUG(("returning current page: %02x", (BX_NE2K_THIS s.curr_page)));
-    return (BX_NE2K_THIS s.curr_page);
-
-  case 0x8:  // MAR0-7
-  case 0x9:
-  case 0xa:
-  case 0xb:
-  case 0xc:
-  case 0xd:
-  case 0xe:
-  case 0xf:
-    return (BX_NE2K_THIS s.mchash[offset - 8]);
-    break;
-
-  default:
-    BX_PANIC(("page 1 r offset %04x out of range", (unsigned) offset));
-  }
-
-  return (0);
-}
-
-void
-bx_ne2k_c::page1_write(Bit32u offset, Bit32u value, unsigned io_len)
-{
-  BX_DEBUG(("page 1 w offset %04x", (unsigned) offset));
-  switch (offset) {
-  case 0x0:  // CR
-    write_cr(value);
-    break;  
-
-  case 0x1:  // PAR0-5
-  case 0x2:
-  case 0x3:
-  case 0x4:
-  case 0x5:
-  case 0x6:
-    BX_NE2K_THIS s.physaddr[offset - 1] = value;
-    break;
-    
-  case 0x7:  // CURR
-    BX_NE2K_THIS s.curr_page = value;
-    break;
-
-  case 0x8:  // MAR0-7
-  case 0x9:
-  case 0xa:
-  case 0xb:
-  case 0xc:
-  case 0xd:
-  case 0xe:
-  case 0xf:
-    BX_NE2K_THIS s.mchash[offset - 8] = value;
-    break;
-
-  default:
-    BX_PANIC(("page 1 w offset %04x out of range", (unsigned) offset));
-  }  
-}
-
-
-//
-// page2_read/page2_write - These routines handle reads/writes to
-// the second page of the DS8390 register file
-//
-Bit32u
-bx_ne2k_c::page2_read(Bit32u offset, unsigned int io_len)
-{
-  BX_DEBUG(("page 2 read from port %04x, len=%u", (unsigned) offset, (unsigned) io_len));
-
-  if (io_len > 1)
-    BX_PANIC(("bad length!  page 2 read from port %04x, len=%u", (unsigned) offset, (unsigned) io_len));
-
-  switch (offset) {
-  case 0x0:  // CR
-    return (read_cr());
-    break;
-
-  case 0x1:  // PSTART
-    return (BX_NE2K_THIS s.page_start);
-    break;
-
-  case 0x2:  // PSTOP
-    return (BX_NE2K_THIS s.page_stop);
-    break;
-
-  case 0x3:  // Remote Next-packet pointer
-    return (BX_NE2K_THIS s.rempkt_ptr);
-    break;
-
-  case 0x4:  // TPSR
-    return (BX_NE2K_THIS s.tx_page_start);
-    break;
-
-  case 0x5:  // Local Next-packet pointer
-    return (BX_NE2K_THIS s.localpkt_ptr);
-    break;
-
-  case 0x6:  // Address counter (upper)
-    return (BX_NE2K_THIS s.address_cnt >> 8);
-    break;
-
-  case 0x7:  // Address counter (lower)
-    return (BX_NE2K_THIS s.address_cnt & 0xff);
-    break;
-
-  case 0x8:  // Reserved
-  case 0x9:
-  case 0xa:
-  case 0xb:
-    BX_ERROR(("reserved read - page 2, 0x%02x", (unsigned) offset));
-    return (0xff);
-    break;
-
-  case 0xc:  // RCR
-    return ((BX_NE2K_THIS s.RCR.monitor   << 5) |
-           (BX_NE2K_THIS s.RCR.promisc   << 4) |
-           (BX_NE2K_THIS s.RCR.multicast << 3) |
-           (BX_NE2K_THIS s.RCR.broadcast << 2) |
-           (BX_NE2K_THIS s.RCR.runts_ok  << 1) |
-           (BX_NE2K_THIS s.RCR.errors_ok));
-    break;
-
-  case 0xd:  // TCR
-    return ((BX_NE2K_THIS s.TCR.coll_prio   << 4) |
-           (BX_NE2K_THIS s.TCR.ext_stoptx  << 3) |
-           ((BX_NE2K_THIS s.TCR.loop_cntl & 0x3) << 1) |
-           (BX_NE2K_THIS s.TCR.crc_disable));
-    break;
-
-  case 0xe:  // DCR
-    return (((BX_NE2K_THIS s.DCR.fifo_size & 0x3) << 5) |
-           (BX_NE2K_THIS s.DCR.auto_rx  << 4) |
-           (BX_NE2K_THIS s.DCR.loop     << 3) |
-           (BX_NE2K_THIS s.DCR.longaddr << 2) |
-           (BX_NE2K_THIS s.DCR.endian   << 1) |
-           (BX_NE2K_THIS s.DCR.wdsize));
-    break;
-
-  case 0xf:  // IMR
-    return ((BX_NE2K_THIS s.IMR.rdma_inte  << 6) |
-           (BX_NE2K_THIS s.IMR.cofl_inte  << 5) |
-           (BX_NE2K_THIS s.IMR.overw_inte << 4) |
-           (BX_NE2K_THIS s.IMR.txerr_inte << 3) |
-           (BX_NE2K_THIS s.IMR.rxerr_inte << 2) |
-           (BX_NE2K_THIS s.IMR.tx_inte    << 1) |
-           (BX_NE2K_THIS s.IMR.rx_inte));
-    break;
-
-  default:
-    BX_PANIC(("page 2 offset %04x out of range", (unsigned) offset));
-  }
-
-  return (0);
-};
-
-void
-bx_ne2k_c::page2_write(Bit32u offset, Bit32u value, unsigned io_len)
-{
-  // Maybe all writes here should be BX_PANIC()'d, since they
-  // affect internal operation, but let them through for now
-  // and print a warning.
-  if (offset != 0)
-    BX_ERROR(("page 2 write ?"));
-
-  switch (offset) {
-  case 0x0:  // CR
-    write_cr(value);
-    break; 
-
-  case 0x1:  // CLDA0
-    // Clear out low byte and re-insert
-    BX_NE2K_THIS s.local_dma &= 0xff00;
-    BX_NE2K_THIS s.local_dma |= (value & 0xff);
-    break;
-
-  case 0x2:  // CLDA1
-    // Clear out high byte and re-insert
-    BX_NE2K_THIS s.local_dma &= 0x00ff;
-    BX_NE2K_THIS s.local_dma |= ((value & 0xff) << 8);
-    break;
-
-  case 0x3:  // Remote Next-pkt pointer
-    BX_NE2K_THIS s.rempkt_ptr = value;
-    break;
-
-  case 0x4:
-    BX_PANIC(("page 2 write to reserved offset 4"));
-    break;
-
-  case 0x5:  // Local Next-packet pointer
-    BX_NE2K_THIS s.localpkt_ptr = value;
-    break;
-
-  case 0x6:  // Address counter (upper)
-    // Clear out high byte and re-insert
-    BX_NE2K_THIS s.address_cnt &= 0x00ff;
-    BX_NE2K_THIS s.address_cnt |= ((value & 0xff) << 8);
-    break;
-
-  case 0x7:  // Address counter (lower)
-    // Clear out low byte and re-insert
-    BX_NE2K_THIS s.address_cnt &= 0xff00;
-    BX_NE2K_THIS s.address_cnt |= (value & 0xff);
-    break;
-
-  case 0x8:
-  case 0x9:
-  case 0xa:
-  case 0xb:
-  case 0xc:
-  case 0xd:
-  case 0xe:
-  case 0xf:
-    BX_PANIC(("page 2 write to reserved offset %0x", offset));
-    break;
-   
-  default:
-    BX_PANIC(("page 2 write, illegal offset %0x", offset));
-    break;
-  }
-}
-  
-//
-// page3_read/page3_write - writes to this page are illegal
-//
-Bit32u
-bx_ne2k_c::page3_read(Bit32u offset, unsigned int io_len)
-{
-  BX_PANIC(("page 3 read attempted"));
-  return (0);
-}
-
-void
-bx_ne2k_c::page3_write(Bit32u offset, Bit32u value, unsigned io_len)
-{
-  BX_PANIC(("page 3 write attempted"));
-}
-
-//
-// tx_timer_handler/tx_timer
-//
-void
-bx_ne2k_c::tx_timer_handler(void *this_ptr)
-{
-  bx_ne2k_c *class_ptr = (bx_ne2k_c *) this_ptr;
-
-  class_ptr->tx_timer();
-}
-
-void
-bx_ne2k_c::tx_timer(void)
-{
-  BX_DEBUG(("tx_timer"));
-  BX_NE2K_THIS s.TSR.tx_ok = 1;
-  // Generate an interrupt if not masked and not one in progress
-  if (BX_NE2K_THIS s.IMR.tx_inte && !BX_NE2K_THIS s.ISR.pkt_tx) {
-    BX_NE2K_THIS s.ISR.pkt_tx = 1;
-    DEV_pic_raise_irq(BX_NE2K_THIS s.base_irq);
-  }
-  BX_NE2K_THIS s.tx_timer_active = 0;
-}
-
-
-//
-// read_handler/read - i/o 'catcher' function called from BOCHS
-// mainline when the CPU attempts a read in the i/o space registered
-// by this ne2000 instance
-//
-Bit32u
-bx_ne2k_c::read_handler(void *this_ptr, Bit32u address, unsigned io_len)
-{
-#if !BX_USE_NE2K_SMF
-  bx_ne2k_c *class_ptr = (bx_ne2k_c *) this_ptr;
-
-  return( class_ptr->read(address, io_len) );
-}
-
-Bit32u
-bx_ne2k_c::read(Bit32u address, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif  // !BX_USE_NE2K_SMF
-  BX_DEBUG(("read addr %x, len %d", address, io_len));
-  Bit32u retval = 0;
-  int offset = address - BX_NE2K_THIS s.base_address;
-
-  if (offset >= 0x10) {
-    retval = asic_read(offset - 0x10, io_len);
-  } else {
-    switch (BX_NE2K_THIS s.CR.pgsel) {
-    case 0x00:
-      retval = page0_read(offset, io_len);
-      break;
-
-    case 0x01:
-      retval = page1_read(offset, io_len);
-      break;
-
-    case 0x02:
-      retval = page2_read(offset, io_len);
-      break;
-
-    case 0x03:
-      retval = page3_read(offset, io_len);
-      break;
-
-    default:
-      BX_PANIC(("ne2K: unknown value of pgsel in read - %d",
-              BX_NE2K_THIS s.CR.pgsel));
-    }
-  }
-
-  return (retval);
-}
-
-//
-// write_handler/write - i/o 'catcher' function called from BOCHS
-// mainline when the CPU attempts a write in the i/o space registered
-// by this ne2000 instance
-//
-void
-bx_ne2k_c::write_handler(void *this_ptr, Bit32u address, Bit32u value, 
-                        unsigned io_len)
-{
-#if !BX_USE_NE2K_SMF
-  bx_ne2k_c *class_ptr = (bx_ne2k_c *) this_ptr;
-  
-  class_ptr->write(address, value, io_len);
-}
-
-void
-bx_ne2k_c::write(Bit32u address, Bit32u value, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif  // !BX_USE_NE2K_SMF
-  BX_DEBUG(("write with length %d", io_len));
-  int offset = address - BX_NE2K_THIS s.base_address;
-
-  //
-  // The high 16 bytes of i/o space are for the ne2000 asic -
-  //  the low 16 bytes are for the DS8390, with the current
-  //  page being selected by the PS0,PS1 registers in the
-  //  command register
-  //
-  if (offset >= 0x10) {
-    asic_write(offset - 0x10, value, io_len);
-  } else {
-    switch (BX_NE2K_THIS s.CR.pgsel) {
-    case 0x00:
-      page0_write(offset, value, io_len);
-      break;
-
-    case 0x01:
-      page1_write(offset, value, io_len);
-      break;
-
-    case 0x02:
-      page2_write(offset, value, io_len);
-      break;
-
-    case 0x03:
-      page3_write(offset, value, io_len);
-      break;
-
-    default:
-      BX_PANIC(("ne2K: unknown value of pgsel in write - %d",
-              BX_NE2K_THIS s.CR.pgsel));
-    }
-  }
-}
-
-
-/*
- * mcast_index() - return the 6-bit index into the multicast
- * table. Stolen unashamedly from FreeBSD's if_ed.c
- */
-unsigned
-bx_ne2k_c::mcast_index(const void *dst)
-{
-#define POLYNOMIAL 0x04c11db6
-  unsigned long crc = 0xffffffffL;
-  int carry, i, j;
-  unsigned char b;
-  unsigned char *ep = (unsigned char *) dst;
-
-  for (i = 6; --i >= 0;) {
-    b = *ep++;
-    for (j = 8; --j >= 0;) {
-      carry = ((crc & 0x80000000L) ? 1 : 0) ^ (b & 0x01);
-      crc <<= 1;
-      b >>= 1;
-      if (carry)
-       crc = ((crc ^ POLYNOMIAL) | carry);
-    }
-  }
-  return (crc >> 26);
-#undef POLYNOMIAL
-}
-
-/*
- * Callback from the eth system driver when a frame has arrived
- */
-void
-bx_ne2k_c::rx_handler(void *arg, const void *buf, unsigned len)
-{
-    // BX_DEBUG(("rx_handler with length %d", len));
-  bx_ne2k_c *class_ptr = (bx_ne2k_c *) arg;
-  
-  class_ptr->rx_frame(buf, len);
-}
-
-/*
- * rx_frame() - called by the platform-specific code when an
- * ethernet frame has been received. The destination address
- * is tested to see if it should be accepted, and if the
- * rx ring has enough room, it is copied into it and
- * the receive process is updated
- */
-void
-bx_ne2k_c::rx_frame(const void *buf, unsigned io_len)
-{
-  unsigned pages;
-  unsigned avail;
-  unsigned idx;
-  int wrapped;
-  int nextpage;
-  unsigned char pkthdr[4];
-  unsigned char *pktbuf = (unsigned char *) buf;
-  unsigned char *startptr;
-  static unsigned char bcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
-
-  BX_DEBUG(("rx_frame with length %d", io_len));
-
-
-  if ((BX_NE2K_THIS s.CR.stop != 0) ||
-      (BX_NE2K_THIS s.page_start == 0) ||
-      ((BX_NE2K_THIS s.DCR.loop == 0) &&
-       (BX_NE2K_THIS s.TCR.loop_cntl != 0))) {
-
-    return;
-  }
-
-  // Add the pkt header + CRC to the length, and work
-  // out how many 256-byte pages the frame would occupy
-  pages = (io_len + 4 + 4 + 255)/256;
-
-  if (BX_NE2K_THIS s.curr_page < BX_NE2K_THIS s.bound_ptr) {
-    avail = BX_NE2K_THIS s.bound_ptr - BX_NE2K_THIS s.curr_page;    
-  } else {
-    avail = (BX_NE2K_THIS s.page_stop - BX_NE2K_THIS s.page_start) -
-      (BX_NE2K_THIS s.curr_page - BX_NE2K_THIS s.bound_ptr);
-    wrapped = 1;
-  }
-
-  // Avoid getting into a buffer overflow condition by not attempting
-  // to do partial receives. The emulation to handle this condition
-  // seems particularly painful.
-  if ((avail < pages) 
-#if BX_NE2K_NEVER_FULL_RING
-      || (avail == pages)
-#endif
-      ) {
-    return;
-  }
-
-  if ((io_len < 60) && !BX_NE2K_THIS s.RCR.runts_ok) {
-    BX_DEBUG(("rejected small packet, length %d", io_len));
-    return;
-  }
-
-  // Do address filtering if not in promiscuous mode
-  if (! BX_NE2K_THIS s.RCR.promisc) {
-    if (!memcmp(buf, bcast_addr, 6)) {
-      if (!BX_NE2K_THIS s.RCR.broadcast) {
-       return;
-      }
-    } else if (pktbuf[0] & 0x01) {
-       if (! BX_NE2K_THIS s.RCR.multicast) {
-           return;
-       }
-      idx = mcast_index(buf);
-      if (!(BX_NE2K_THIS s.mchash[idx >> 3] & (1 << (idx & 0x7)))) {
-       return;
-      }
-    } else if (0 != memcmp(buf, BX_NE2K_THIS s.physaddr, 6)) {
-      return;
-    }
-  } else {
-      BX_DEBUG(("rx_frame promiscuous receive"));
-  }
-
-//    BX_INFO(("rx_frame %d to %x:%x:%x:%x:%x:%x from %x:%x:%x:%x:%x:%x",
-//        io_len,
-//        pktbuf[0], pktbuf[1], pktbuf[2], pktbuf[3], pktbuf[4], pktbuf[5],
-//        pktbuf[6], pktbuf[7], pktbuf[8], pktbuf[9], pktbuf[10], pktbuf[11]));
-
-  nextpage = BX_NE2K_THIS s.curr_page + pages;
-  if (nextpage >= BX_NE2K_THIS s.page_stop) {
-    nextpage -= BX_NE2K_THIS s.page_stop - BX_NE2K_THIS s.page_start;
-  }
-
-  // Setup packet header
-  pkthdr[0] = 0;       // rx status - old behavior
-  pkthdr[0] = 1;        // Probably better to set it all the time
-                        // rather than set it to 0, which is clearly wrong.
-  if (pktbuf[0] & 0x01) {
-    pkthdr[0] |= 0x20;  // rx status += multicast packet
-  }
-  pkthdr[1] = nextpage;        // ptr to next packet
-  pkthdr[2] = (io_len + 4) & 0xff;     // length-low
-  pkthdr[3] = (io_len + 4) >> 8;       // length-hi
-
-  // copy into buffer, update curpage, and signal interrupt if config'd
-  startptr = & BX_NE2K_THIS s.mem[BX_NE2K_THIS s.curr_page * 256 -
-                              BX_NE2K_MEMSTART];
-  if ((nextpage > BX_NE2K_THIS s.curr_page) ||
-      ((BX_NE2K_THIS s.curr_page + pages) == BX_NE2K_THIS s.page_stop)) {
-    memcpy(startptr, pkthdr, 4);
-    memcpy(startptr + 4, buf, io_len);
-    BX_NE2K_THIS s.curr_page = nextpage;
-  } else {
-    int endbytes = (BX_NE2K_THIS s.page_stop - BX_NE2K_THIS s.curr_page) 
-      * 256;
-    memcpy(startptr, pkthdr, 4);
-    memcpy(startptr + 4, buf, endbytes - 4);
-    startptr = & BX_NE2K_THIS s.mem[BX_NE2K_THIS s.page_start * 256 -
-                                BX_NE2K_MEMSTART];
-    memcpy(startptr, (void *)(pktbuf + endbytes - 4),
-          io_len - endbytes + 8);    
-    BX_NE2K_THIS s.curr_page = nextpage;
-  }
-  
-  BX_NE2K_THIS s.RSR.rx_ok = 1;
-  if (pktbuf[0] & 0x80) {
-    BX_NE2K_THIS s.RSR.rx_mbit = 1;
-  }
-
-  BX_NE2K_THIS s.ISR.pkt_rx = 1;
-
-  if (BX_NE2K_THIS s.IMR.rx_inte) {
-    DEV_pic_raise_irq(BX_NE2K_THIS s.base_irq);
-  }
-
-}
-
-void
-bx_ne2k_c::init(void)
-{
-  BX_DEBUG(("Init $Id: ne2k.cc,v 1.56.2.1 2004/02/02 22:37:22 cbothamy Exp $"));
-
-  // Read in values from config file
-  BX_NE2K_THIS s.base_address = bx_options.ne2k.Oioaddr->get ();
-  BX_NE2K_THIS s.base_irq     = bx_options.ne2k.Oirq->get ();
-  memcpy(BX_NE2K_THIS s.physaddr, bx_options.ne2k.Omacaddr->getptr (), 6);
-
-  if (BX_NE2K_THIS s.tx_timer_index == BX_NULL_TIMER_HANDLE) {
-    BX_NE2K_THIS s.tx_timer_index =
-      bx_pc_system.register_timer(this, tx_timer_handler, 0,
-                                  0,0, "ne2k"); // one-shot, inactive
-  }
-  // Register the IRQ and i/o port addresses
-  DEV_register_irq(BX_NE2K_THIS s.base_irq, "NE2000 ethernet NIC");
-
-  for (unsigned addr = BX_NE2K_THIS s.base_address; 
-       addr <= BX_NE2K_THIS s.base_address + 0x20; 
-       addr++) {
-    DEV_register_ioread_handler(this, read_handler, addr, "ne2000 NIC", 3);
-    DEV_register_iowrite_handler(this, write_handler, addr, "ne2000 NIC", 3);
-  }
-  BX_INFO(("port 0x%x/32 irq %d mac %02x:%02x:%02x:%02x:%02x:%02x",
-           BX_NE2K_THIS s.base_address,
-           BX_NE2K_THIS s.base_irq,
-           BX_NE2K_THIS s.physaddr[0],
-           BX_NE2K_THIS s.physaddr[1],
-           BX_NE2K_THIS s.physaddr[2],
-           BX_NE2K_THIS s.physaddr[3],
-           BX_NE2K_THIS s.physaddr[4],
-           BX_NE2K_THIS s.physaddr[5]));
-
-  // Initialise the mac address area by doubling the physical address
-  BX_NE2K_THIS s.macaddr[0]  = BX_NE2K_THIS s.physaddr[0];
-  BX_NE2K_THIS s.macaddr[1]  = BX_NE2K_THIS s.physaddr[0];
-  BX_NE2K_THIS s.macaddr[2]  = BX_NE2K_THIS s.physaddr[1];
-  BX_NE2K_THIS s.macaddr[3]  = BX_NE2K_THIS s.physaddr[1];
-  BX_NE2K_THIS s.macaddr[4]  = BX_NE2K_THIS s.physaddr[2];
-  BX_NE2K_THIS s.macaddr[5]  = BX_NE2K_THIS s.physaddr[2];
-  BX_NE2K_THIS s.macaddr[6]  = BX_NE2K_THIS s.physaddr[3];
-  BX_NE2K_THIS s.macaddr[7]  = BX_NE2K_THIS s.physaddr[3];
-  BX_NE2K_THIS s.macaddr[8]  = BX_NE2K_THIS s.physaddr[4];
-  BX_NE2K_THIS s.macaddr[9]  = BX_NE2K_THIS s.physaddr[4];
-  BX_NE2K_THIS s.macaddr[10] = BX_NE2K_THIS s.physaddr[5];
-  BX_NE2K_THIS s.macaddr[11] = BX_NE2K_THIS s.physaddr[5];
-    
-  // ne2k signature
-  for (int i = 12; i < 32; i++) 
-    BX_NE2K_THIS s.macaddr[i] = 0x57;
-    
-  // Attach to the simulated ethernet dev
-  char *ethmod = bx_options.ne2k.Oethmod->get_choice(bx_options.ne2k.Oethmod->get());
-  BX_NE2K_THIS ethdev = eth_locator_c::create(ethmod,
-                                              bx_options.ne2k.Oethdev->getptr (),
-                                              (const char *) bx_options.ne2k.Omacaddr->getptr (),
-                                              rx_handler, 
-                                              this);
-
-  if (BX_NE2K_THIS ethdev == NULL) {
-    BX_PANIC(("could not find eth module %s", ethmod));
-    // if they continue, use null.
-    BX_INFO(("could not find eth module %s - using null instead", ethmod));
-
-    BX_NE2K_THIS ethdev = eth_locator_c::create("null", NULL,
-                                                (const char *) bx_options.ne2k.Omacaddr->getptr (),
-                                                rx_handler, 
-                                                this);
-    if (BX_NE2K_THIS ethdev == NULL)
-      BX_PANIC(("could not locate null module"));
-  }
-
-  // Bring the register state into power-up state
-  theNE2kDevice->reset(BX_RESET_HARDWARE);
-}
-
-#if BX_DEBUGGER
-
-/*
- * this implements the info ne2k commands in the debugger.
- * info ne2k - shows all registers
- * info ne2k page N - shows all registers in a page
- * info ne2k page N reg M - shows just one register
- */
-
-#define SHOW_FIELD(reg,field) do { \
-  if (n>0 && !(n%5)) dbg_printf ("\n  "); \
-  dbg_printf ("%s=%d ", #field, BX_NE2K_THIS s.reg.field); \
-  n++; \
-} while (0);
-#define BX_HIGH_BYTE(x) ((0xff00 & (x)) >> 8)
-#define BX_LOW_BYTE(x) (0x00ff & (x))
-#define BX_DUPLICATE(n) if (brief && num!=n) break;
-
-void
-bx_ne2k_c::print_info (FILE *fp, int page, int reg, int brief)
-{
-  int i;
-  int n = 0;
-  if (page < 0) {
-    for (page=0; page<=2; page++)
-      theNE2kDevice->print_info (fp, page, reg, 1);
-    // tell them how to use this command
-    dbg_printf ("\nHow to use the info ne2k command:\n");
-    dbg_printf ("info ne2k - show all registers\n");
-    dbg_printf ("info ne2k page N - show registers in page N\n");
-    dbg_printf ("info ne2k page N reg M - show just one register\n");
-    return;
-  }
-  if (page > 2) {
-    dbg_printf ("NE2K has only pages 0, 1, and 2.  Page %d is out of range.\n", page);
-    return;
-  }
-  if (reg < 0) {
-    dbg_printf ("NE2K registers, page %d\n", page);
-    dbg_printf ("----------------------\n");
-    for (reg=0; reg<=15; reg++)
-      theNE2kDevice->print_info (fp, page, reg, 1);
-    dbg_printf ("----------------------\n");
-    return;
-  }
-  if (reg > 15) {
-    dbg_printf ("NE2K has only registers 0-15 (0x0-0xf).  Register %d is out of range.\n", reg);
-    return;
-  }
-  if (!brief) {
-    dbg_printf ("NE2K Info - page %d, register 0x%02x\n", page, reg);
-    dbg_printf ("----------------------------------\n");
-  }
-  int num = page*0x100 + reg;
-  switch (num) {
-    case 0x0000:
-    case 0x0100:
-    case 0x0200:
-      dbg_printf ("CR (Command register):\n  ");
-      SHOW_FIELD (CR, stop);
-      SHOW_FIELD (CR, start);
-      SHOW_FIELD (CR, tx_packet);
-      SHOW_FIELD (CR, rdma_cmd);
-      SHOW_FIELD (CR, pgsel);
-      dbg_printf ("\n");
-      break;
-    case 0x0003:
-      dbg_printf ("BNRY = Boundary Pointer = 0x%02x\n", BX_NE2K_THIS s.bound_ptr);
-      break;
-    case 0x0004:
-      dbg_printf ("TSR (Transmit Status Register), read-only:\n  ");
-      SHOW_FIELD (TSR, tx_ok);
-      SHOW_FIELD (TSR, reserved);
-      SHOW_FIELD (TSR, collided);
-      SHOW_FIELD (TSR, aborted);
-      SHOW_FIELD (TSR, no_carrier);
-      SHOW_FIELD (TSR, fifo_ur);
-      SHOW_FIELD (TSR, cd_hbeat);
-      SHOW_FIELD (TSR, ow_coll);
-      dbg_printf ("\n");
-      // fall through into TPSR, no break line.
-    case 0x0204:
-      dbg_printf ("TPSR = Transmit Page Start = 0x%02x\n", BX_NE2K_THIS s.tx_page_start);
-      break;
-    case 0x0005:
-    case 0x0006:  BX_DUPLICATE(0x0005);
-      dbg_printf ("NCR = Number of Collisions Register (read-only) = 0x%02x\n", BX_NE2K_THIS s.num_coll);
-      dbg_printf ("TBCR1,TBCR0 = Transmit Byte Count = %02x %02x\n", 
-         BX_HIGH_BYTE (BX_NE2K_THIS s.tx_bytes),
-         BX_LOW_BYTE (BX_NE2K_THIS s.tx_bytes));
-      dbg_printf ("FIFO = %02x\n", BX_NE2K_THIS s.fifo);
-      break;
-    case 0x0007:
-      dbg_printf ("ISR (Interrupt Status Register):\n  ");
-      SHOW_FIELD (ISR, pkt_rx);
-      SHOW_FIELD (ISR, pkt_tx);
-      SHOW_FIELD (ISR, rx_err);
-      SHOW_FIELD (ISR, tx_err);
-      SHOW_FIELD (ISR, overwrite);
-      SHOW_FIELD (ISR, cnt_oflow);
-      SHOW_FIELD (ISR, rdma_done);
-      SHOW_FIELD (ISR, reset);
-      dbg_printf ("\n");
-      break;
-    case 0x0008:
-    case 0x0009:  BX_DUPLICATE(0x0008);
-      dbg_printf ("CRDA1,0 = Current remote DMA address = %02x %02x\n", 
-         BX_HIGH_BYTE (BX_NE2K_THIS s.remote_dma),
-         BX_LOW_BYTE (BX_NE2K_THIS s.remote_dma));
-      dbg_printf ("RSAR1,0 = Remote start address = %02x %02x\n", 
-         BX_HIGH_BYTE(s.remote_start),
-         BX_LOW_BYTE(s.remote_start));
-      break;
-    case 0x000a:
-    case 0x000b:  BX_DUPLICATE(0x000a);
-      dbg_printf ("RCBR1,0 = Remote byte count = %02x\n", BX_NE2K_THIS s.remote_bytes);
-      break;
-    case 0x000c:
-      dbg_printf ("RSR (Receive Status Register), read-only:\n  ");
-      SHOW_FIELD (RSR, rx_ok);
-      SHOW_FIELD (RSR, bad_crc);
-      SHOW_FIELD (RSR, bad_falign);
-      SHOW_FIELD (RSR, fifo_or);
-      SHOW_FIELD (RSR, rx_missed);
-      SHOW_FIELD (RSR, rx_mbit);
-      SHOW_FIELD (RSR, rx_disabled);
-      SHOW_FIELD (RSR, deferred);
-      dbg_printf ("\n");
-      // fall through into RCR
-    case 0x020c:
-      dbg_printf ("RCR (Receive Configuration Register):\n  ");
-      SHOW_FIELD (RCR, errors_ok);
-      SHOW_FIELD (RCR, runts_ok);
-      SHOW_FIELD (RCR, broadcast);
-      SHOW_FIELD (RCR, multicast);
-      SHOW_FIELD (RCR, promisc);
-      SHOW_FIELD (RCR, monitor);
-      SHOW_FIELD (RCR, reserved);
-      dbg_printf ("\n");
-      break;
-    case 0x000d:
-      dbg_printf ("CNTR0 = Tally Counter 0 (Frame alignment errors) = %02x\n",
-         BX_NE2K_THIS s.tallycnt_0);
-      // fall through into TCR
-    case 0x020d:
-      dbg_printf ("TCR (Transmit Configuration Register):\n  ");
-      SHOW_FIELD (TCR, crc_disable);
-      SHOW_FIELD (TCR, loop_cntl);
-      SHOW_FIELD (TCR, ext_stoptx);
-      SHOW_FIELD (TCR, coll_prio);
-      SHOW_FIELD (TCR, reserved);
-      dbg_printf ("\n");
-      break;
-    case 0x000e:
-      dbg_printf ("CNTR1 = Tally Counter 1 (CRC Errors) = %02x\n",
-         BX_NE2K_THIS s.tallycnt_1);
-      // fall through into DCR
-    case 0x020e:
-      dbg_printf ("DCR (Data Configuration Register):\n  ");
-      SHOW_FIELD (DCR, wdsize);
-      SHOW_FIELD (DCR, endian);
-      SHOW_FIELD (DCR, longaddr);
-      SHOW_FIELD (DCR, loop);
-      SHOW_FIELD (DCR, auto_rx);
-      SHOW_FIELD (DCR, fifo_size);
-      dbg_printf ("\n");
-      break;
-    case 0x000f:
-      dbg_printf ("CNTR2 = Tally Counter 2 (Missed Packet Errors) = %02x\n",
-         BX_NE2K_THIS s.tallycnt_2);
-      // fall through into IMR
-    case 0x020f:
-      dbg_printf ("IMR (Interrupt Mask Register)\n  ");
-      SHOW_FIELD (IMR, rx_inte);
-      SHOW_FIELD (IMR, tx_inte);
-      SHOW_FIELD (IMR, rxerr_inte);
-      SHOW_FIELD (IMR, txerr_inte);
-      SHOW_FIELD (IMR, overw_inte);
-      SHOW_FIELD (IMR, cofl_inte);
-      SHOW_FIELD (IMR, rdma_inte);
-      SHOW_FIELD (IMR, reserved);
-      dbg_printf ("\n");
-      break;
-    case 0x0101:
-    case 0x0102:  BX_DUPLICATE(0x0101);
-    case 0x0103:  BX_DUPLICATE(0x0101);
-    case 0x0104:  BX_DUPLICATE(0x0101);
-    case 0x0105:  BX_DUPLICATE(0x0101);
-    case 0x0106:  BX_DUPLICATE(0x0101);
-      dbg_printf ("MAC address registers are located at page 1, registers 1-6.\n");
-      dbg_printf ("The MAC address is ");
-      for (i=0; i<=5; i++) 
-       dbg_printf ("%02x%c", BX_NE2K_THIS s.physaddr[i], i<5?':' : '\n');
-      break;
-    case 0x0107:
-      dbg_printf ("Current page is 0x%02x\n", BX_NE2K_THIS s.curr_page);
-      break;
-    case 0x0108:
-    case 0x0109:  BX_DUPLICATE(0x0108);
-    case 0x010A:  BX_DUPLICATE(0x0108);
-    case 0x010B:  BX_DUPLICATE(0x0108);
-    case 0x010C:  BX_DUPLICATE(0x0108);
-    case 0x010D:  BX_DUPLICATE(0x0108);
-    case 0x010E:  BX_DUPLICATE(0x0108);
-    case 0x010F:  BX_DUPLICATE(0x0108);
-      dbg_printf ("MAR0-7 (Multicast address registers 0-7) are set to:\n");
-      for (i=0; i<8; i++) dbg_printf ("%02x ", BX_NE2K_THIS s.mchash[i]);
-      dbg_printf ("\nMAR0 is listed first.\n");
-      break;
-    case 0x0001:
-    case 0x0002:  BX_DUPLICATE(0x0001);
-    case 0x0201:  BX_DUPLICATE(0x0001);
-    case 0x0202:  BX_DUPLICATE(0x0001);
-      dbg_printf ("PSTART = Page start register = %02x\n", BX_NE2K_THIS s.page_start);
-      dbg_printf ("PSTOP = Page stop register = %02x\n", BX_NE2K_THIS s.page_stop);
-      dbg_printf ("Local DMA address = %02x %02x\n", 
-         BX_HIGH_BYTE(BX_NE2K_THIS s.local_dma),
-         BX_LOW_BYTE(BX_NE2K_THIS s.local_dma));
-      break;
-    case 0x0203:
-      dbg_printf ("Remote Next Packet Pointer = %02x\n", BX_NE2K_THIS s.rempkt_ptr);
-      break;
-    case 0x0205:
-      dbg_printf ("Local Next Packet Pointer = %02x\n", BX_NE2K_THIS s.localpkt_ptr);
-      break;
-    case 0x0206:
-    case 0x0207:  BX_DUPLICATE(0x0206);
-      dbg_printf ("Address Counter= %02x %02x\n", 
-        BX_HIGH_BYTE(BX_NE2K_THIS s.address_cnt),
-        BX_LOW_BYTE(BX_NE2K_THIS s.address_cnt));
-      break;
-    case 0x0208:
-    case 0x0209:  BX_DUPLICATE(0x0208);
-    case 0x020A:  BX_DUPLICATE(0x0208);
-    case 0x020B:  BX_DUPLICATE(0x0208);
-      if (!brief) dbg_printf ("Reserved\n");
-    case 0xffff:
-      dbg_printf ("IMR (Interrupt Mask Register):\n  ");
-      dbg_printf ("\n");
-      break;
-    default:
-      dbg_printf ("NE2K info: sorry, page %d register %d cannot be displayed.\n", page, reg);
-  }
-  if (!brief)
-    dbg_printf ("\n");
-}
-
-#else
-
-void
-bx_ne2k_c::print_info (FILE *fp, int page, int reg, int brief)
-{
-}
-
-#endif
-
-#endif /* if BX_NE2K_SUPPORT */
diff --git a/tools/ioemu/iodev/ne2k.h b/tools/ioemu/iodev/ne2k.h
deleted file mode 100644 (file)
index 37cc712..0000000
+++ /dev/null
@@ -1,239 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: ne2k.h,v 1.11 2003/03/02 23:59:11 cbothamy Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2001  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-// Peter Grehan (grehan@iprg.nokia.com) coded all of this
-// NE2000/ether stuff.
-
-//
-// An implementation of an ne2000 ISA ethernet adapter. This part uses
-// a National Semiconductor DS-8390 ethernet MAC chip, with some h/w
-// to provide a windowed memory region for the chip and a MAC address.
-//
-
-
-#if BX_USE_NE2K_SMF
-#  define BX_NE2K_SMF  static
-#  define BX_NE2K_THIS theNE2kDevice->
-#else
-#  define BX_NE2K_SMF
-#  define BX_NE2K_THIS this->
-#endif
-
-#define  BX_NE2K_MEMSIZ    (32*1024)
-#define  BX_NE2K_MEMSTART  (16*1024)
-#define  BX_NE2K_MEMEND    (BX_NE2K_MEMSTART + BX_NE2K_MEMSIZ)
-
-typedef struct {
-    //
-    // ne2k register state
-   
-    //
-    // Page 0
-    //
-    //  Command Register - 00h read/write
-    struct {
-        bx_bool  stop;         // STP - Software Reset command
-        bx_bool  start;                // START - start the NIC
-        bx_bool  tx_packet;    // TXP - initiate packet transmission
-        Bit8u    rdma_cmd;      // RD0,RD1,RD2 - Remote DMA command
-       Bit8u    pgsel;         // PS0,PS1 - Page select
-    } CR;
-    // Interrupt Status Register - 07h read/write
-    struct {  
-       bx_bool  pkt_rx;        // PRX - packet received with no errors
-       bx_bool  pkt_tx;        // PTX - packet transmitted with no errors
-       bx_bool  rx_err;        // RXE - packet received with 1 or more errors
-       bx_bool  tx_err;        // TXE - packet tx'd       "  " "    "    "
-       bx_bool  overwrite;     // OVW - rx buffer resources exhausted
-       bx_bool  cnt_oflow;     // CNT - network tally counter MSB's set
-       bx_bool  rdma_done;     // RDC - remote DMA complete
-       bx_bool  reset;         // RST - reset status
-    } ISR;
-    // Interrupt Mask Register - 0fh write
-    struct {
-       bx_bool  rx_inte;       // PRXE - packet rx interrupt enable
-       bx_bool  tx_inte;       // PTXE - packet tx interrput enable
-       bx_bool  rxerr_inte;    // RXEE - rx error interrupt enable
-       bx_bool  txerr_inte;    // TXEE - tx error interrupt enable
-       bx_bool  overw_inte;    // OVWE - overwrite warn int enable
-       bx_bool  cofl_inte;     // CNTE - counter o'flow int enable
-       bx_bool  rdma_inte;     // RDCE - remote DMA complete int enable
-       bx_bool  reserved;      //  D7 - reserved
-    } IMR;
-    // Data Configuration Register - 0eh write
-    struct {
-       bx_bool  wdsize;        // WTS - 8/16-bit select
-       bx_bool  endian;        // BOS - byte-order select
-       bx_bool  longaddr;      // LAS - long-address select
-       bx_bool  loop;          // LS  - loopback select
-       bx_bool  auto_rx;       // AR  - auto-remove rx packets with remote DMA
-        Bit8u    fifo_size;    // FT0,FT1 - fifo threshold
-    } DCR;
-    // Transmit Configuration Register - 0dh write
-    struct {
-       bx_bool  crc_disable;   // CRC - inhibit tx CRC
-       Bit8u    loop_cntl;     // LB0,LB1 - loopback control
-       bx_bool  ext_stoptx;    // ATD - allow tx disable by external mcast
-       bx_bool  coll_prio;     // OFST - backoff algorithm select
-       Bit8u    reserved;      //  D5,D6,D7 - reserved
-    } TCR;
-    // Transmit Status Register - 04h read
-    struct {
-       bx_bool  tx_ok;         // PTX - tx complete without error
-       bx_bool  reserved;      //  D1 - reserved
-       bx_bool  collided;      // COL - tx collided >= 1 times
-       bx_bool  aborted;       // ABT - aborted due to excessive collisions
-       bx_bool  no_carrier;    // CRS - carrier-sense lost
-       bx_bool  fifo_ur;       // FU  - FIFO underrun
-       bx_bool  cd_hbeat;      // CDH - no tx cd-heartbeat from transceiver
-       bx_bool  ow_coll;       // OWC - out-of-window collision
-    } TSR;
-    // Receive Configuration Register - 0ch write
-    struct {
-       bx_bool  errors_ok;     // SEP - accept pkts with rx errors
-       bx_bool  runts_ok;      // AR  - accept < 64-byte runts
-       bx_bool  broadcast;     // AB  - accept eth broadcast address
-       bx_bool  multicast;     // AM  - check mcast hash array
-       bx_bool  promisc;       // PRO - accept all packets
-       bx_bool  monitor;       // MON - check pkts, but don't rx
-       Bit8u    reserved;      //  D6,D7 - reserved
-    } RCR;
-    // Receive Status Register - 0ch read
-    struct {
-       bx_bool  rx_ok;         // PRX - rx complete without error
-       bx_bool  bad_crc;       // CRC - Bad CRC detected
-       bx_bool  bad_falign;    // FAE - frame alignment error
-       bx_bool  fifo_or;       // FO  - FIFO overrun
-       bx_bool  rx_missed;     // MPA - missed packet error
-       bx_bool  rx_mbit;       // PHY - unicast or mcast/bcast address match
-       bx_bool  rx_disabled;   // DIS - set when in monitor mode
-       bx_bool  deferred;      // DFR - collision active
-    } RSR;
-
-    Bit16u local_dma;  // 01,02h read ; current local DMA addr
-    Bit8u  page_start;  // 01h write ; page start register
-    Bit8u  page_stop;   // 02h write ; page stop register
-    Bit8u  bound_ptr;   // 03h read/write ; boundary pointer
-    Bit8u  tx_page_start; // 04h write ; transmit page start register
-    Bit8u  num_coll;    // 05h read  ; number-of-collisions register
-    Bit16u tx_bytes;    // 05,06h write ; transmit byte-count register
-    Bit8u  fifo;       // 06h read  ; FIFO
-    Bit16u remote_dma;  // 08,09h read ; current remote DMA addr
-    Bit16u remote_start;  // 08,09h write ; remote start address register
-    Bit16u remote_bytes;  // 0a,0bh write ; remote byte-count register
-    Bit8u  tallycnt_0;  // 0dh read  ; tally counter 0 (frame align errors)
-    Bit8u  tallycnt_1;  // 0eh read  ; tally counter 1 (CRC errors)
-    Bit8u  tallycnt_2;  // 0fh read  ; tally counter 2 (missed pkt errors)
-
-    //
-    // Page 1
-    //
-    //   Command Register 00h (repeated)
-    //
-    Bit8u  physaddr[6];  // 01-06h read/write ; MAC address
-    Bit8u  curr_page;    // 07h read/write ; current page register
-    Bit8u  mchash[8];    // 08-0fh read/write ; multicast hash array
-
-    //
-    // Page 2  - diagnostic use only
-    // 
-    //   Command Register 00h (repeated)
-    //
-    //   Page Start Register 01h read  (repeated)
-    //   Page Stop Register  02h read  (repeated)
-    //   Current Local DMA Address 01,02h write (repeated)
-    //   Transmit Page start address 04h read (repeated)
-    //   Receive Configuration Register 0ch read (repeated)
-    //   Transmit Configuration Register 0dh read (repeated)
-    //   Data Configuration Register 0eh read (repeated)
-    //   Interrupt Mask Register 0fh read (repeated)
-    //
-    Bit8u  rempkt_ptr;   // 03h read/write ; remote next-packet pointer
-    Bit8u  localpkt_ptr; // 05h read/write ; local next-packet pointer
-    Bit16u address_cnt;  // 06,07h read/write ; address counter
-
-    //
-    // Page 3  - should never be modified.
-    //
-
-    // Novell ASIC state
-    Bit8u  macaddr[32];          // ASIC ROM'd MAC address, even bytes
-    Bit8u  mem[BX_NE2K_MEMSIZ];  // on-chip packet memory
-
-    // ne2k internal state
-    Bit32u base_address;
-    int    base_irq;
-    int    tx_timer_index;
-    int    tx_timer_active;
-
-} bx_ne2k_t;
-
-
-
-class bx_ne2k_c : public bx_ne2k_stub_c {
-public:
-  bx_ne2k_c(void);
-  ~bx_ne2k_c(void);
-  virtual void init(void);
-  virtual void reset(unsigned type);
-  virtual void print_info (FILE *file, int page, int reg, int nodups);
-
-private:
-  bx_ne2k_t s;
-
-  eth_pktmover_c *ethdev;
-
-  BX_NE2K_SMF Bit32u read_cr(void);
-  BX_NE2K_SMF void   write_cr(Bit32u value);
-
-  BX_NE2K_SMF Bit32u chipmem_read(Bit32u address, unsigned io_len) BX_CPP_AttrRegparmN(2);
-  BX_NE2K_SMF Bit32u asic_read(Bit32u offset, unsigned io_len) BX_CPP_AttrRegparmN(2);
-  BX_NE2K_SMF Bit32u page0_read(Bit32u offset, unsigned io_len);
-  BX_NE2K_SMF Bit32u page1_read(Bit32u offset, unsigned io_len);
-  BX_NE2K_SMF Bit32u page2_read(Bit32u offset, unsigned io_len);
-  BX_NE2K_SMF Bit32u page3_read(Bit32u offset, unsigned io_len);
-
-  BX_NE2K_SMF void chipmem_write(Bit32u address, Bit32u value, unsigned io_len) BX_CPP_AttrRegparmN(3);
-  BX_NE2K_SMF void asic_write(Bit32u address, Bit32u value, unsigned io_len);
-  BX_NE2K_SMF void page0_write(Bit32u address, Bit32u value, unsigned io_len);
-  BX_NE2K_SMF void page1_write(Bit32u address, Bit32u value, unsigned io_len);
-  BX_NE2K_SMF void page2_write(Bit32u address, Bit32u value, unsigned io_len);
-  BX_NE2K_SMF void page3_write(Bit32u address, Bit32u value, unsigned io_len);
-
-  static void tx_timer_handler(void *);
-  BX_NE2K_SMF void tx_timer(void);
-
-  static void rx_handler(void *arg, const void *buf, unsigned len);
-  BX_NE2K_SMF unsigned mcast_index(const void *dst);
-  BX_NE2K_SMF void rx_frame(const void *buf, unsigned io_len);
-
-  static Bit32u read_handler(void *this_ptr, Bit32u address, unsigned io_len);
-  static void   write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);
-#if !BX_USE_NE2K_SMF
-  Bit32u read(Bit32u address, unsigned io_len);
-  void   write(Bit32u address, Bit32u value, unsigned io_len);
-#endif
-};
diff --git a/tools/ioemu/iodev/osdep.cc b/tools/ioemu/iodev/osdep.cc
deleted file mode 100644 (file)
index c010306..0000000
+++ /dev/null
@@ -1,340 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: osdep.cc,v 1.14.2.1 2004/02/06 22:14:34 danielg4 Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2001  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-//
-// osdep.cc
-// 
-// Provide definition of library functions that are missing on various
-// systems.  The only reason this is a .cc file rather than a .c file
-// is so that it can include bochs.h.  Bochs.h includes all the required
-// system headers, with appropriate #ifdefs for different compilers and 
-// platforms.
-//
-
-#include "bochs.h"
-
-//////////////////////////////////////////////////////////////////////
-// Missing library functions.  These should work on any platform 
-// that needs them.
-//////////////////////////////////////////////////////////////////////
-
-#if !BX_HAVE_SNPRINTF
-/* XXX use real snprintf */
-/* if they don't have snprintf, just use sprintf */
-int bx_snprintf (char *s, size_t maxlen, const char *format, ...)
-{
-  va_list arg;
-  int done;
-
-  va_start (arg, format);
-  done = vsprintf (s, format, arg);
-  va_end (arg);
-
-  return done;
-}
-#endif  /* !BX_HAVE_SNPRINTF */
-
-
-#if (!BX_HAVE_STRTOULL && !BX_HAVE_STRTOUQ)
-/* taken from glibc-2.2.2: strtod.c, and stripped down a lot.  There are 
-   still a few leftover references to decimal points and exponents, 
-   but it works for bases 10 and 16 */
-
-#define RETURN(val,end)                                                              \
-    do { if (endptr != NULL) *endptr = (char *) (end);               \
-        return val; } while (0)
-
-Bit64u
-bx_strtoull (const char *nptr, char **endptr, int baseignore)
-{
-  int negative;                        /* The sign of the number.  */
-  int exponent;                        /* Exponent of the number.  */
-
-  /* Numbers starting `0X' or `0x' have to be processed with base 16.  */
-  int base = 10;
-
-  /* Number of bits currently in result value.  */
-  int bits;
-
-  /* Running pointer after the last character processed in the string.  */
-  const char *cp, *tp;
-  /* Start of significant part of the number.  */
-  const char *startp, *start_of_digits;
-  /* Total number of digit and number of digits in integer part.  */
-  int dig_no;
-  /* Contains the last character read.  */
-  char c;
-
-  Bit64s n = 0;
-  char const *p;
-
-  /* Prepare number representation.  */
-  exponent = 0;
-  negative = 0;
-  bits = 0;
-
-  /* Parse string to get maximal legal prefix.  We need the number of
-     characters of the integer part, the fractional part and the exponent.  */
-  cp = nptr - 1;
-  /* Ignore leading white space.  */
-  do
-    c = *++cp;
-  while (isspace (c));
-
-  /* Get sign of the result.  */
-  if (c == '-')
-    {
-      negative = 1;
-      c = *++cp;
-    }
-  else if (c == '+')
-    c = *++cp;
-
-  if (c < '0' || c > '9')
-    {
-      /* It is really a text we do not recognize.  */
-      RETURN (0, nptr);
-    }
-
-  /* First look whether we are faced with a hexadecimal number.  */
-  if (c == '0' && tolower (cp[1]) == 'x')
-    {
-      /* Okay, it is a hexa-decimal number.  Remember this and skip
-        the characters.  BTW: hexadecimal numbers must not be
-        grouped.  */
-      base = 16;
-      cp += 2;
-      c = *cp;
-    }
-
-  /* Record the start of the digits, in case we will check their grouping.  */
-  start_of_digits = startp = cp;
-
-  /* Ignore leading zeroes.  This helps us to avoid useless computations.  */
-  while (c == '0')
-    c = *++cp;
-
-  /* If no other digit but a '0' is found the result is 0.0.
-     Return current read pointer.  */
-  if ((c < '0' || c > '9')
-      && (base == 16 && (c < tolower ('a') || c > tolower ('f')))
-      && (base == 16 && (cp == start_of_digits || tolower (c) != 'p'))
-      && (base != 16 && tolower (c) != 'e'))
-    {
-      tp = start_of_digits;
-      /* If TP is at the start of the digits, there was no correctly
-        grouped prefix of the string; so no number found.  */
-      RETURN (0, tp == start_of_digits ? (base == 16 ? cp - 1 : nptr) : tp);
-    }
-
-  /* Remember first significant digit and read following characters until the
-     decimal point, exponent character or any non-FP number character.  */
-  startp = cp;
-  dig_no = 0;
-  while (1)
-    {
-      if ((c >= '0' && c <= '9')
-         || (base == 16 && tolower (c) >= 'a' && tolower (c) <= 'f'))
-       ++dig_no;
-      else
-       break;
-      c = *++cp;
-    }
-
-  /* The whole string is parsed.  Store the address of the next character.  */
-  if (endptr)
-    *endptr = (char *) cp;
-
-  if (dig_no == 0) 
-    return 0;
-
-  for (p=start_of_digits; p!=cp; p++) {
-    n = n * (Bit64s)base;
-    c = tolower (*p);
-    c = (c >= 'a') ? (10+c-'a') : c-'0';
-    n = n + (Bit64s)c;
-    //printf ("after shifting in digit %c, n is %lld\n", *p, n);
-  }
-  return negative? -n : n;
-}
-#endif  /* !BX_HAVE_STRTOULL */
-
-#if BX_TEST_STRTOULL_MAIN
-/* test driver for strtoull.  Do not compile by default. */
-int main (int argc, char **argv)
-{
-  char buf[256], *endbuf;
-  long l;
-  Bit64s ll;
-  while (1) {
-    printf ("Enter a long int: ");
-    gets (buf);
-    l = strtoul (buf, &endbuf, 10);
-    printf ("As a long, %ld\n", l);
-    printf ("Endbuf is at buf[%d]\n", endbuf-buf);
-    ll = bx_strtoull (buf, &endbuf, 10);
-    printf ("As a long long, %lld\n", ll);
-    printf ("Endbuf is at buf[%d]\n", endbuf-buf);
-  }
-  return 0;
-}
-#endif  /* BX_TEST_STRTOULL_MAIN */
-
-#if !BX_HAVE_STRDUP
-/* XXX use real strdup */
-char *bx_strdup(const char *str)
-{
-       char *temp;
-       
-       temp = (char*)malloc(strlen(str)+1);
-       sprintf(temp, "%s", str);
-       return temp;
-       
-       // Well, I'm sure this isn't how strdup is REALLY implemented,
-       // but it works...
-}
-#endif  /* !BX_HAVE_STRDUP */
-
-#if !BX_HAVE_STRREV
-char *bx_strrev(char *str)
-{
-  char *p1, *p2;
-
-  if (! str || ! *str)
-    return str;
-
-  for (p1 = str, p2 = str + strlen(str) - 1; p2 > p1; ++p1, --p2) {
-    *p1 ^= *p2;
-    *p2 ^= *p1;
-    *p1 ^= *p2;
-  }
-  return str;
-}
-#endif  /* !BX_HAVE_STRREV */
-
-#if BX_WITH_MACOS
-namespace std{extern "C" {char *mktemp(char *tpl);}}
-#endif
-#if !BX_HAVE_MKSTEMP
-int bx_mkstemp(char *tpl)
-{
-  mktemp(tpl);
-  return ::open(tpl, O_RDWR | O_CREAT | O_TRUNC
-#  ifdef O_BINARY
-            | O_BINARY
-#  endif
-              , S_IWUSR | S_IRUSR | S_IRGRP | S_IWGRP);
-}
-#endif // !BX_HAVE_MKSTEMP
-
-//////////////////////////////////////////////////////////////////////
-// Missing library functions, implemented for MacOS only
-//////////////////////////////////////////////////////////////////////
-
-#if BX_WITH_MACOS
-// these functions are part of MacBochs.  They are not intended to be
-// portable!
-#include <Devices.h>
-#include <Files.h>
-#include <Disks.h>
-
-int fd_read(char *buffer, Bit32u offset, Bit32u bytes)
-{
-       OSErr err;
-       IOParam param;
-       
-       param.ioRefNum=-5; // Refnum of the floppy disk driver
-       param.ioVRefNum=1;
-       param.ioPosMode=fsFromStart;
-       param.ioPosOffset=offset;
-       param.ioBuffer=buffer;
-       param.ioReqCount=bytes;
-       err = PBReadSync((union ParamBlockRec *)(&param));
-       return param.ioActCount;
-}
-
-int fd_write(char *buffer, Bit32u offset, Bit32u bytes)
-{
-       OSErr           err;
-       IOParam param;
-       
-       param.ioRefNum=-5; // Refnum of the floppy disk driver
-       param.ioVRefNum=1;
-       param.ioPosMode=fsFromStart;
-       param.ioPosOffset=offset;
-       param.ioBuffer=buffer;
-       param.ioReqCount=bytes;
-       err = PBWriteSync((union ParamBlockRec *)(&param));
-       return param.ioActCount;
-}
-
-int fd_stat(struct stat *buf)
-{
-       OSErr           err;
-       DrvSts  status;
-       int                     result;
-       
-       result = 0;
-       err = DriveStatus(1, &status);
-       if (status.diskInPlace <1 || status.diskInPlace > 2)
-               result = -1;
-       buf->st_mode = S_IFCHR;
-       return result;
-}
-#endif /* BX_WITH_MACOS */
-
-
-
-//////////////////////////////////////////////////////////////////////
-// New functions to replace library functions
-//   with OS-independent versions
-//////////////////////////////////////////////////////////////////////
-
-#if BX_HAVE_REALTIME_USEC
-#  if BX_HAVE_GETTIMEOFDAY
-Bit64u bx_get_realtime64_usec (void) {
-  timeval thetime;
-  gettimeofday(&thetime,0);
-  Bit64u mytime;
-  mytime=(Bit64u)thetime.tv_sec*(Bit64u)1000000+(Bit64u)thetime.tv_usec;
-  return mytime;
-}
-#  elif defined(WIN32)
-Bit64u last_realtime64_top = 0;
-Bit64u last_realtime64_bottom = 0;
-Bit64u bx_get_realtime64_usec (void) {
-  Bit64u new_bottom = ((Bit64u) GetTickCount()) & BX_CONST64(0x0FFFFFFFF);
-  if(new_bottom < last_realtime64_bottom) {
-    last_realtime64_top += BX_CONST64(0x0000000100000000);
-  }
-  last_realtime64_bottom = new_bottom;
-  Bit64u interim_realtime64 =
-    (last_realtime64_top & BX_CONST64(0xFFFFFFFF00000000)) |
-    (new_bottom          & BX_CONST64(0x00000000FFFFFFFF));
-  return interim_realtime64*(BX_CONST64(1000));
-}
-#  endif
-#endif
diff --git a/tools/ioemu/iodev/parallel.cc b/tools/ioemu/iodev/parallel.cc
deleted file mode 100644 (file)
index 8b0d4b3..0000000
+++ /dev/null
@@ -1,300 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: parallel.cc,v 1.24 2003/10/29 17:29:26 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-//
-////////////////////////////////////////////////////////
-// This code was just a few stubs until Volker.Ruppert@t-online.de 
-// fixed it up in November 2001.
-
-
-// Define BX_PLUGGABLE in files that can be compiled into plugins.  For
-// platforms that require a special tag on exported symbols, BX_PLUGGABLE 
-// is used to know when we are exporting symbols and when we are importing.
-#define BX_PLUGGABLE
-
-#include "bochs.h"
-#define LOG_THIS theParallelDevice->
-
-bx_parallel_c *theParallelDevice = NULL;
-
-  int
-libparallel_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
-{
-  theParallelDevice = new bx_parallel_c ();
-  bx_devices.pluginParallelDevice = theParallelDevice;
-  BX_REGISTER_DEVICE_DEVMODEL(plugin, type, theParallelDevice, BX_PLUGIN_PARALLEL);
-  return(0); // Success
-}
-
-  void
-libparallel_LTX_plugin_fini(void)
-{
-}
-
-bx_parallel_c::bx_parallel_c(void)
-{
-  put("PAR");
-  settype(PARLOG);
-  s.output = NULL;
-}
-
-bx_parallel_c::~bx_parallel_c(void)
-{
-  if (s.output != NULL)
-    fclose(s.output);
-}
-
-  void
-bx_parallel_c::init(void)
-{
-  BX_DEBUG(("Init $Id: parallel.cc,v 1.24 2003/10/29 17:29:26 vruppert Exp $"));
-
-  if (bx_options.par[0].Oenabled->get ()) {
-
-    /* PARALLEL PORT 1 */
-
-    DEV_register_irq(7, "Parallel Port 1");
-    BX_INFO (("parallel port 1 at 0x378 irq 7"));
-    for (unsigned addr=0x0378; addr<=0x037A; addr++) {
-      DEV_register_ioread_handler(this, read_handler, addr, "Parallel Port 1", 1);
-      }
-    DEV_register_iowrite_handler(this, write_handler, 0x0378, "Parallel Port 1", 1);
-    DEV_register_iowrite_handler(this, write_handler, 0x037A, "Parallel Port 1", 1);
-
-    BX_PAR_THIS s.STATUS.error = 1;
-    BX_PAR_THIS s.STATUS.slct  = 1;
-    BX_PAR_THIS s.STATUS.pe    = 0;
-    BX_PAR_THIS s.STATUS.ack   = 1;
-    BX_PAR_THIS s.STATUS.busy  = 1;
-
-    BX_PAR_THIS s.CONTROL.strobe   = 0;
-    BX_PAR_THIS s.CONTROL.autofeed = 0;
-    BX_PAR_THIS s.CONTROL.init     = 1;
-    BX_PAR_THIS s.CONTROL.slct_in  = 1;
-    BX_PAR_THIS s.CONTROL.irq      = 0;
-    BX_PAR_THIS s.CONTROL.input    = 0;
-
-    BX_PAR_THIS s.initmode = 0;
-
-    if (strlen(bx_options.par[0].Ooutfile->getptr ()) > 0) {
-      s.output = fopen(bx_options.par[0].Ooutfile->getptr (), "wb");
-      if (!s.output)
-        BX_PANIC (("Could not open '%s' to write parport1 output",
-                   bx_options.par[0].Ooutfile->getptr ()));
-    }
-  }
-}
-
-  void
-bx_parallel_c::reset(unsigned type)
-{
-}
-
-  void
-bx_parallel_c::virtual_printer(void)
-{
-  if (BX_PAR_THIS s.STATUS.slct) {
-    if (BX_PAR_THIS s.output != NULL) {
-      fputc(BX_PAR_THIS s.data, BX_PAR_THIS s.output);
-      fflush (BX_PAR_THIS s.output);
-      }
-    if (BX_PAR_THIS s.CONTROL.irq == 1) {
-      DEV_pic_raise_irq(7);
-      }
-    BX_PAR_THIS s.STATUS.ack = 0;
-    BX_PAR_THIS s.STATUS.busy = 1;
-    }
-  else {
-    BX_ERROR(("data is valid, but printer is offline"));
-    }
-}
-
-  // static IO port read callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-  Bit32u
-bx_parallel_c::read_handler(void *this_ptr, Bit32u address, unsigned io_len)
-{
-#if !BX_USE_PAR_SMF
-  bx_parallel_c *class_ptr = (bx_parallel_c *) this_ptr;
-
-  return( class_ptr->read(address, io_len) );
-}
-
-
-  Bit32u
-bx_parallel_c::read(Bit32u address, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif  // !BX_USE_PAR_SMF
-
-  Bit32u retval;
-
-  switch (address) {
-    /* PARALLEL PORT 1 */
-    case 0x0378:
-      if (!BX_PAR_THIS s.CONTROL.input) {
-        return (Bit32u)BX_PAR_THIS s.data;
-      } else {
-        BX_ERROR(("read: input mode not supported"));
-        return (0xFF);
-      }
-      break;
-    case 0x0379:
-      {
-        retval = ((BX_PAR_THIS s.STATUS.busy  << 7) |
-                  (BX_PAR_THIS s.STATUS.ack   << 6) |
-                  (BX_PAR_THIS s.STATUS.pe    << 5) |
-                  (BX_PAR_THIS s.STATUS.slct  << 4) |
-                  (BX_PAR_THIS s.STATUS.error << 3));
-        if (BX_PAR_THIS s.STATUS.ack == 0) {
-          BX_PAR_THIS s.STATUS.ack = 1;
-          if (BX_PAR_THIS s.CONTROL.irq == 1) {
-            DEV_pic_lower_irq(7);
-          }
-        }
-        if (BX_PAR_THIS s.initmode == 1) {
-          BX_PAR_THIS s.STATUS.busy  = 1;
-          BX_PAR_THIS s.STATUS.slct  = 1;
-          BX_PAR_THIS s.STATUS.ack  = 0;
-          if (BX_PAR_THIS s.CONTROL.irq == 1) {
-            DEV_pic_raise_irq(7);
-          }
-          BX_PAR_THIS s.initmode = 0;
-        }
-        BX_DEBUG(("read: status register returns 0x%02x", retval));
-        return retval;
-      }
-      break;
-    case 0x037A:
-      {
-        retval = ((BX_PAR_THIS s.CONTROL.input    << 5) |
-                  (BX_PAR_THIS s.CONTROL.irq      << 4) |
-                  (BX_PAR_THIS s.CONTROL.slct_in  << 3) |
-                  (BX_PAR_THIS s.CONTROL.init     << 2) |
-                  (BX_PAR_THIS s.CONTROL.autofeed << 1) |
-                  (BX_PAR_THIS s.CONTROL.strobe));
-        BX_DEBUG(("read: control register returns 0x%02x", retval));
-        return retval;
-      }
-      break;
-  }
-  return(0);
-}
-
-
-  // static IO port write callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-  void
-bx_parallel_c::write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len)
-{
-#if !BX_USE_PAR_SMF
-  bx_parallel_c *class_ptr = (bx_parallel_c *) this_ptr;
-
-  class_ptr->write(address, value, io_len);
-}
-
-  void
-bx_parallel_c::write(Bit32u address, Bit32u value, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif  // !BX_USE_PAR_SMF
-
-  switch (address) {
-    /* PARALLEL PORT 1 */
-    case 0x0378:
-      BX_PAR_THIS s.data = (Bit8u)value;
-      BX_DEBUG(("write: data output register = 0x%02x", (Bit8u)value));
-      break;
-    case 0x037A:
-      {
-        if ((value & 0x01) == 0x01) {
-          if (BX_PAR_THIS s.CONTROL.strobe == 0) {
-            BX_PAR_THIS s.CONTROL.strobe = 1;
-            virtual_printer(); // data is valid now
-          }
-        } else {
-          if (BX_PAR_THIS s.CONTROL.strobe == 1) {
-            BX_PAR_THIS s.CONTROL.strobe = 0;
-          }
-        }
-        BX_PAR_THIS s.CONTROL.autofeed = ((value & 0x02) == 0x02);
-        if ((value & 0x04) == 0x04) {
-          if (BX_PAR_THIS s.CONTROL.init == 0) {
-            BX_PAR_THIS s.CONTROL.init = 1;
-            BX_PAR_THIS s.STATUS.busy  = 0;
-            BX_PAR_THIS s.STATUS.slct  = 0;
-            BX_PAR_THIS s.initmode = 1;
-            BX_DEBUG(("printer init requested"));
-          }
-        } else {
-          if (BX_PAR_THIS s.CONTROL.init == 1) {
-            BX_PAR_THIS s.CONTROL.init = 0;
-          }
-        }
-        if ((value & 0x08) == 0x08) {
-          if (BX_PAR_THIS s.CONTROL.slct_in == 0) {
-            BX_PAR_THIS s.CONTROL.slct_in = 1;
-            BX_DEBUG(("printer now online"));
-          }
-        } else {
-          if (BX_PAR_THIS s.CONTROL.slct_in == 1) {
-            BX_PAR_THIS s.CONTROL.slct_in = 0;
-            BX_DEBUG(("printer now offline"));
-          }
-        }
-        BX_PAR_THIS s.STATUS.slct = BX_PAR_THIS s.CONTROL.slct_in;
-        if ((value & 0x10) == 0x10) {
-          if (BX_PAR_THIS s.CONTROL.irq == 0) {
-            BX_PAR_THIS s.CONTROL.irq = 1;
-            BX_DEBUG(("irq mode selected"));
-          }
-        } else {
-          if (BX_PAR_THIS s.CONTROL.irq == 1) {
-            BX_PAR_THIS s.CONTROL.irq = 0;
-            BX_DEBUG(("polling mode selected"));
-          }
-        }
-        if ((value & 0x20) == 0x20) {
-          if (BX_PAR_THIS s.CONTROL.input == 0) {
-            BX_PAR_THIS s.CONTROL.input = 1;
-            BX_DEBUG(("data input mode selected"));
-          }
-        } else {
-          if (BX_PAR_THIS s.CONTROL.input == 1) {
-            BX_PAR_THIS s.CONTROL.input = 0;
-            BX_DEBUG(("data output mode selected"));
-          }
-        }
-        if ((value & 0xC0) > 0) {
-          BX_ERROR(("write: unsupported control bit ignored"));
-        }
-      }
-      break;
-  }
-}
diff --git a/tools/ioemu/iodev/parallel.h b/tools/ioemu/iodev/parallel.h
deleted file mode 100644 (file)
index b4a256a..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: parallel.h,v 1.11 2002/10/25 11:44:40 bdenney Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2001  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-#if BX_USE_PAR_SMF
-#  define BX_PAR_SMF  static
-#  define BX_PAR_THIS theParallelDevice->
-#else
-#  define BX_PAR_SMF
-#  define BX_PAR_THIS this->
-#endif
-
-typedef struct {
-  Bit8u data;
-  struct {
-    bx_bool error;
-    bx_bool slct;
-    bx_bool pe;
-    bx_bool ack;
-    bx_bool busy;
-  } STATUS;
-  struct {
-    bx_bool strobe;
-    bx_bool autofeed;
-    bx_bool init;
-    bx_bool slct_in;
-    bx_bool irq;
-    bx_bool input;
-  } CONTROL;
-  FILE *output;
-  bx_bool initmode;
-} bx_par_t;
-
-
-
-class bx_parallel_c : public bx_devmodel_c {
-public:
-
-  bx_parallel_c(void);
-  ~bx_parallel_c(void);
-  virtual void   init(void);
-  virtual void   reset(unsigned type);
-
-private:
-  bx_par_t s;
-
-  static void   virtual_printer();
-
-  static Bit32u read_handler(void *this_ptr, Bit32u address, unsigned io_len);
-  static void   write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);
-#if !BX_USE_PAR_SMF
-  Bit32u read(Bit32u address, unsigned io_len);
-  void   write(Bit32u address, Bit32u value, unsigned io_len);
-#endif
-  };
diff --git a/tools/ioemu/iodev/pc_system.cc b/tools/ioemu/iodev/pc_system.cc
deleted file mode 100644 (file)
index de34d99..0000000
+++ /dev/null
@@ -1,570 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: pc_system.cc,v 1.34 2003/06/07 19:16:51 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-
-#include "bochs.h"
-#define LOG_THIS bx_pc_system.
-
-#ifdef WIN32
-#ifndef __MINGW32__
-// #include <winsock2.h> // +++
-#include <winsock.h>
-#endif
-#endif
-
-#if BX_SHOW_IPS
-unsigned long ips_count=0;
-#endif
-
-#if defined(PROVIDE_M_IPS)
-double     m_ips; // Millions of Instructions Per Second
-#endif
-
-#ifdef BX_USE_VMX
-unsigned int tsc_per_bx_tick;
-#endif
-
-// Option for turning off BX_TIMER_DEBUG?
-// Check out m_ips and ips
-
-#define SpewPeriodicTimerInfo 0
-#define MinAllowableTimerPeriod 1
-
-
-#if SpewPeriodicTimerInfo
-// If debugging, set the heartbeat to 5M cycles.  Each heartbeat
-// spews the active timer info.
-const Bit64u bx_pc_system_c::NullTimerInterval = 5000000;
-#else
-// This must be the maximum 32-bit unsigned int value, NOT (Bit64u) -1.
-const Bit64u bx_pc_system_c::NullTimerInterval = 0xffffffff;
-#endif
-
-  // constructor
-bx_pc_system_c::bx_pc_system_c(void)
-{
-  this->put("SYS");
-
-  // Timer[0] is the null timer.  It is initialized as a special
-  // case here.  It should never be turned off or modified, and its
-  // duration should always remain the same.
-  ticksTotal = 0; // Reset ticks since emulator started.
-  timer[0].period     = NullTimerInterval;
-  timer[0].timeToFire = ticksTotal + NullTimerInterval;
-  timer[0].active     = 1;
-  timer[0].continuous = 1;
-  timer[0].funct      = nullTimer;
-  timer[0].this_ptr   = this;
-  currCountdown       = NullTimerInterval;
-  currCountdownPeriod = NullTimerInterval;
-  numTimers = 1; // So far, only the nullTimer.
-  lastTimeUsec = 0;
-  usecSinceLast = 0;
-}
-
-  void
-bx_pc_system_c::init_ips(Bit32u ips)
-{
-  HRQ = 0;
-
-  enable_a20 = 1;
-  //set_INTR (0);
-
-#if BX_CPU_LEVEL < 2
-  a20_mask   =    0xfffff;
-#elif BX_CPU_LEVEL == 2
-  a20_mask   =   0xffffff;
-#else /* 386+ */
-  a20_mask   = 0xffffffff;
-#endif
-
-#ifdef BX_USE_VMX
-  Bit64u phy_cpu_freq = cpu_calibrate_ticks();
-  if (ips == 500000) {  //default ips: we use fixed scaling factor to calulate ips
-    tsc_per_bx_tick = 2000;
-    ips = phy_cpu_freq / tsc_per_bx_tick;
-  } else  //use uesr defined ips to calulate factor
-    tsc_per_bx_tick = ((phy_cpu_freq + (ips>>1)) / ips);
-#endif
-
-  // parameter 'ips' is the processor speed in Instructions-Per-Second
-  m_ips = double(ips) / 1000000.0L;
-
-  BX_DEBUG(("ips = %u", (unsigned) ips));
-}
-
-  void
-bx_pc_system_c::set_HRQ(bx_bool val)
-{
-  HRQ = val;
-  if (val)
-    BX_CPU(0)->async_event = 1;
-}
-
-
-#if (BX_NUM_SIMULATORS < 2)
-  void
-bx_pc_system_c::set_INTR(bx_bool value)
-{
-  if (bx_dbg.interrupts)
-    BX_INFO(("pc_system: Setting INTR=%d on bootstrap processor %d", (int)value, BX_BOOTSTRAP_PROCESSOR));
-  //INTR = value;
-  BX_CPU(BX_BOOTSTRAP_PROCESSOR)->set_INTR(value);
-}
-#endif
-
-//
-// Read from the IO memory address space
-//
-
-  Bit32u BX_CPP_AttrRegparmN(2)
-bx_pc_system_c::inp(Bit16u addr, unsigned io_len)
-{
-  Bit32u ret;
-
-  ret = bx_devices.inp(addr, io_len);
-
-  return( ret );
-}
-
-
-//
-// Write to the IO memory address space.
-//
-
-  void BX_CPP_AttrRegparmN(3)
-bx_pc_system_c::outp(Bit16u addr, Bit32u value, unsigned io_len)
-{
-  bx_devices.outp(addr, value, io_len);
-}
-
-  void BX_CPP_AttrRegparmN(1)
-bx_pc_system_c::set_enable_a20(Bit8u value)
-{
-#if BX_CPU_LEVEL < 2
-    BX_PANIC(("set_enable_a20() called: 8086 emulation"));
-#else
-
-#if BX_SUPPORT_A20
-  unsigned old_enable_a20 = enable_a20;
-
-  if (value) {
-    enable_a20 = 1;
-#if BX_CPU_LEVEL == 2
-    a20_mask   = 0xffffff;   /* 286: enable all 24 address lines */
-#else /* 386+ */
-    a20_mask   = 0xffffffff; /* 386: enable all 32 address lines */
-#endif
-    }
-  else {
-    enable_a20 = 0;
-    a20_mask   = 0xffefffff;   /* mask off A20 address line */
-    }
-
-  BX_DBG_A20_REPORT(value);
-
-  BX_DEBUG(("A20: set() = %u", (unsigned) enable_a20));
-
-  // If there has been a transition, we need to notify the CPUs so
-  // they can potentially invalidate certain cache info based on
-  // A20-line-applied physical addresses.
-  if (old_enable_a20 != enable_a20) {
-    for (unsigned i=0; i<BX_SMP_PROCESSORS; i++)
-      BX_CPU(i)->pagingA20Changed();
-    }
-#else
-  BX_DEBUG(("set_enable_a20: ignoring: SUPPORT_A20 = 0"));
-#endif  // #if BX_SUPPORT_A20
-
-#endif
-}
-
-  bx_bool
-bx_pc_system_c::get_enable_a20(void)
-{
-#if BX_SUPPORT_A20
-  if (bx_dbg.a20)
-    BX_INFO(("A20: get() = %u", (unsigned) enable_a20));
-
-  if (enable_a20) return(1);
-  else return(0);
-#else
-  BX_INFO(("get_enable_a20: ignoring: SUPPORT_A20 = 0"));
-  return(1);
-#endif  // #if BX_SUPPORT_A20
-}
-
-  int
-bx_pc_system_c::ResetSignal( PCS_OP operation )
-{
-  UNUSED( operation );
-  // Reset the processor.
-
-  BX_ERROR(( "# bx_pc_system_c::ResetSignal() called" ));
-  for (int i=0; i<BX_SMP_PROCESSORS; i++)
-    BX_CPU(i)->reset(BX_RESET_SOFTWARE);
-  DEV_reset_devices(BX_RESET_SOFTWARE);
-  return(0);
-}
-
-
-  Bit8u
-bx_pc_system_c::IAC(void)
-{
-  return( DEV_pic_iac() );
-}
-
-  void
-bx_pc_system_c::exit(void)
-{
-  if (DEV_hd_present())
-    DEV_hd_close_harddrive();
-
-  BX_INFO(("Last time is %u", (unsigned) DEV_cmos_get_timeval()));
-
-  if (bx_gui) bx_gui->exit();
-}
-
-
-// ================================================
-// Bochs internal timer delivery framework features
-// ================================================
-
-  int
-bx_pc_system_c::register_timer( void *this_ptr, void (*funct)(void *),
-  Bit32u useconds, bx_bool continuous, bx_bool active, const char *id)
-{
-  Bit64u ticks;
-
-  // Convert useconds to number of ticks.
-  ticks = (Bit64u) (double(useconds) * m_ips);
-
-  return register_timer_ticks(this_ptr, funct, ticks, continuous, active, id);
-}
-
-  int
-bx_pc_system_c::register_timer_ticks(void* this_ptr, bx_timer_handler_t funct,
-    Bit64u ticks, bx_bool continuous, bx_bool active, const char *id)
-{
-  unsigned i;
-
-#if BX_TIMER_DEBUG
-  if (numTimers >= BX_MAX_TIMERS) {
-    BX_PANIC(("register_timer: too many registered timers."));
-    }
-  if (this_ptr == NULL)
-    BX_PANIC(("register_timer_ticks: this_ptr is NULL"));
-  if (funct == NULL)
-    BX_PANIC(("register_timer_ticks: funct is NULL"));
-#endif
-
-  // If the timer frequency is rediculously low, make it more sane.
-  // This happens when 'ips' is too low.
-  if (ticks < MinAllowableTimerPeriod) {
-    //BX_INFO(("register_timer_ticks: adjusting ticks of %llu to min of %u",
-    //          ticks, MinAllowableTimerPeriod));
-    ticks = MinAllowableTimerPeriod;
-    }
-
-  for (i=0; i < numTimers; i++) {
-    if (timer[i].inUse == 0)
-      break;
-    }
-
-  timer[i].inUse      = 1;
-  timer[i].period     = ticks;
-  timer[i].timeToFire = (ticksTotal + Bit64u(currCountdownPeriod-currCountdown)) +
-                        ticks;
-  timer[i].active     = active;
-  timer[i].continuous = continuous;
-  timer[i].funct      = funct;
-  timer[i].this_ptr   = this_ptr;
-  strncpy(timer[i].id, id, BxMaxTimerIDLen);
-  timer[i].id[BxMaxTimerIDLen-1] = 0; // Null terminate if not already.
-
-  if (active) {
-    if (ticks < Bit64u(currCountdown)) {
-      // This new timer needs to fire before the current countdown.
-      // Skew the current countdown and countdown period to be smaller
-      // by the delta.
-      currCountdownPeriod -= (currCountdown - Bit32u(ticks));
-      currCountdown = Bit32u(ticks);
-      }
-    }
-
-  // If we didn't find a free slot, increment the bound, numTimers.
-  if (i==numTimers)
-    numTimers++; // One new timer installed.
-
-  // Return timer id.
-  return(i);
-}
-
-
-  void
-bx_pc_system_c::countdownEvent(void)
-{
-  unsigned i;
-  Bit64u   minTimeToFire;
-  bx_bool  triggered[BX_MAX_TIMERS];
-
-  // The countdown decremented to 0.  We need to service all the active
-  // timers, and invoke callbacks from those timers which have fired.
-#if BX_TIMER_DEBUG
-  if (currCountdown != 0)
-    BX_PANIC(("countdownEvent: ticks!=0"));
-#endif
-
-  // Increment global ticks counter by number of ticks which have
-  // elapsed since the last update.
-  ticksTotal += Bit64u(currCountdownPeriod);
-  minTimeToFire = (Bit64u) -1;
-
-  for (i=0; i < numTimers; i++) {
-    triggered[i] = 0; // Reset triggered flag.
-    if (timer[i].active) {
-#if BX_TIMER_DEBUG
-      if (ticksTotal > timer[i].timeToFire)
-        BX_PANIC(("countdownEvent: ticksTotal > timeToFire[%u], D " FMT_LL "u", i,
-                  timer[i].timeToFire-ticksTotal));
-#endif
-      if (ticksTotal == timer[i].timeToFire) {
-        // This timer is ready to fire.
-        triggered[i] = 1;
-
-        if (timer[i].continuous==0) {
-          // If triggered timer is one-shot, deactive.
-          timer[i].active = 0;
-          }
-        else {
-          // Continuous timer, increment time-to-fire by period.
-          timer[i].timeToFire += timer[i].period;
-          if (timer[i].timeToFire < minTimeToFire)
-            minTimeToFire = timer[i].timeToFire;
-          }
-        }
-      else {
-        // This timer is not ready to fire yet.
-        if (timer[i].timeToFire < minTimeToFire)
-          minTimeToFire = timer[i].timeToFire;
-        }
-      }
-    }
-
-  // Calculate next countdown period.  We need to do this before calling
-  // any of the callbacks, as they may call timer features, which need
-  // to be advanced to the next countdown cycle.
-  currCountdown = currCountdownPeriod =
-      Bit32u(minTimeToFire - ticksTotal);
-
-  for (i=0; i < numTimers; i++) {
-    // Call requested timer function.  It may request a different
-    // timer period or deactivate etc.
-    if (triggered[i]) {
-      timer[i].funct(timer[i].this_ptr);
-      }
-    }
-}
-
-  void
-bx_pc_system_c::nullTimer(void* this_ptr)
-{
-  // This function is always inserted in timer[0].  It is sort of
-  // a heartbeat timer.  It ensures that at least one timer is
-  // always active to make the timer logic more simple, and has
-  // a duration of less than the maximum 32-bit integer, so that
-  // a 32-bit size can be used for the hot countdown timer.  The
-  // rest of the timer info can be 64-bits.  This is also a good
-  // place for some logic to report actual emulated
-  // instructions-per-second (IPS) data when measured relative to
-  // the host computer's wall clock.
-
-  UNUSED(this_ptr);
-
-#if SpewPeriodicTimerInfo
-  BX_INFO(("==================================="));
-  for (unsigned i=0; i < bx_pc_system.numTimers; i++) {
-    if (bx_pc_system.timer[i].active) {
-      BX_INFO(("BxTimer(%s): period=" FMT_LL "u, continuous=%u",
-               bx_pc_system.timer[i].id, bx_pc_system.timer[i].period,
-               bx_pc_system.timer[i].continuous));
-      }
-    }
-#endif
-}
-
-#if BX_DEBUGGER
-  void
-bx_pc_system_c::timebp_handler(void* this_ptr)
-{
-      BX_CPU(0)->break_point = BREAK_POINT_TIME;
-      BX_DEBUG(( "Time breakpoint triggered" ));
-
-      if (timebp_queue_size > 1) {
-           Bit64s new_diff = timebp_queue[1] - bx_pc_system.time_ticks();
-           bx_pc_system.activate_timer_ticks(timebp_timer, new_diff, 1);
-      }
-      timebp_queue_size--;
-      for (int i = 0; i < timebp_queue_size; i++)
-           timebp_queue[i] = timebp_queue[i+1];
-}
-#endif // BX_DEBUGGER
-
-  Bit64u
-bx_pc_system_c::time_usec_sequential() {
-    Bit64u this_time_usec = time_usec();
-    if(this_time_usec != lastTimeUsec) {
-      Bit64u diff_usec = this_time_usec-lastTimeUsec;
-      lastTimeUsec = this_time_usec;
-      if(diff_usec >= usecSinceLast) {
-       usecSinceLast = 0;
-      } else {
-       usecSinceLast -= diff_usec;
-      }
-    }
-    usecSinceLast++;
-    return (this_time_usec+usecSinceLast);
-}
-  Bit64u
-bx_pc_system_c::time_usec() {
-  return (Bit64u) (((double)(Bit64s)time_ticks()) / m_ips );
-}
-
-  void
-bx_pc_system_c::start_timers(void)
-{
-}
-
-  void
-bx_pc_system_c::activate_timer_ticks(unsigned i, Bit64u ticks, bx_bool continuous)
-{
-#if BX_TIMER_DEBUG
-  if (i >= numTimers)
-    BX_PANIC(("activate_timer_ticks: timer %u OOB", i));
-  if (timer[i].period < MinAllowableTimerPeriod)
-    BX_PANIC(("activate_timer_ticks: timer[%u].period of " FMT_LL "u < min of %u",
-              i, timer[i].period, MinAllowableTimerPeriod));
-#endif
-
-  // If the timer frequency is rediculously low, make it more sane.
-  // This happens when 'ips' is too low.
-  if (ticks < MinAllowableTimerPeriod) {
-    //BX_INFO(("activate_timer_ticks: adjusting ticks of %llu to min of %u",
-    //          ticks, MinAllowableTimerPeriod));
-    ticks = MinAllowableTimerPeriod;
-    }
-
-  timer[i].period = ticks;
-  timer[i].timeToFire = (ticksTotal + Bit64u(currCountdownPeriod-currCountdown)) +
-                        ticks;
-  timer[i].active     = 1;
-  timer[i].continuous = continuous;
-
-  if (ticks < Bit64u(currCountdown)) {
-    // This new timer needs to fire before the current countdown.
-    // Skew the current countdown and countdown period to be smaller
-    // by the delta.
-    currCountdownPeriod -= (currCountdown - Bit32u(ticks));
-    currCountdown = Bit32u(ticks);
-    }
-}
-
-  void
-bx_pc_system_c::activate_timer(unsigned i, Bit32u useconds, bx_bool continuous)
-{
-  Bit64u ticks;
-
-#if BX_TIMER_DEBUG
-  if (i >= numTimers)
-    BX_PANIC(("activate_timer: timer %u OOB", i));
-#endif
-
-  // if useconds = 0, use default stored in period field
-  // else set new period from useconds
-  if (useconds==0) {
-    ticks = timer[i].period;
-    }
-  else {
-    // convert useconds to number of ticks
-    ticks = (Bit64u) (double(useconds) * m_ips);
-
-    // If the timer frequency is rediculously low, make it more sane.
-    // This happens when 'ips' is too low.
-    if (ticks < MinAllowableTimerPeriod) {
-      //BX_INFO(("activate_timer: adjusting ticks of %llu to min of %u",
-      //          ticks, MinAllowableTimerPeriod));
-      ticks = MinAllowableTimerPeriod;
-      }
-
-    timer[i].period = ticks;
-    }
-
-  activate_timer_ticks(i, ticks, continuous);
-}
-
-  void
-bx_pc_system_c::deactivate_timer( unsigned i )
-{
-#if BX_TIMER_DEBUG
-  if (i >= numTimers)
-    BX_PANIC(("deactivate_timer: timer %u OOB", i));
-#endif
-
-  timer[i].active = 0;
-}
-
-  unsigned
-bx_pc_system_c::unregisterTimer(int timerIndex)
-{
-  unsigned i = (unsigned) timerIndex;
-
-#if BX_TIMER_DEBUG
-  if (i >= numTimers)
-    BX_PANIC(("unregisterTimer: timer %u OOB", i));
-  if (i == 0)
-    BX_PANIC(("unregisterTimer: timer 0 is the nullTimer!"));
-  if (timer[i].inUse == 0)
-    BX_PANIC(("unregisterTimer: timer %u is not in-use!", i));
-#endif
-
-  if (timer[i].active) {
-    BX_PANIC(("unregisterTimer: timer '%s' is still active!", timer[i].id));
-    return(0); // Fail.
-    }
-
-  // Reset timer fields for good measure.
-  timer[i].inUse      = 0; // No longer registered.
-  timer[i].period     = BX_MAX_BIT64S; // Max value (invalid)
-  timer[i].timeToFire = BX_MAX_BIT64S; // Max value (invalid)
-  timer[i].continuous = 0;
-  timer[i].funct      = NULL;
-  timer[i].this_ptr   = NULL;
-  memset(timer[i].id, 0, BxMaxTimerIDLen);
-
-  return(1); // OK
-}
diff --git a/tools/ioemu/iodev/pci.cc b/tools/ioemu/iodev/pci.cc
deleted file mode 100644 (file)
index 6dfe5db..0000000
+++ /dev/null
@@ -1,467 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: pci.cc,v 1.29 2003/07/31 19:51:42 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-//
-// i440FX Support - PMC/DBX
-//
-
-// Define BX_PLUGGABLE in files that can be compiled into plugins.  For
-// platforms that require a special tag on exported symbols, BX_PLUGGABLE 
-// is used to know when we are exporting symbols and when we are importing.
-#define BX_PLUGGABLE
-
-#include "bochs.h"
-#if BX_PCI_SUPPORT
-
-#define LOG_THIS thePciBridge->
-
-bx_pci_c *thePciBridge = NULL;
-
-  int
-libpci_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
-{
-  thePciBridge = new bx_pci_c ();
-  bx_devices.pluginPciBridge = thePciBridge;
-  BX_REGISTER_DEVICE_DEVMODEL(plugin, type, thePciBridge, BX_PLUGIN_PCI);
-  return(0); // Success
-}
-
-  void
-libpci_LTX_plugin_fini(void)
-{
-}
-
-bx_pci_c::bx_pci_c(void)
-{
-  put("PCI");
-  settype(PCILOG);
-}
-
-bx_pci_c::~bx_pci_c(void)
-{
-  // nothing for now
-  BX_DEBUG(("Exit."));
-}
-
-
-  void
-bx_pci_c::init(void)
-{
-  // called once when bochs initializes
-  unsigned i;
-  BX_PCI_THIS num_pci_handles = 0;
-
-  /* set unused elements to appropriate values */
-  for (i=0; i < BX_MAX_PCI_DEVICES; i++) {
-    BX_PCI_THIS pci_handler[i].read  = NULL;
-    BX_PCI_THIS pci_handler[i].write = NULL;
-    }
-
-  for (i=0; i < 0x100; i++) {
-    BX_PCI_THIS pci_handler_id[i] = BX_MAX_PCI_DEVICES;  // not assigned
-  }
-
-  // confAddr accepts dword i/o only
-  DEV_register_ioread_handler(this, read_handler, 0x0CF8, "i440FX", 4);
-  DEV_register_iowrite_handler(this, write_handler, 0x0CF8, "i440FX", 4);
-
-  for (i=0x0CFC; i<=0x0CFF; i++) {
-    DEV_register_ioread_handler(this, read_handler, i, "i440FX", 7);
-  }
-  for (i=0x0CFC; i<=0x0CFF; i++) {
-    DEV_register_iowrite_handler(this, write_handler, i, "i440FX", 7);
-  }
-
-  DEV_register_pci_handlers(this, pci_read_handler, pci_write_handler,
-                            BX_PCI_DEVICE(0,0), "440FX Host bridge");
-
-  for (i=0; i<256; i++)
-    BX_PCI_THIS s.i440fx.pci_conf[i] = 0x0;
-  // readonly registers
-  BX_PCI_THIS s.i440fx.pci_conf[0x00] = 0x86;
-  BX_PCI_THIS s.i440fx.pci_conf[0x01] = 0x80;
-  BX_PCI_THIS s.i440fx.pci_conf[0x02] = 0x37;
-  BX_PCI_THIS s.i440fx.pci_conf[0x03] = 0x12;
-  BX_PCI_THIS s.i440fx.pci_conf[0x0b] = 0x06;
-}
-
-  void
-bx_pci_c::reset(unsigned type)
-{
-  BX_PCI_THIS s.i440fx.confAddr = 0;
-  BX_PCI_THIS s.i440fx.confData = 0;
-
-  BX_PCI_THIS s.i440fx.pci_conf[0x04] = 0x06;
-  BX_PCI_THIS s.i440fx.pci_conf[0x05] = 0x00;
-  BX_PCI_THIS s.i440fx.pci_conf[0x06] = 0x80;
-  BX_PCI_THIS s.i440fx.pci_conf[0x07] = 0x02;
-  BX_PCI_THIS s.i440fx.pci_conf[0x0d] = 0x00;
-  BX_PCI_THIS s.i440fx.pci_conf[0x0f] = 0x00;
-  BX_PCI_THIS s.i440fx.pci_conf[0x50] = 0x00;
-  BX_PCI_THIS s.i440fx.pci_conf[0x51] = 0x01;
-  BX_PCI_THIS s.i440fx.pci_conf[0x52] = 0x00;
-  BX_PCI_THIS s.i440fx.pci_conf[0x53] = 0x80;
-  BX_PCI_THIS s.i440fx.pci_conf[0x54] = 0x00;
-  BX_PCI_THIS s.i440fx.pci_conf[0x55] = 0x00;
-  BX_PCI_THIS s.i440fx.pci_conf[0x56] = 0x00;
-  BX_PCI_THIS s.i440fx.pci_conf[0x57] = 0x01;
-  BX_PCI_THIS s.i440fx.pci_conf[0x58] = 0x10;
-  for (unsigned i=0x59; i<0x60; i++)
-    BX_PCI_THIS s.i440fx.pci_conf[i] = 0x00;
-}
-
-
-
-  // static IO port read callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-  Bit32u
-bx_pci_c::read_handler(void *this_ptr, Bit32u address, unsigned io_len)
-{
-#if !BX_USE_PCI_SMF
-  bx_pci_c *class_ptr = (bx_pci_c *) this_ptr;
-
-  return( class_ptr->read(address, io_len) );
-}
-
-
-  Bit32u
-bx_pci_c::read(Bit32u address, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif // !BX_USE_PCI_SMF
-
-  switch (address) {
-    case 0x0CF8:
-      {
-        return BX_PCI_THIS s.i440fx.confAddr;
-      }
-      break;
-    case 0x0CFC:
-    case 0x0CFD:
-    case 0x0CFE:
-    case 0x0CFF:
-      {
-      Bit32u handle, retval;
-      Bit8u devfunc, regnum;
-
-      if ((BX_PCI_THIS s.i440fx.confAddr & 0x80FF0000) == 0x80000000) {
-        devfunc = (BX_PCI_THIS s.i440fx.confAddr >> 8) & 0xff;
-        regnum = (BX_PCI_THIS s.i440fx.confAddr & 0xfc) + (address & 0x03);
-        handle = BX_PCI_THIS pci_handler_id[devfunc];
-        if ((io_len <= 4) && (handle < BX_MAX_PCI_DEVICES))
-          retval = (* BX_PCI_THIS pci_handler[handle].read)
-                     (BX_PCI_THIS pci_handler[handle].this_ptr, regnum, io_len);
-        else
-          retval = 0xFFFFFFFF;
-        }
-      else
-        retval = 0xFFFFFFFF;
-      BX_PCI_THIS s.i440fx.confData = retval;
-      return retval;
-      }
-    }
-
-  BX_PANIC(("unsupported IO read to port 0x%x",
-           (unsigned) address));
-  return(0xffffffff);
-}
-
-
-  // static IO port write callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-  void
-bx_pci_c::write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len)
-{
-#if !BX_USE_PCI_SMF
-  bx_pci_c *class_ptr = (bx_pci_c *) this_ptr;
-
-  class_ptr->write(address, value, io_len);
-}
-
-  void
-bx_pci_c::write(Bit32u address, Bit32u value, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif // !BX_USE_PCI_SMF
-
-  switch (address) {
-    case 0xCF8:
-      {
-        BX_PCI_THIS s.i440fx.confAddr = value;
-        if ((value & 0x80FFFF00) == 0x80000000) {
-          BX_DEBUG(("440FX PMC register 0x%02x selected", value & 0xfc));
-        } else if ((value & 0x80000000) == 0x80000000) {
-          BX_DEBUG(("440FX request for bus 0x%02x device 0x%02x function 0x%02x",
-                    (value >> 16) & 0xFF, (value >> 11) & 0x1F, (value >> 8) & 0x07));
-        }
-      }
-      break;
-
-    case 0xCFC:
-    case 0xCFD:
-    case 0xCFE:
-    case 0xCFF:
-      {
-      Bit32u handle;
-      Bit8u devfunc, regnum;
-
-      if ((BX_PCI_THIS s.i440fx.confAddr & 0x80FF0000) == 0x80000000) {
-        devfunc = (BX_PCI_THIS s.i440fx.confAddr >> 8) & 0xff;
-        regnum = (BX_PCI_THIS s.i440fx.confAddr & 0xfc) + (address & 0x03);
-        handle = BX_PCI_THIS pci_handler_id[devfunc];
-        if ((io_len <= 4) && (handle < BX_MAX_PCI_DEVICES)) {
-          if (((regnum>=4) && (regnum<=7)) || (regnum==12) || (regnum==13) || (regnum>14)) {
-            (* BX_PCI_THIS pci_handler[handle].write)
-               (BX_PCI_THIS pci_handler[handle].this_ptr, regnum, value, io_len);
-            BX_PCI_THIS s.i440fx.confData = value << (8 * (address & 0x03));
-            }
-          else
-            BX_DEBUG(("read only register, write ignored"));
-          }
-        }
-      }
-      break;
-
-    default:
-      BX_PANIC(("IO write to port 0x%x", (unsigned) address));
-    }
-}
-
-
-  // static pci configuration space read callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-  Bit32u
-bx_pci_c::pci_read_handler(void *this_ptr, Bit8u address, unsigned io_len)
-{
-#if !BX_USE_PCI_SMF
-  bx_pci_c *class_ptr = (bx_pci_c *) this_ptr;
-
-  return( class_ptr->pci_read(address, io_len) );
-}
-
-
-  Bit32u
-bx_pci_c::pci_read(Bit8u address, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif // !BX_USE_PCI_SMF
-
-  Bit32u val440fx = 0;
-
-  if (io_len <= 4) {
-    for (unsigned i=0; i<io_len; i++) {
-      val440fx |= (BX_PCI_THIS s.i440fx.pci_conf[address+i] << (i*8));
-    }
-    BX_DEBUG(("440FX PMC read register 0x%02x value 0x%08x", address, val440fx));
-    return val440fx;
-    }
-  else
-    return(0xffffffff);
-}
-
-
-  // static pci configuration space write callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-  void
-bx_pci_c::pci_write_handler(void *this_ptr, Bit8u address, Bit32u value, unsigned io_len)
-{
-#if !BX_USE_PCI_SMF
-  bx_pci_c *class_ptr = (bx_pci_c *) this_ptr;
-
-  class_ptr->pci_write(address, value, io_len);
-}
-
-  void
-bx_pci_c::pci_write(Bit8u address, Bit32u value, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif // !BX_USE_PCI_SMF
-
-  Bit8u value8;
-
-  if (io_len <= 4) {
-    for (unsigned i=0; i<io_len; i++) {
-      value8 = (value >> (i*8)) & 0xFF;
-      switch (address+i) {
-        case 0x06:
-        case 0x0c:
-          break;
-        default:
-          BX_PCI_THIS s.i440fx.pci_conf[address+i] = value8;
-          BX_DEBUG(("440FX PMC write register 0x%02x value 0x%02x", address,
-                    value8));
-        }
-      }
-    }
-}
-
-
-  Bit8u
-bx_pci_c::rd_memType (Bit32u addr)
-{
-   switch ((addr & 0xFC000) >> 12) {
-      case 0xC0:
-           return (BX_PCI_THIS s.i440fx.pci_conf[0x5A] & 0x1);
-      case 0xC4:
-           return ( (BX_PCI_THIS s.i440fx.pci_conf[0x5A] >> 4) & 0x1);
-      case 0xC8:
-           return (BX_PCI_THIS s.i440fx.pci_conf[0x5B] & 0x1);
-      case 0xCC:
-           return ( (BX_PCI_THIS s.i440fx.pci_conf[0x5B] >> 4) & 0x1);
-
-
-      case 0xD0:
-           return (BX_PCI_THIS s.i440fx.pci_conf[0x5C] & 0x1);
-      case 0xD4:
-           return ( (BX_PCI_THIS s.i440fx.pci_conf[0x5C] >> 4) & 0x1);
-      case 0xD8:
-           return (BX_PCI_THIS s.i440fx.pci_conf[0x5D] & 0x1);
-      case 0xDC:
-           return ( (BX_PCI_THIS s.i440fx.pci_conf[0x5D] >> 4) & 0x1);
-
-      case 0xE0:
-           return (BX_PCI_THIS s.i440fx.pci_conf[0x5E] & 0x1);
-      case 0xE4:
-           return ( (BX_PCI_THIS s.i440fx.pci_conf[0x5E] >> 4) & 0x1);
-      case 0xE8:
-           return (BX_PCI_THIS s.i440fx.pci_conf[0x5F] & 0x1);
-      case 0xEC:
-           return ( (BX_PCI_THIS s.i440fx.pci_conf[0x5F] >> 4) & 0x1);
-
-      case 0xF0:
-      case 0xF4:
-      case 0xF8:
-      case 0xFC:
-           return ( (BX_PCI_THIS s.i440fx.pci_conf[0x59] >> 4) & 0x1);
-
-      default:
-           BX_PANIC(("rd_memType () Error: Memory Type not known !"));
-           return(0); // keep compiler happy
-           break;
-   }
-
-}
-
-  Bit8u
-bx_pci_c::wr_memType (Bit32u addr)
-{
-   switch ((addr & 0xFC000) >> 12) {
-      case 0xC0:
-           return ( (BX_PCI_THIS s.i440fx.pci_conf[0x5A] >> 1) & 0x1);
-      case 0xC4:
-           return ( (BX_PCI_THIS s.i440fx.pci_conf[0x5A] >> 5) & 0x1);
-      case 0xC8:
-           return ( (BX_PCI_THIS s.i440fx.pci_conf[0x5B] >> 1) & 0x1);
-      case 0xCC:
-           return ( (BX_PCI_THIS s.i440fx.pci_conf[0x5B] >> 5) & 0x1);
-
-
-      case 0xD0:
-           return ( (BX_PCI_THIS s.i440fx.pci_conf[0x5C] >> 1) & 0x1);
-      case 0xD4:
-           return ( (BX_PCI_THIS s.i440fx.pci_conf[0x5C] >> 5) & 0x1);
-      case 0xD8:
-           return ( (BX_PCI_THIS s.i440fx.pci_conf[0x5D] >> 1) & 0x1);
-      case 0xDC:
-           return ( (BX_PCI_THIS s.i440fx.pci_conf[0x5D] >> 5) & 0x1);
-
-      case 0xE0:
-           return ( (BX_PCI_THIS s.i440fx.pci_conf[0x5E] >> 1) & 0x1);
-      case 0xE4:
-           return ( (BX_PCI_THIS s.i440fx.pci_conf[0x5E] >> 5) & 0x1);
-      case 0xE8:
-           return ( (BX_PCI_THIS s.i440fx.pci_conf[0x5F] >> 1) & 0x1);
-      case 0xEC:
-           return ( (BX_PCI_THIS s.i440fx.pci_conf[0x5F] >> 5) & 0x1);
-
-      case 0xF0:
-      case 0xF4:
-      case 0xF8:
-      case 0xFC:
-           return ( (BX_PCI_THIS s.i440fx.pci_conf[0x59] >> 5) & 0x1);
-
-      default:
-           BX_PANIC(("wr_memType () Error: Memory Type not known !"));
-           return(0); // keep compiler happy
-           break;
-   }
-}
-
-  void
-bx_pci_c::print_i440fx_state()
-{
-  int  i;
-
-  BX_DEBUG(( "i440fxConfAddr:0x%08x", BX_PCI_THIS s.i440fx.confAddr ));
-  BX_DEBUG(( "i440fxConfData:0x%08x", BX_PCI_THIS s.i440fx.confData ));
-
-#ifdef DUMP_FULL_I440FX
-  for (i=0; i<256; i++) {
-    BX_DEBUG(( "i440fxArray%02x:0x%02x", i, BX_PCI_THIS s.i440fx.pci_conf[i] ));
-    }
-#else /* DUMP_FULL_I440FX */
-  for (i=0x59; i<0x60; i++) {
-    BX_DEBUG(( "i440fxArray%02x:0x%02x", i, BX_PCI_THIS s.i440fx.pci_conf[i] ));
-    }
-#endif /* DUMP_FULL_I440FX */
-}
-
-  bx_bool
-bx_pci_c::register_pci_handlers( void *this_ptr, bx_pci_read_handler_t f1,
-                                 bx_pci_write_handler_t f2, Bit8u devfunc,
-                                 const char *name)
-{
-  unsigned handle;
-
-  /* first check if device/function is available */
-  if (BX_PCI_THIS pci_handler_id[devfunc] == BX_MAX_PCI_DEVICES) {
-    if (BX_PCI_THIS num_pci_handles >= BX_MAX_PCI_DEVICES) {
-      BX_INFO(("too many PCI devices installed."));
-      BX_PANIC(("  try increasing BX_MAX_PCI_DEVICES"));
-      return false;
-      }
-    handle = BX_PCI_THIS num_pci_handles++;
-    BX_PCI_THIS pci_handler[handle].read  = f1;
-    BX_PCI_THIS pci_handler[handle].write = f2;
-    BX_PCI_THIS pci_handler[handle].this_ptr = this_ptr;
-    BX_PCI_THIS pci_handler_id[devfunc] = handle;
-    BX_INFO(("%s present at device %d, function %d", name, devfunc >> 3,
-             devfunc & 0x07));
-    return true; // device/function mapped successfully
-    }
-  else {
-    return false; // device/function not available, return false.
-    }
-}
-#endif /* BX_PCI_SUPPORT */
diff --git a/tools/ioemu/iodev/pci.h b/tools/ioemu/iodev/pci.h
deleted file mode 100644 (file)
index 92e7bee..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: pci.h,v 1.14 2003/01/23 19:31:27 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-#define BX_MAX_PCI_DEVICES 20
-
-#define BX_PCI_DEVICE(device, function) ((device)<<3 | (function))
-
-typedef Bit32u (*bx_pci_read_handler_t)(void *, Bit8u, unsigned);
-typedef void   (*bx_pci_write_handler_t)(void *, Bit8u, Bit32u, unsigned);
-
-#if BX_USE_PCI_SMF
-#  define BX_PCI_SMF  static
-#  define BX_PCI_THIS thePciBridge->
-#else
-#  define BX_PCI_SMF
-#  define BX_PCI_THIS this->
-#endif
-
-
-typedef struct {
-  Bit32u confAddr;
-  Bit32u confData;
-  Bit8u  pci_conf[256];
-  } bx_def440fx_t;
-
-
-
-class bx_pci_c : public bx_pci_stub_c {
-
-public:
-  bx_pci_c(void);
-  ~bx_pci_c(void);
-  virtual void   init(void);
-  virtual void   reset(unsigned type);
-  virtual bx_bool register_pci_handlers(void *this_ptr,
-                                        bx_pci_read_handler_t f1,
-                                        bx_pci_write_handler_t f2,
-                                        Bit8u devfunc, const char *name);
-  virtual void   print_i440fx_state(void);
-  virtual Bit8u rd_memType (Bit32u addr);
-  virtual Bit8u wr_memType (Bit32u addr);
-
-private:
-  Bit8u pci_handler_id[0x100];  // 256 devices/functions
-  struct {
-    bx_pci_read_handler_t  read;
-    bx_pci_write_handler_t write;
-    void             *this_ptr;
-    } pci_handler[BX_MAX_PCI_DEVICES];
-  unsigned num_pci_handles;
-
-  struct {
-    bx_def440fx_t i440fx;
-    } s;
-
-  static Bit32u read_handler(void *this_ptr, Bit32u address, unsigned io_len);
-  static void   write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);
-  static Bit32u pci_read_handler(void *this_ptr, Bit8u address, unsigned io_len);
-  static void   pci_write_handler(void *this_ptr, Bit8u address, Bit32u value, unsigned io_len);
-#if !BX_USE_PCI_SMF
-  Bit32u read(Bit32u address, unsigned io_len);
-  void   write(Bit32u address, Bit32u value, unsigned io_len);
-  Bit32u pci_read(Bit8u address, unsigned io_len);
-  void   pci_write(Bit8u address, Bit32u value, unsigned io_len);
-#endif
-  };
diff --git a/tools/ioemu/iodev/pci2isa.cc b/tools/ioemu/iodev/pci2isa.cc
deleted file mode 100644 (file)
index 54c3bc4..0000000
+++ /dev/null
@@ -1,294 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: pci2isa.cc,v 1.10 2003/07/31 19:51:42 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-//
-// i440FX Support - PCI-to-ISA bridge (PIIX3)
-//
-
-// Define BX_PLUGGABLE in files that can be compiled into plugins.  For
-// platforms that require a special tag on exported symbols, BX_PLUGGABLE 
-// is used to know when we are exporting symbols and when we are importing.
-#define BX_PLUGGABLE
-
-#include "bochs.h"
-#if BX_PCI_SUPPORT
-
-#define LOG_THIS thePci2IsaBridge->
-
-bx_pci2isa_c *thePci2IsaBridge = NULL;
-
-  int
-libpci2isa_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
-{
-  thePci2IsaBridge = new bx_pci2isa_c ();
-  bx_devices.pluginPci2IsaBridge = thePci2IsaBridge;
-  BX_REGISTER_DEVICE_DEVMODEL(plugin, type, thePci2IsaBridge, BX_PLUGIN_PCI2ISA);
-  return(0); // Success
-}
-
-  void
-libpci2isa_LTX_plugin_fini(void)
-{
-}
-
-bx_pci2isa_c::bx_pci2isa_c(void)
-{
-  put("P2I");
-  settype(PCI2ISALOG);
-}
-
-bx_pci2isa_c::~bx_pci2isa_c(void)
-{
-  // nothing for now
-  BX_DEBUG(("Exit."));
-}
-
-
-  void
-bx_pci2isa_c::init(void)
-{
-  // called once when bochs initializes
-
-  DEV_register_pci_handlers(this, pci_read_handler, pci_write_handler,
-                            BX_PCI_DEVICE(1,0), "PIIX3 PCI-to-ISA bridge");
-
-  DEV_register_iowrite_handler(this, write_handler, 0x00B2, "PIIX3 PCI-to-ISA bridge", 1);
-  DEV_register_iowrite_handler(this, write_handler, 0x00B3, "PIIX3 PCI-to-ISA bridge", 1);
-  DEV_register_iowrite_handler(this, write_handler, 0x04D0, "PIIX3 PCI-to-ISA bridge", 1);
-  DEV_register_iowrite_handler(this, write_handler, 0x04D1, "PIIX3 PCI-to-ISA bridge", 1);
-  DEV_register_iowrite_handler(this, write_handler, 0x0CF9, "PIIX3 PCI-to-ISA bridge", 1);
-
-  DEV_register_ioread_handler(this, read_handler, 0x00B2, "PIIX3 PCI-to-ISA bridge", 1);
-  DEV_register_ioread_handler(this, read_handler, 0x00B3, "PIIX3 PCI-to-ISA bridge", 1);
-  DEV_register_ioread_handler(this, read_handler, 0x04D0, "PIIX3 PCI-to-ISA bridge", 1);
-  DEV_register_ioread_handler(this, read_handler, 0x04D1, "PIIX3 PCI-to-ISA bridge", 1);
-  DEV_register_ioread_handler(this, read_handler, 0x0CF9, "PIIX3 PCI-to-ISA bridge", 1);
-
-  for (unsigned i=0; i<256; i++)
-    BX_P2I_THIS s.pci_conf[i] = 0x0;
-  // readonly registers
-  BX_P2I_THIS s.pci_conf[0x00] = 0x86;
-  BX_P2I_THIS s.pci_conf[0x01] = 0x80;
-  BX_P2I_THIS s.pci_conf[0x02] = 0x00;
-  BX_P2I_THIS s.pci_conf[0x03] = 0x70;
-  BX_P2I_THIS s.pci_conf[0x0a] = 0x01;
-  BX_P2I_THIS s.pci_conf[0x0b] = 0x06;
-  BX_P2I_THIS s.pci_conf[0x0e] = 0x80;
-}
-
-  void
-bx_pci2isa_c::reset(unsigned type)
-{
-  BX_P2I_THIS s.pci_conf[0x04] = 0x07;
-  BX_P2I_THIS s.pci_conf[0x05] = 0x00;
-  BX_P2I_THIS s.pci_conf[0x06] = 0x00;
-  BX_P2I_THIS s.pci_conf[0x07] = 0x02;
-  BX_P2I_THIS s.pci_conf[0x4c] = 0x4d;
-  BX_P2I_THIS s.pci_conf[0x4e] = 0x03;
-  BX_P2I_THIS s.pci_conf[0x4f] = 0x00;
-  BX_P2I_THIS s.pci_conf[0x60] = 0x80;
-  BX_P2I_THIS s.pci_conf[0x69] = 0x02;
-  BX_P2I_THIS s.pci_conf[0x70] = 0x80;
-  BX_P2I_THIS s.pci_conf[0x76] = 0x0c;
-  BX_P2I_THIS s.pci_conf[0x77] = 0x0c;
-  BX_P2I_THIS s.pci_conf[0x78] = 0x02;
-  BX_P2I_THIS s.pci_conf[0x79] = 0x00;
-  BX_P2I_THIS s.pci_conf[0x80] = 0x00;
-  BX_P2I_THIS s.pci_conf[0x82] = 0x00;
-  BX_P2I_THIS s.pci_conf[0xa0] = 0x08;
-  BX_P2I_THIS s.pci_conf[0xa0] = 0x08;
-  BX_P2I_THIS s.pci_conf[0xa2] = 0x00;
-  BX_P2I_THIS s.pci_conf[0xa3] = 0x00;
-  BX_P2I_THIS s.pci_conf[0xa4] = 0x00;
-  BX_P2I_THIS s.pci_conf[0xa5] = 0x00;
-  BX_P2I_THIS s.pci_conf[0xa6] = 0x00;
-  BX_P2I_THIS s.pci_conf[0xa7] = 0x00;
-  BX_P2I_THIS s.pci_conf[0xa8] = 0x0f;
-  BX_P2I_THIS s.pci_conf[0xaa] = 0x00;
-  BX_P2I_THIS s.pci_conf[0xab] = 0x00;
-  BX_P2I_THIS s.pci_conf[0xac] = 0x00;
-  BX_P2I_THIS s.pci_conf[0xae] = 0x00;
-
-  BX_P2I_THIS s.elcr1 = 0x00;
-  BX_P2I_THIS s.elcr2 = 0x00;
-}
-
-
-
-  // static IO port read callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-  Bit32u
-bx_pci2isa_c::read_handler(void *this_ptr, Bit32u address, unsigned io_len)
-{
-#if !BX_USE_P2I_SMF
-  bx_pci2isa_c *class_ptr = (bx_pci2isa_c *) this_ptr;
-
-  return( class_ptr->read(address, io_len) );
-}
-
-
-  Bit32u
-bx_pci2isa_c::read(Bit32u address, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif // !BX_USE_P2I_SMF
-
-  switch (address) {
-    case 0x00b2:
-      BX_ERROR(("read: APM command register not supported yet"));
-      break;
-    case 0x00b3:
-      BX_ERROR(("read: APM status register not supported yet"));
-      break;
-    case 0x04d0:
-      return(BX_P2I_THIS s.elcr1);
-      break;
-    case 0x04d1:
-      return(BX_P2I_THIS s.elcr2);
-      break;
-    case 0x0cf9:
-      BX_ERROR(("read: CPU reset register not supported yet"));
-      break;
-    }
-
-  return(0xffffffff);
-}
-
-
-  // static IO port write callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-  void
-bx_pci2isa_c::write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len)
-{
-#if !BX_USE_P2I_SMF
-  bx_pci2isa_c *class_ptr = (bx_pci2isa_c *) this_ptr;
-
-  class_ptr->write(address, value, io_len);
-}
-
-  void
-bx_pci2isa_c::write(Bit32u address, Bit32u value, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif // !BX_USE_P2I_SMF
-
-  switch (address) {
-    case 0x00b2:
-      BX_ERROR(("write: APM command register not supported yet"));
-      break;
-    case 0x00b3:
-      BX_ERROR(("write: APM status register not supported yet"));
-      break;
-    case 0x04d0:
-      BX_P2I_THIS s.elcr1 = (value & 0xf8);
-      BX_ERROR(("write: ELCR1 changes have no effect yet"));
-      break;
-    case 0x04d1:
-      BX_P2I_THIS s.elcr2 = (value & 0xde);
-      BX_ERROR(("write: ELCR2 changes have no effect yet"));
-      break;
-    case 0x0cf9:
-      BX_ERROR(("write: CPU reset register not supported yet"));
-      break;
-    }
-}
-
-
-  // static pci configuration space read callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-  Bit32u
-bx_pci2isa_c::pci_read_handler(void *this_ptr, Bit8u address, unsigned io_len)
-{
-#if !BX_USE_P2I_SMF
-  bx_pci2isa_c *class_ptr = (bx_pci2isa_c *) this_ptr;
-
-  return( class_ptr->pci_read(address, io_len) );
-}
-
-
-  Bit32u
-bx_pci2isa_c::pci_read(Bit8u address, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif // !BX_USE_P2I_SMF
-
-  Bit32u value = 0;
-
-  if (io_len <= 4) {
-    for (unsigned i=0; i<io_len; i++) {
-      value |= (BX_P2I_THIS s.pci_conf[address+i] << (i*8));
-    }
-    BX_DEBUG(("PIIX3 PCI-to-ISA read register 0x%02x value 0x%08x", address, value));
-    return value;
-    }
-  else
-    return(0xffffffff);
-}
-
-
-  // static pci configuration space write callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-  void
-bx_pci2isa_c::pci_write_handler(void *this_ptr, Bit8u address, Bit32u value, unsigned io_len)
-{
-#if !BX_USE_P2I_SMF
-  bx_pci2isa_c *class_ptr = (bx_pci2isa_c *) this_ptr;
-
-  class_ptr->pci_write(address, value, io_len);
-}
-
-  void
-bx_pci2isa_c::pci_write(Bit8u address, Bit32u value, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif // !BX_USE_P2I_SMF
-
-  Bit8u value8;
-
-  if (io_len <= 4) {
-    for (unsigned i=0; i<io_len; i++) {
-      value8 = (value >> (i*8)) & 0xFF;
-      switch (address+i) {
-        case 0x06:
-          break;
-        default:
-          BX_P2I_THIS s.pci_conf[address+i] = value8;
-          BX_DEBUG(("PIIX3 PCI-to-ISA write register 0x%02x value 0x%02x", address,
-                    value8));
-        }
-      }
-    }
-}
-
-#endif /* BX_PCI_SUPPORT */
diff --git a/tools/ioemu/iodev/pci2isa.h b/tools/ioemu/iodev/pci2isa.h
deleted file mode 100644 (file)
index 1517052..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: pci2isa.h,v 1.4 2002/11/09 20:51:40 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-#if BX_USE_P2I_SMF
-#  define BX_P2I_SMF  static
-#  define BX_P2I_THIS thePci2IsaBridge->
-#else
-#  define BX_P2I_SMF
-#  define BX_P2I_THIS this->
-#endif
-
-
-class bx_pci2isa_c : public bx_devmodel_c {
-
-public:
-  bx_pci2isa_c(void);
-  ~bx_pci2isa_c(void);
-  virtual void   init(void);
-  virtual void   reset(unsigned type);
-
-private:
-
-  struct {
-    Bit8u pci_conf[256];
-    Bit8u elcr1;
-    Bit8u elcr2; 
-    } s;
-
-  static Bit32u read_handler(void *this_ptr, Bit32u address, unsigned io_len);
-  static void   write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);
-  static Bit32u pci_read_handler(void *this_ptr, Bit8u address, unsigned io_len);
-  static void   pci_write_handler(void *this_ptr, Bit8u address, Bit32u value, unsigned io_len);
-#if !BX_USE_P2I_SMF
-  Bit32u read(Bit32u address, unsigned io_len);
-  void   write(Bit32u address, Bit32u value, unsigned io_len);
-  Bit32u pci_read(Bit8u address, unsigned io_len);
-  void   pci_write(Bit8u address, Bit32u value, unsigned io_len);
-#endif
-  };
diff --git a/tools/ioemu/iodev/pciusb.cc b/tools/ioemu/iodev/pciusb.cc
deleted file mode 100644 (file)
index e2d4248..0000000
+++ /dev/null
@@ -1,668 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: pciusb.cc,v 1.3 2003/02/06 19:09:24 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2003  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-//
-// Experimental PCI USB adapter
-// Benjamin D Lunt (fys@cybertrails.com) coded most of this usb emulation.
-//  I hope to add to this code to make it more functionable.
-//
-
-// Define BX_PLUGGABLE in files that can be compiled into plugins.  For
-// platforms that require a special tag on exported symbols, BX_PLUGGABLE 
-// is used to know when we are exporting symbols and when we are importing.
-#define BX_PLUGGABLE
-
-#include "bochs.h"
-#if BX_PCI_SUPPORT && BX_PCI_USB_SUPPORT
-
-#define LOG_THIS theUSBDevice->
-
-bx_pciusb_c* theUSBDevice = NULL;
-
-  int
-libpciusb_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
-{
-  theUSBDevice = new bx_pciusb_c ();
-  bx_devices.pluginPciUSBAdapter = theUSBDevice;
-  BX_REGISTER_DEVICE_DEVMODEL(plugin, type, theUSBDevice, BX_PLUGIN_PCIUSB);
-  return 0; // Success
-}
-
-  void
-libpciusb_LTX_plugin_fini(void)
-{
-}
-
-
-bx_pciusb_c::bx_pciusb_c(void)
-{
-  put("USB");
-  settype(PCIUSBLOG);
-}
-
-bx_pciusb_c::~bx_pciusb_c(void)
-{
-  // nothing for now
-  BX_DEBUG(("Exit."));
-}
-
-
-  void
-bx_pciusb_c::init(void)
-{
-  // called once when bochs initializes
-
-  if (!bx_options.usb[0].Oenabled->get()) return;
-
-  Bit16u base_ioaddr = bx_options.usb[0].Oioaddr->get();
-  Bit8u irq = bx_options.usb[0].Oirq->get();
-
-  DEV_register_irq(irq, "USB Hub #1");
-  BX_USB_THIS hub[0].irq = irq;
-
-  // Call our timer routine every 1mS (1,000uS)
-  // Continuous and active
-  BX_USB_THIS hub[0].timer_index =
-                   bx_pc_system.register_timer(this, usb_timer_handler, 1000, 1,1, "usb.timer");
-
-  for (unsigned addr=base_ioaddr; addr<(unsigned)(base_ioaddr+0x14); addr++) {
-    BX_DEBUG(("register read/write: 0x%04x", addr));
-    DEV_register_ioread_handler(this, read_handler, addr, "USB Hub #1", 7);
-    DEV_register_iowrite_handler(this, write_handler, addr, "USB Hub #1", 7);
-  }
-  BX_USB_THIS hub[0].base_ioaddr = base_ioaddr;
-
-  DEV_register_pci_handlers(this,
-                            pci_read_handler,
-                            pci_write_handler,
-                            BX_PCI_DEVICE(1,2),
-                            "Experimental PCI USB");
-
-  for (unsigned i=0; i<256; i++) {
-    BX_USB_THIS hub[0].pci_conf[i] = 0x0;
-  }
-
-  BX_INFO(("usb1 at 0x%04x-0x%04x irq %d", base_ioaddr, base_ioaddr+0x13, irq));
-}
-
-  void
-bx_pciusb_c::reset(unsigned type)
-{
-  unsigned i;
-
-  static const struct reset_vals_t {
-    unsigned      addr;
-    unsigned char val;
-  } reset_vals[] = {
-    { 0x00, 0x86 }, { 0x01, 0x80 }, // 0x8086 = vendor
-    { 0x02, 0x20 }, { 0x03, 0x70 }, // 0x7020 = device
-    { 0x04, 0x05 }, { 0x05, 0x00 },    // command_io
-    { 0x06, 0x80 }, { 0x07, 0x02 },    // status
-    { 0x08, 0x01 },                 // revision number
-    { 0x09, 0x00 },                 // interface
-    { 0x0a, 0x03 },                 // class_sub  USB Host Controller
-    { 0x0b, 0x0c },                 // class_base Serial Bus Controller
-    { 0x0D, 0x20 },                 // bus latency
-    { 0x0e, 0x00 },                 // header_type_generic
-    // address space 0x20 - 0x23
-    { 0x20, ((bx_options.usb[0].Oioaddr->get() & 0xE0) | 0x01) },
-    { 0x21, (bx_options.usb[0].Oioaddr->get() >> 8) },
-    { 0x22, 0x00 }, { 0x23, 0x00 },
-    { 0x3c, bx_options.usb[0].Oirq->get() }, // IRQ
-    { 0x3d, 0x04 },                 // INT
-    { 0x6a, 0x01 },                 // USB clock
-    { 0xc1, 0x20 }                  // PIRQ enable
-
-  };
-  for (i = 0; i < sizeof(reset_vals) / sizeof(*reset_vals); ++i) {
-      BX_USB_THIS hub[0].pci_conf[reset_vals[i].addr] = reset_vals[i].val;
-  }
-
-  // reset locals
-  BX_USB_THIS global_reset = 0;
-
-  // Put the USB registers into their RESET state
-  for (i=0; i<BX_USB_CONFDEV; i++) {
-    BX_USB_THIS hub[i].usb_command.max_packet_size = 0;
-    BX_USB_THIS hub[i].usb_command.configured = 0;
-    BX_USB_THIS hub[i].usb_command.debug = 0;
-    BX_USB_THIS hub[i].usb_command.resume = 0;
-    BX_USB_THIS hub[i].usb_command.suspend = 1;
-    BX_USB_THIS hub[i].usb_command.host_reset = 0;
-    BX_USB_THIS hub[i].usb_command.reset = 0;
-    BX_USB_THIS hub[i].usb_command.schedule = 0;
-    BX_USB_THIS hub[i].usb_status.error_interrupt = 0;
-    BX_USB_THIS hub[i].usb_status.host_error = 0;
-    BX_USB_THIS hub[i].usb_status.host_halted = 0;
-    BX_USB_THIS hub[i].usb_status.interrupt = 0;
-    BX_USB_THIS hub[i].usb_status.pci_error = 0;
-    BX_USB_THIS hub[i].usb_status.resume = 0;
-    BX_USB_THIS hub[i].usb_enable.short_packet = 0;
-    BX_USB_THIS hub[i].usb_enable.on_complete = 0;
-    BX_USB_THIS hub[i].usb_enable.resume = 0;
-    BX_USB_THIS hub[i].usb_enable.timeout_crc = 0;
-    BX_USB_THIS hub[i].usb_frame_num.frame_num = 0x0000;
-    BX_USB_THIS hub[i].usb_frame_base.frame_base = 0x00000000;
-    BX_USB_THIS hub[i].usb_sof.sof_timing = 0x40;
-    for (unsigned j=0; j<USB_NUM_PORTS; j++) {
-      BX_USB_THIS hub[i].usb_port[j].connect_changed = 0;
-      BX_USB_THIS hub[i].usb_port[j].line_dminus = 0;
-      BX_USB_THIS hub[i].usb_port[j].line_dplus = 0;
-      BX_USB_THIS hub[i].usb_port[j].low_speed = 0;
-      BX_USB_THIS hub[i].usb_port[j].reset = 0;
-      BX_USB_THIS hub[i].usb_port[j].resume = 0;
-      BX_USB_THIS hub[i].usb_port[j].suspend = 0;
-      BX_USB_THIS hub[i].usb_port[j].enabled = 0;
-      BX_USB_THIS hub[i].usb_port[j].able_changed = 0;
-      BX_USB_THIS hub[i].usb_port[j].status = 0;
-    }
-  }
-}
-
-
-  // static IO port read callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-  Bit32u
-bx_pciusb_c::read_handler(void *this_ptr, Bit32u address, unsigned io_len)
-{
-#if !BX_USE_PCIUSB_SMF
-  bx_pciusb_c *class_ptr = (bx_pciusb_c *) this_ptr;
-
-  return( class_ptr->read(address, io_len) );
-}
-
-
-  Bit32u
-bx_pciusb_c::read(Bit32u address, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif // !BX_USE_PCIUSB_SMF
-  Bit32u val = 0x0;
-  Bit8u  offset,port;
-
-  BX_DEBUG(("register read from address 0x%04x - ", (unsigned) address));
-
-  offset = address - BX_USB_THIS hub[0].base_ioaddr;
-
-  switch (offset) {
-    case 0x0C: // Start of Frame Modify
-    case 0x11: // port0 (high byte read)
-    case 0x13: // port1 (high byte read)
-      if (io_len != 1)
-        BX_PANIC(("io read from port 0x%04x, bad len=%u", (unsigned) address, (unsigned) io_len));
-      break;
-    case 0x10: // port0
-    case 0x12: // port1
-      if ((io_len < 1) || (io_len > 2))
-        BX_PANIC(("io read from port 0x%04x, bad len=%u", (unsigned) address, (unsigned) io_len));
-      break;
-    case 0x00: // command register (16-bit)
-    case 0x02: // status register (16-bit)
-    case 0x04: // interrupt enable register (1-bit)
-    case 0x06: // frame number register (16-bit)
-      if (io_len != 2)
-        BX_PANIC(("io read from port 0x%04x, bad len=%u", (unsigned) address, (unsigned) io_len));
-      break;
-    case 0x08: // frame base register (32-bit)
-      if (io_len != 4)
-        BX_PANIC(("io read from port 0x%04x, bad len=%u", (unsigned) address, (unsigned) io_len));
-      break;
-  }
-
-  switch (offset) {
-    case 0x00: // command register (16-bit)
-      val = BX_USB_THIS hub[0].usb_command.max_packet_size << 7
-            | BX_USB_THIS hub[0].usb_command.configured << 6
-            | BX_USB_THIS hub[0].usb_command.debug << 5
-            | BX_USB_THIS hub[0].usb_command.resume << 4
-            | BX_USB_THIS hub[0].usb_command.suspend << 3
-            | BX_USB_THIS hub[0].usb_command.reset << 2
-            | BX_USB_THIS hub[0].usb_command.host_reset << 1
-            | BX_USB_THIS hub[0].usb_command.schedule;
-      break;
-
-    case 0x02: // status register (16-bit)
-      val = BX_USB_THIS hub[0].usb_status.host_halted << 5
-            | BX_USB_THIS hub[0].usb_status.host_error << 4
-            | BX_USB_THIS hub[0].usb_status.pci_error << 3
-            | BX_USB_THIS hub[0].usb_status.resume << 2
-            | BX_USB_THIS hub[0].usb_status.error_interrupt << 1
-            | BX_USB_THIS hub[0].usb_status.interrupt;
-      break;
-
-    case 0x04: // interrupt enable register (16-bit)
-      val = BX_USB_THIS hub[0].usb_enable.short_packet << 3
-            | BX_USB_THIS hub[0].usb_enable.on_complete << 2
-            | BX_USB_THIS hub[0].usb_enable.resume << 1
-            | BX_USB_THIS hub[0].usb_enable.timeout_crc;
-      break;
-
-    case 0x06: // frame number register (16-bit)
-      val = BX_USB_THIS hub[0].usb_frame_num.frame_num;
-      break;
-
-    case 0x08: // frame base register (32-bit)
-      val = BX_USB_THIS hub[0].usb_frame_base.frame_base;
-      break;
-
-    case 0x0C: // start of Frame Modify register (8-bit)
-      val = BX_USB_THIS hub[0].usb_sof.sof_timing;
-      break;
-
-    case 0x10: // port0
-    case 0x12: // port1
-      port = (offset & 0x0F) >> 1;
-      if (port < USB_NUM_PORTS) {
-        val = BX_USB_THIS hub[0].usb_port[port].suspend << 12
-              | BX_USB_THIS hub[0].usb_port[port].reset << 9
-              | BX_USB_THIS hub[0].usb_port[port].low_speed << 8
-              | 1 << 7
-              | BX_USB_THIS hub[0].usb_port[port].resume << 6
-              | BX_USB_THIS hub[0].usb_port[port].line_dplus << 5
-              | BX_USB_THIS hub[0].usb_port[port].line_dminus << 4
-              | BX_USB_THIS hub[0].usb_port[port].able_changed << 3
-              | BX_USB_THIS hub[0].usb_port[port].enabled << 2
-              | BX_USB_THIS hub[0].usb_port[port].connect_changed << 1
-              | BX_USB_THIS hub[0].usb_port[port].status;
-        break;
-      } // else fall through to default
-
-    default:
-      val = 0; // keep compiler happy
-      BX_PANIC(("unsupported io read from address=0x%04x!", (unsigned) address));
-      break;
-  }
-
-  BX_DEBUG(("val =  0x%08x", (Bit32u) val));
-
-  return(val);
-}
-
-
-  // static IO port write callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-  void
-bx_pciusb_c::write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len)
-{
-#if !BX_USE_PCIUSB_SMF
-  bx_pciusb_c *class_ptr = (bx_pciusb_c *) this_ptr;
-
-  class_ptr->write(address, value, io_len);
-}
-
-  void
-bx_pciusb_c::write(Bit32u address, Bit32u value, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif // !BX_USE_PCIUSB_SMF
-  Bit8u  offset,port;
-
-  BX_DEBUG(("register write to address 0x%04x - ", (unsigned) address));
-
-  offset = address - BX_USB_THIS hub[0].base_ioaddr;
-
-  switch (offset) {
-    case 0x0C: // Start of Frame Modify
-      if (io_len != 1)
-        BX_PANIC(("io write to port 0x%04x, bad len=%u", (unsigned) address, (unsigned) io_len));
-      break;
-    case 0x00: // command register (16-bit)
-    case 0x02: // status register (16-bit)
-    case 0x04: // interrupt enable register (1-bit)
-    case 0x06: // frame number register (16-bit)
-    case 0x10: // port0
-    case 0x12: // port1
-      if (io_len != 2)
-        BX_PANIC(("io write to port 0x%04x, bad len=%u", (unsigned) address, (unsigned) io_len));
-      break;
-    case 0x08: // frame base register (32-bit)
-      if (io_len != 4)
-        BX_PANIC(("io write to port 0x%04x, bad len=%u", (unsigned) address, (unsigned) io_len));
-      break;
-  }
-
-  switch (offset) {
-    case 0x00: // command register (16-bit) (R/W)
-      if (value & 0xFF00)
-        BX_ERROR(("write to command register with bits 15:8 not zero: 0x%04x", value));
-
-      BX_USB_THIS hub[0].usb_command.max_packet_size = (value & 0x80) ? 1: 0;
-      BX_USB_THIS hub[0].usb_command.configured = (value & 0x40) ? 1: 0;
-      BX_USB_THIS hub[0].usb_command.debug = (value & 0x20) ? 1: 0;
-      BX_USB_THIS hub[0].usb_command.resume = (value & 0x10) ? 1: 0;
-      BX_USB_THIS hub[0].usb_command.suspend = (value & 0x08) ? 1: 0;
-      BX_USB_THIS hub[0].usb_command.reset = (value & 0x04) ? 1: 0;
-      BX_USB_THIS hub[0].usb_command.host_reset = (value & 0x02) ? 1: 0;
-      BX_USB_THIS hub[0].usb_command.schedule = (value & 0x01) ? 1: 0;
-
-      // If software set the reset bit, we need to set reset bit of each port for 10ms.
-      if (BX_USB_THIS hub[0].usb_command.reset)
-        BX_USB_THIS global_reset = 10;
-
-      // If host_reset then reset all registers, etc.
-      if (BX_USB_THIS hub[0].usb_command.host_reset)
-        BX_USB_THIS reset(0);
-
-      // If Run/Stop, identify in log and ignore
-      if (BX_USB_THIS hub[0].usb_command.schedule)
-        BX_INFO(("Software set Schedule bit in Command register"));
-
-      // If Debug mode set, panic.  Not implemented
-      if (BX_USB_THIS hub[0].usb_command.debug)
-        BX_PANIC(("Software set DEBUG bit in Command register. Not implemented"));
-
-      break;
-
-    case 0x02: // status register (16-bit) (R/WC)
-      if (value & 0xFFC0)
-        BX_ERROR(("write to status register with bits 15:6 not zero: 0x%04x", value));
-
-      BX_USB_THIS hub[0].usb_status.host_halted = (value & 0x20) ? 0: BX_USB_THIS hub[0].usb_status.host_halted;
-      BX_USB_THIS hub[0].usb_status.host_error = (value & 0x10) ? 0: BX_USB_THIS hub[0].usb_status.host_error;
-      BX_USB_THIS hub[0].usb_status.pci_error = (value & 0x08) ? 0: BX_USB_THIS hub[0].usb_status.pci_error;
-      BX_USB_THIS hub[0].usb_status.resume = (value & 0x04) ? 0: BX_USB_THIS hub[0].usb_status.resume;
-      BX_USB_THIS hub[0].usb_status.error_interrupt = (value & 0x02) ? 0: BX_USB_THIS hub[0].usb_status.error_interrupt;
-      BX_USB_THIS hub[0].usb_status.interrupt = (value & 0x01) ? 0: BX_USB_THIS hub[0].usb_status.interrupt;
-      break;
-
-    case 0x04: // interrupt enable register (16-bit)
-      if (value & 0xFFF0)
-        BX_ERROR(("write to interrupt enable register with bits 15:4 not zero: 0x%04x", value));
-
-      BX_USB_THIS hub[0].usb_enable.short_packet  = (value & 0x08) ? 1: 0;
-      BX_USB_THIS hub[0].usb_enable.on_complete  = (value & 0x04) ? 1: 0;
-      BX_USB_THIS hub[0].usb_enable.resume  = (value & 0x02) ? 1: 0;
-      BX_USB_THIS hub[0].usb_enable.timeout_crc = (value & 0x01) ? 1: 0;
-
-      // For now, we will just ignore these being set since we never raise the IRQ
-
-      break;
-
-    case 0x06: // frame number register (16-bit)
-      if (value & 0xF800)
-        BX_ERROR(("write to frame number register with bits 15:11 not zero: 0x%04x", value));
-
-      if (BX_USB_THIS hub[0].usb_status.host_halted)
-        BX_USB_THIS hub[0].usb_frame_num.frame_num = value;
-      else
-        // ignored by the hardward, but lets report it anyway
-        BX_ERROR(("write to frame number register with STATUS.HALTED == 0"));
-
-      break;
-
-    case 0x08: // frame base register (32-bit)
-      if (value & 0xFFF)
-        BX_PANIC(("write to frame base register with bits 11:0 not zero: 0x%08x", value));
-
-      BX_USB_THIS hub[0].usb_frame_base.frame_base = value;
-      break;
-
-    case 0x0C: // start of Frame Modify register (8-bit)
-      if (value & 0x80)
-        BX_ERROR(("write to SOF Modify register with bit 7 not zero: 0x%04x", value));
-
-       BX_USB_THIS hub[0].usb_sof.sof_timing = value;
-       break;
-
-    case 0x10: // port0
-    case 0x12: // port1
-      port = (offset & 0x0F) >> 1;
-      if (port < USB_NUM_PORTS) {
-        if (value & ((1<<5) | (1<<4) | (1<<0)))
-          BX_PANIC(("write to one or more read-only bits in port%d register: 0x%04x", port, value));
-        if (!(value & (1<<7)))
-          BX_ERROR(("write to port%d register bit 7 = 0", port));
-        if (value & (1<<8))
-          BX_INFO(("write to bit 8 in port%d register ignored", port));
-        if (value & (1<<2))
-          BX_INFO(("port%d enabled ignored.  Not implemented", port));
-        if ((value & (1<<12)) && BX_USB_THIS hub[0].usb_command.suspend)
-          BX_ERROR(("write to port%d register bit 12 when in Global-Suspend", port));
-
-        BX_USB_THIS hub[0].usb_port[port].suspend = (value & (1<<12)) ? 1 : 0;
-        BX_USB_THIS hub[0].usb_port[port].reset = (value & (1<<9)) ? 1 : 0;
-        BX_USB_THIS hub[0].usb_port[port].resume = (value & (1<<6)) ? 1 : 0;
-        BX_USB_THIS hub[0].usb_port[port].able_changed = (value & (1<<3)) ? 0 : BX_USB_THIS hub[0].usb_port[0].able_changed;
-        BX_USB_THIS hub[0].usb_port[port].enabled = (value & (1<<2)) ? 1 : 0;
-        BX_USB_THIS hub[0].usb_port[port].connect_changed = (value & (1<<1)) ? 0 : BX_USB_THIS hub[0].usb_port[0].connect_changed;
-        break;
-      }
-      // else fall through to default
-
-    default:
-      BX_PANIC(("unsupported io write to address=0x%04x!", (unsigned) address));
-      break;
-  }
-}
-
-void bx_pciusb_c::usb_timer_handler(void *this_ptr)
-{
-  bx_pciusb_c *class_ptr = (bx_pciusb_c *) this_ptr;
-  class_ptr->usb_timer();
-}
-
-// Called once every 1ms
-void bx_pciusb_c::usb_timer(void)
-{
-  int i;
-
-  // The Frame Number Register is incremented every 1ms  ?????????
-  // Needs more work and investigation on this.
-  BX_USB_THIS hub[0].usb_frame_num.frame_num++;
-  BX_USB_THIS hub[0].usb_frame_num.frame_num &= (1024-1);
-
-  // If the "global reset" bit was set by software, we need
-  // to set the reset bit in each "active" port for 10ms
-  if (BX_USB_THIS global_reset) {
-    for (i=0; i<USB_NUM_PORTS; i++) {
-      BX_USB_THIS hub[0].usb_port[i].able_changed = 0;
-      BX_USB_THIS hub[0].usb_port[i].connect_changed = 0;
-      BX_USB_THIS hub[0].usb_port[i].enabled = 0;
-      BX_USB_THIS hub[0].usb_port[i].line_dminus = 0;
-      BX_USB_THIS hub[0].usb_port[i].line_dplus = 0;
-      BX_USB_THIS hub[0].usb_port[i].low_speed = 0;
-      BX_USB_THIS hub[0].usb_port[i].reset = 1;
-      BX_USB_THIS hub[0].usb_port[i].resume = 0;
-      BX_USB_THIS hub[0].usb_port[i].status = 0;
-      BX_USB_THIS hub[0].usb_port[i].suspend = 0;
-    }
-    BX_USB_THIS global_reset--;
-  } else {
-    for (i=0; i<USB_NUM_PORTS; i++)
-      BX_USB_THIS hub[0].usb_port[i].reset = 0;
-  }
-
-  // If command.schedule = 0, then we need to set Status.Halted
-  if (!BX_USB_THIS hub[0].usb_command.schedule)
-    BX_USB_THIS hub[0].usb_status.host_halted = 1;
-
-
-  // TODO:
-  //  If ins Global_Suspend mode and any of usb_port[i] bits 6,3, or 1 are set,
-  //    we need to issue a Global_Resume (set the global resume bit).
-  //    However, since we don't do anything, let's not.
-
-}
-  
-  // static pci configuration space read callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-  Bit32u
-bx_pciusb_c::pci_read_handler(void *this_ptr, Bit8u address, unsigned io_len)
-{
-#if !BX_USE_PCIUSB_SMF
-  bx_pciusb_c *class_ptr = (bx_pciusb_c *) this_ptr;
-
-  return class_ptr->pci_read(address, io_len);
-}
-
-
-  Bit32u
-bx_pciusb_c::pci_read(Bit8u address, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif // !BX_USE_PCIUSB_SMF
-
-  Bit32u value = 0;
-
-  if (io_len > 4 || io_len == 0) {
-    BX_ERROR(("Experimental USB PCI read register 0x%02x, len=%u !",
-             (unsigned) address, (unsigned) io_len));
-    return 0xffffffff;
-  }
-
-  const char* pszName = "                  ";
-  switch (address) {
-    case 0x00: if (io_len == 2) {
-                 pszName = "(vendor id)       ";
-               } else if (io_len == 4) {
-                 pszName = "(vendor + device) ";
-               }
-      break;
-    case 0x04: if (io_len == 2) {
-                 pszName = "(command)         ";
-               } else if (io_len == 4) {
-                 pszName = "(command+status)  ";
-               }
-      break;
-    case 0x08: if (io_len == 1) {
-                 pszName = "(revision id)     ";
-               } else if (io_len == 4) {
-                 pszName = "(rev.+class code) ";
-               }
-      break;
-    case 0x0c: pszName = "(cache line size) "; break;
-    case 0x20: pszName = "(base address)    "; break;
-    case 0x28: pszName = "(cardbus cis)     "; break;
-    case 0x2c: pszName = "(subsys. vendor+) "; break;
-    case 0x30: pszName = "(rom base)        "; break;
-    case 0x3c: pszName = "(interrupt line+) "; break;
-    case 0x3d: pszName = "(interrupt pin)   "; break;
-  }
-
-  // This odd code is to display only what bytes actually were read.
-  char szTmp[9];
-  char szTmp2[3];
-  szTmp[0] = '\0';
-  szTmp2[0] = '\0';
-  for (unsigned i=0; i<io_len; i++) {
-    value |= (BX_USB_THIS hub[0].pci_conf[address+i] << (i*8));
-    sprintf(szTmp2, "%02x", (BX_USB_THIS hub[0].pci_conf[address+i]));
-    strrev(szTmp2);
-    strcat(szTmp, szTmp2);
-  }
-  strrev(szTmp);
-  BX_DEBUG(("Experimental USB PCI read register 0x%02x %svalue 0x%s",
-            address, pszName, szTmp));
-  return value;
-}
-
-
-  // static pci configuration space write callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-  void
-bx_pciusb_c::pci_write_handler(void *this_ptr, Bit8u address, Bit32u value, unsigned io_len)
-{
-#if !BX_USE_PCIUSB_SMF
-  bx_pciusb_c *class_ptr = (bx_pciusb_c *) this_ptr;
-
-  class_ptr->pci_write(address, value, io_len);
-}
-
-  void
-bx_pciusb_c::pci_write(Bit8u address, Bit32u value, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif // !BX_USE_PCIUSB_SMF
-
-  if (io_len > 4 || io_len == 0) {
-    BX_ERROR(("Experimental USB PCI write register 0x%02x, len=%u !",
-             (unsigned) address, (unsigned) io_len));
-    return;
-  }
-
-  // This odd code is to display only what bytes actually were written.
-  char szTmp[9];
-  char szTmp2[3];
-  szTmp[0] = '\0';
-  szTmp2[0] = '\0';
-  for (unsigned i=0; i<io_len; i++) {
-    const Bit8u value8 = (value >> (i*8)) & 0xFF;
-    switch (address+i) {
-      case 0x20: // Base address
-        BX_USB_THIS hub[0].pci_conf[address+i] = (value8 & 0xe0) | 0x01;
-        sprintf(szTmp2, "%02x", (value8 & 0xe0) | 0x01);
-        break;
-      case 0x10: // Reserved
-      case 0x11: //
-      case 0x12: //
-      case 0x13: //
-      case 0x14: //
-      case 0x15: //
-      case 0x16: //
-      case 0x17: //
-      case 0x18: //
-      case 0x19: //
-      case 0x1a: //
-      case 0x1b: //
-      case 0x1c: //
-      case 0x1d: //
-      case 0x1e: //
-      case 0x1f: //
-      case 0x22: // Always 0
-      case 0x23: //
-      case 0x24: // Reserved
-      case 0x25: //
-      case 0x26: //
-      case 0x27: //
-      case 0x30: // Oh, no, you're not writing to rom_base!
-      case 0x31: //
-      case 0x32: //
-      case 0x33: //
-      case 0x3d: //
-      case 0x05: // disallowing write to command hi-byte
-      case 0x06: // disallowing write to status lo-byte (is that expected?)
-        strcpy(szTmp2, "..");
-        break;
-      default:
-        BX_USB_THIS hub[0].pci_conf[address+i] = value8;
-        sprintf(szTmp2, "%02x", value8);
-    }
-    strrev(szTmp2);
-    strcat(szTmp, szTmp2);
-  }
-  strrev(szTmp);
-  BX_DEBUG(("Experimental USB PCI write register 0x%02x value 0x%s", address, szTmp));
-}
-
-#endif // BX_PCI_SUPPORT && BX_PCI_USB_SUPPORT
diff --git a/tools/ioemu/iodev/pciusb.h b/tools/ioemu/iodev/pciusb.h
deleted file mode 100644 (file)
index be2532c..0000000
+++ /dev/null
@@ -1,195 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: pciusb.h,v 1.1 2003/01/28 16:58:10 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2003  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-// Benjamin D Lunt (fys@cybertrails.com) coded most of this usb emulation.
-//  I hope to add to this code to make it more functionable.
-//
-
-#if BX_USE_PCIUSB_SMF
-#  define BX_USB_THIS theUSBDevice->
-#else
-#  define BX_USB_THIS this->
-#endif
-
-#define BX_USB_MAXDEV   1
-#define BX_USB_CONFDEV  1   /* only 1 USB hub currently */
-
-#define USB_NUM_PORTS   2 /* UHCI supports 2 ports per root hub */
-
-typedef struct {
-
-  Bit16u base_ioaddr;
-  Bit8u  irq;
-  int    timer_index;
-
-  // Registers
-  // Base + 0x00  Command register
-  // Base + 0x02  Status register
-  // Base + 0x04  Interrupt Enable register
-  // Base + 0x06  Frame Number register
-  // Base + 0x08  Frame Base Register (32-bit)
-  // Base + 0x0C  Start of Frame Modify register
-  // Base + 0x0D
-  // Base + 0x0E
-  // Base + 0x0F
-  // Base + 0x10  Eight(?) 16-bit ports (one for each port on hub)
-
-  // Bit reps of registers above
-  // Command Register
-  //  Bits 15-8 are reserved
-  //  Bit 7 = Maximum packet size
-  //  Bit 6 = Host Controller has been configured (set by software)
-  //  Bit 5 = software debug mode
-  //  Bit 4 = force global resume
-  //  Bit 3 = enter global suspend mode
-  //  Bit 2 = global reset
-  //  Bit 1 = host controller reset
-  //  Bit 0 = run/stop schedule
-  struct {
-    bx_bool max_packet_size; //(bit 7) 0 = 32 bytes, 1 = 64 bytes
-    bx_bool configured;      //(bit 6)
-    bx_bool debug;           //(bit 5)
-    bx_bool resume;          //(bit 4)
-    bx_bool suspend;         //(bit 3)
-    bx_bool reset;           //(bit 2)
-    bx_bool host_reset;      //(bit 1)
-    bx_bool schedule;        //(bit 0) 0 = Stop, 1 = Run
-  } usb_command;
-
-  // Status Register
-  //  Bits 15-6 are reserved
-  //  Bit 5 = Host controller halted
-  //  Bit 4 = Host controller process error
-  //  Bit 3 = PCI Bus error
-  //  Bit 2 = resume received
-  //  Bit 1 = USB error interrupt
-  //  Bit 0 = USB interrupt
-  struct {
-    bx_bool host_halted;     //(bit 5)
-    bx_bool host_error;      //(bit 4)
-    bx_bool pci_error;       //(bit 3)
-    bx_bool resume;          //(bit 2)
-    bx_bool error_interrupt; //(bit 1)
-    bx_bool interrupt;       //(bit 0)
-  } usb_status;
-
-  // Interrupt Enable Register
-  //  Bits 15-4 are reserved
-  //  Bit 3 = enable short packet interrupts
-  //  Bit 2 = enable interrupt On Complete
-  //  Bit 1 = enable resume
-  //  Bit 0 = enable timeout/crc
-  struct {
-    bx_bool short_packet; //(bit 3)
-    bx_bool on_complete;  //(bit 2)
-    bx_bool resume;       //(bit 1)
-    bx_bool timeout_crc;  //(bit 0)
-  } usb_enable;
-
-  // Frame Number Register
-  //  Bits 15-11 are reserved
-  //  Bits 10-0  Frame List Current Index/Frame Number
-  struct {
-    Bit16u frame_num;
-  } usb_frame_num;
-
-  // Frame List Base Address Register
-  //  Bits 31-12  Base
-  //  Bits 11-0   *must* be zeros when written to
-  struct {
-    Bit32u frame_base;
-  } usb_frame_base;
-
-  // Start of Frame Modify Register
-  //  Bit    7 reserved
-  //  Bits 6-0 SOF timing value (default 64)
-  // SOF cycle time equals 11936+timing value
-  struct {
-    Bit8u sof_timing;
-  } usb_sof;
-
-  // Port Register (0-1)
-  //  Bits 15-13  are reserved
-  //  Bit     12  suspend port
-  //  Bit  11-10  are reserved
-  //  Bit      9  port in reset state
-  //  Bit      8  low-speed device is attached (read-only)
-  //  Bit      7  reserved
-  //  Bit      6  resume detected (read-only)
-  //  Bit      5  line-status D+ (read-only)
-  //  Bit      4  line-status D- (read-only)
-  //  Bit      3  port enabled/disable status has changed
-  //               (write 1 to this bit to clear it)
-  //  Bit      2  port is enabled
-  //  Bit      1  connect status has changed
-  //               (write 1 to this bit to clear it)
-  //  Bit      0  current connect status (read-only)
-  //  Can only write in WORD sizes (Read in byte sizes???)
-  struct {
-    bx_bool suspend;
-    bx_bool reset;
-    bx_bool low_speed;
-    bx_bool resume;
-    bx_bool line_dplus;
-    bx_bool line_dminus;
-    bx_bool able_changed;
-    bx_bool enabled;
-    bx_bool connect_changed;
-    bx_bool status;
-  } usb_port[USB_NUM_PORTS];
-
-  Bit8u pci_conf[256];
-
-} bx_usb_t;
-
-
-class bx_pciusb_c : public bx_devmodel_c
-{
-public:
-  bx_pciusb_c(void);
-  ~bx_pciusb_c(void);
-  virtual void   init(void);
-  virtual void   reset(unsigned type);
-
-private:
-
-  bx_usb_t hub[BX_USB_MAXDEV];
-  Bit8u  global_reset;
-
-  static void usb_timer_handler(void *);
-  void usb_timer(void);
-
-  static Bit32u read_handler(void *this_ptr, Bit32u address, unsigned io_len);
-  static void   write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);
-  static Bit32u pci_read_handler(void *this_ptr, Bit8u address, unsigned io_len);
-  static void   pci_write_handler(void *this_ptr, Bit8u address, Bit32u value, unsigned io_len);
-#if !BX_USE_PCIUSB_SMF
-  Bit32u read(Bit32u address, unsigned io_len);
-  void   write(Bit32u address, Bit32u value, unsigned io_len);
-  Bit32u pci_read(Bit8u address, unsigned io_len);
-  void   pci_write(Bit8u address, Bit32u value, unsigned io_len);
-#endif
-};
diff --git a/tools/ioemu/iodev/pcivga.cc b/tools/ioemu/iodev/pcivga.cc
deleted file mode 100644 (file)
index 4d999be..0000000
+++ /dev/null
@@ -1,248 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: pcivga.cc,v 1.2 2003/01/23 19:31:28 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002,2003 Mike Nordell
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-//
-// Experimental PCI VGA adapter
-//
-
-// Note: This "driver" was created for the SOLE PURPOSE of getting BeOS
-// to boot. It currently does NOTHING more than presenting a generic VGA
-// device on the PCI bus. ALL gfx in/out-put is still handled by the VGA code.
-// Furthermore, almost all of the PCI registers are currently acting like RAM.
-
-
-// Define BX_PLUGGABLE in files that can be compiled into plugins.  For
-// platforms that require a special tag on exported symbols, BX_PLUGGABLE 
-// is used to know when we are exporting symbols and when we are importing.
-#define BX_PLUGGABLE
-
-#include "bochs.h"
-#if BX_PCI_SUPPORT && BX_PCI_VGA_SUPPORT
-
-#define LOG_THIS thePciVgaAdapter->
-
-bx_pcivga_c* thePciVgaAdapter = 0;
-
-  int
-libpcivga_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
-{
-  thePciVgaAdapter = new bx_pcivga_c ();
-  bx_devices.pluginPciVgaAdapter = thePciVgaAdapter;
-  BX_REGISTER_DEVICE_DEVMODEL(plugin, type, thePciVgaAdapter, BX_PLUGIN_PCIVGA);
-  return 0; // Success
-}
-
-  void
-libpcivga_LTX_plugin_fini(void)
-{
-}
-
-
-bx_pcivga_c::bx_pcivga_c(void)
-{
-  put("PCIVGA");
-  settype(PCIVGALOG);
-}
-
-bx_pcivga_c::~bx_pcivga_c(void)
-{
-  // nothing for now
-  BX_DEBUG(("Exit."));
-}
-
-
-  void
-bx_pcivga_c::init(void)
-{
-  // called once when bochs initializes
-
-  DEV_register_pci_handlers(this,
-                            pci_read_handler,
-                            pci_write_handler,
-                            BX_PCI_DEVICE(2,0),
-                            "Experimental PCI VGA");
-
-  for (unsigned i=0; i<256; i++) {
-    BX_PCIVGA_THIS s.pci_conf[i] = 0x0;
-  }
-
-  // readonly registers
-  static const struct init_vals_t {
-    unsigned      addr;
-    unsigned char val;
-  } init_vals[] = {
-    // Note that the values for vendor and device id are selected at random!
-    // There might actually be "real" values for "experimental" vendor and
-    // device that should be used!
-    { 0x00, 0x34 }, { 0x01, 0x12 }, // 0x1234 - experimental vendor
-    { 0x02, 0x11 }, { 0x03, 0x11 }, // 0x1111 - experimental device
-    { 0x0a, 0x00 },                 // class_sub  VGA controller
-    { 0x0b, 0x03 },                 // class_base display
-    { 0x0e, 0x00 }                  // header_type_generic
-  };
-  for (unsigned i = 0; i < sizeof(init_vals) / sizeof(*init_vals); ++i) {
-    BX_PCIVGA_THIS s.pci_conf[init_vals[i].addr] = init_vals[i].val;
-  }
-}
-
-  void
-bx_pcivga_c::reset(unsigned type)
-{
-  static const struct reset_vals_t {
-    unsigned      addr;
-    unsigned char val;
-  } reset_vals[] = {
-      { 0x04, 0x01 }, { 0x05, 0x00 },  // command_io
-      { 0x06, 0x00 }, { 0x07, 0x02 }   // status_devsel_medium
-  };
-  for (unsigned i = 0; i < sizeof(reset_vals) / sizeof(*reset_vals); ++i) {
-      BX_PCIVGA_THIS s.pci_conf[reset_vals[i].addr] = reset_vals[i].val;
-  }
-}
-
-
-  // static pci configuration space read callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-  Bit32u
-bx_pcivga_c::pci_read_handler(void *this_ptr, Bit8u address, unsigned io_len)
-{
-#if !BX_USE_PCIVGA_SMF
-  bx_pcivga_c *class_ptr = (bx_pcivga_c *) this_ptr;
-
-  return class_ptr->pci_read(address, io_len);
-}
-
-
-  Bit32u
-bx_pcivga_c::pci_read(Bit8u address, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif // !BX_USE_PCIVGA_SMF
-
-  Bit32u value = 0;
-
-  if (io_len > 4 || io_len == 0) {
-    BX_DEBUG(("Experimental PCIVGA read register 0x%02x, len=%u !",
-             (unsigned) address, (unsigned) io_len));
-    return 0xffffffff;
-  }
-
-  const char* pszName = "                  ";
-  switch (address) {
-    case 0x00: if (io_len == 2) {
-                 pszName = "(vendor id)       ";
-               } else if (io_len == 4) {
-                 pszName = "(vendor + device) ";
-               }
-      break;
-    case 0x04: if (io_len == 2) {
-                 pszName = "(command)         ";
-               } else if (io_len == 4) {
-                 pszName = "(command+status)  ";
-               }
-      break;
-    case 0x08: if (io_len == 1) {
-                 pszName = "(revision id)     ";
-               } else if (io_len == 4) {
-                 pszName = "(rev.+class code) ";
-               }
-      break;
-    case 0x0c: pszName = "(cache line size) "; break;
-    case 0x28: pszName = "(cardbus cis)     "; break;
-    case 0x2c: pszName = "(subsys. vendor+) "; break;
-    case 0x30: pszName = "(rom base)        "; break;
-    case 0x3c: pszName = "(interrupt line+) "; break;
-    case 0x3d: pszName = "(interrupt pin)   "; break;
-  }
-
-  // This odd code is to display only what bytes actually were read.
-  char szTmp[9];
-  char szTmp2[3];
-  szTmp[0] = '\0';
-  szTmp2[0] = '\0';
-  for (unsigned i=0; i<io_len; i++) {
-    value |= (BX_PCIVGA_THIS s.pci_conf[address+i] << (i*8));
-
-    sprintf(szTmp2, "%02x", (BX_PCIVGA_THIS s.pci_conf[address+i]));
-    strrev(szTmp2);
-    strcat(szTmp, szTmp2);
-  }
-  strrev(szTmp);
-  BX_DEBUG(("Experimental PCIVGA  read register 0x%02x %svalue 0x%s",
-            address, pszName, szTmp));
-  return value;
-}
-
-
-  // static pci configuration space write callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-  void
-bx_pcivga_c::pci_write_handler(void *this_ptr, Bit8u address, Bit32u value, unsigned io_len)
-{
-#if !BX_USE_PCIVGA_SMF
-  bx_pcivga_c *class_ptr = (bx_pcivga_c *) this_ptr;
-
-  class_ptr->pci_write(address, value, io_len);
-}
-
-  void
-bx_pcivga_c::pci_write(Bit8u address, Bit32u value, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif // !BX_USE_PCIVGA_SMF
-
-  if (io_len > 4 || io_len == 0) {
-    BX_DEBUG(("Experimental PCIVGA write register 0x%02x, len=%u !",
-             (unsigned) address, (unsigned) io_len));
-    return;
-  }
-
-  // This odd code is to display only what bytes actually were written.
-  char szTmp[9];
-  char szTmp2[3];
-  szTmp[0] = '\0';
-  szTmp2[0] = '\0';
-  for (unsigned i=0; i<io_len; i++) {
-    const Bit8u value8 = (value >> (i*8)) & 0xFF;
-    switch (address+i) {
-      case 0x30: // Oh, no, you're not writing to rom_base!
-      case 0x31: //
-      case 0x32: //
-      case 0x33: //
-      case 0x04: // disallowing write to command
-      case 0x06: // disallowing write to status lo-byte (is that expected?)
-        strcpy(szTmp2, "..");
-        break;
-      default:
-        BX_PCIVGA_THIS s.pci_conf[address+i] = value8;
-        sprintf(szTmp2, "%02x", value8);
-    }
-    strrev(szTmp2);
-    strcat(szTmp, szTmp2);
-  }
-  strrev(szTmp);
-  BX_DEBUG(("Experimental PCIVGA write register 0x%02x value 0x%s", address, szTmp));
-}
-
-#endif // BX_PCI_SUPPORT && BX_PCI_VGA_SUPPORT
diff --git a/tools/ioemu/iodev/pcivga.h b/tools/ioemu/iodev/pcivga.h
deleted file mode 100644 (file)
index 15bd986..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: pcivga.h,v 1.3 2003/01/27 21:11:55 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002,2003  Mike Nordell
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-#if BX_USE_PCIVGA_SMF
-#  define BX_PCIVGA_THIS thePciVgaAdapter->
-#else
-#  define BX_PCIVGA_THIS this->
-#endif
-
-
-class bx_pcivga_c : public bx_devmodel_c
-{
-public:
-  bx_pcivga_c(void);
-  ~bx_pcivga_c(void);
-  virtual void   init(void);
-  virtual void   reset(unsigned type);
-
-private:
-
-  struct {
-    Bit8u pci_conf[256];
-  } s;
-
-  static Bit32u pci_read_handler(void *this_ptr, Bit8u address, unsigned io_len);
-  static void   pci_write_handler(void *this_ptr, Bit8u address, Bit32u value, unsigned io_len);
-#if !BX_USE_PCIVGA_SMF
-  Bit32u pci_read(Bit8u address, unsigned io_len);
-  void   pci_write(Bit8u address, Bit32u value, unsigned io_len);
-#endif
-};
diff --git a/tools/ioemu/iodev/pic.cc b/tools/ioemu/iodev/pic.cc
deleted file mode 100644 (file)
index f445550..0000000
+++ /dev/null
@@ -1,887 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: pic.cc,v 1.33 2003/08/05 09:19:36 akrisak Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-
-// Define BX_PLUGGABLE in files that can be compiled into plugins.  For
-// platforms that require a special tag on exported symbols, BX_PLUGGABLE 
-// is used to know when we are exporting symbols and when we are importing.
-#define BX_PLUGGABLE
-
-#include "bochs.h"
-
-#define LOG_THIS thePic->
-
-
-
-bx_pic_c *thePic = NULL;
-
-  int
-libpic_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
-{
-  thePic = new bx_pic_c ();
-  bx_devices.pluginPicDevice = thePic;
-  BX_REGISTER_DEVICE_DEVMODEL(plugin, type, thePic, BX_PLUGIN_PIC);
-  return(0); // Success
-}
-
-  void
-libpic_LTX_plugin_fini(void)
-{
-}
-
-
-bx_pic_c::bx_pic_c(void)
-{
-  put("PIC");
-  settype(PICLOG);
-}
-
-bx_pic_c::~bx_pic_c(void)
-{
-  // nothing for now
-}
-
-
-  void
-bx_pic_c::init(void)
-{
-  /* 8259 PIC (Programmable Interrupt Controller) */
-  DEV_register_ioread_handler(this, read_handler, 0x0020, "8259 PIC", 1);
-  DEV_register_ioread_handler(this, read_handler, 0x0021, "8259 PIC", 1);
-  DEV_register_ioread_handler(this, read_handler, 0x00A0, "8259 PIC", 1);
-  DEV_register_ioread_handler(this, read_handler, 0x00A1, "8259 PIC", 1);
-
-  DEV_register_iowrite_handler(this, write_handler, 0x0020, "8259 PIC", 1);
-  DEV_register_iowrite_handler(this, write_handler, 0x0021, "8259 PIC", 1);
-  DEV_register_iowrite_handler(this, write_handler, 0x00A0, "8259 PIC", 1);
-  DEV_register_iowrite_handler(this, write_handler, 0x00A1, "8259 PIC", 1);
-
-
-  BX_PIC_THIS s.master_pic.single_PIC = 0;
-  BX_PIC_THIS s.master_pic.interrupt_offset = 0x08; /* IRQ0 = INT 0x08 */
-  /* slave PIC connected to IRQ2 of master */
-  BX_PIC_THIS s.master_pic.u.slave_connect_mask = 0x04;
-  BX_PIC_THIS s.master_pic.sfnm = 0; /* normal nested mode */
-  BX_PIC_THIS s.master_pic.buffered_mode = 0; /* unbuffered mode */
-  BX_PIC_THIS s.master_pic.master_slave  = 0; /* no meaning, buffered_mode=0 */
-  BX_PIC_THIS s.master_pic.auto_eoi      = 0; /* manual EOI from CPU */
-  BX_PIC_THIS s.master_pic.imr           = 0xFF; /* all IRQ's initially masked */
-  BX_PIC_THIS s.master_pic.isr           = 0x00; /* no IRQ's in service */
-  BX_PIC_THIS s.master_pic.irr           = 0x00; /* no IRQ's requested */
-  BX_PIC_THIS s.master_pic.read_reg_select = 0; /* IRR */
-  BX_PIC_THIS s.master_pic.irq = 0;
-  BX_PIC_THIS s.master_pic.INT = 0;
-  BX_PIC_THIS s.master_pic.init.in_init = 0;
-  BX_PIC_THIS s.master_pic.init.requires_4 = 0;
-  BX_PIC_THIS s.master_pic.init.byte_expected = 0;
-  BX_PIC_THIS s.master_pic.special_mask = 0;
-  BX_PIC_THIS s.master_pic.lowest_priority = 7;
-  BX_PIC_THIS s.master_pic.polled = 0;
-  BX_PIC_THIS s.master_pic.rotate_on_autoeoi = 0;
-
-  BX_PIC_THIS s.slave_pic.single_PIC = 0;
-  BX_PIC_THIS s.slave_pic.interrupt_offset = 0x70; /* IRQ8 = INT 0x70 */
-  BX_PIC_THIS s.slave_pic.u.slave_id = 0x02; /* slave PIC connected to IRQ2 of master */
-  BX_PIC_THIS s.slave_pic.sfnm       = 0; /* normal nested mode */
-  BX_PIC_THIS s.slave_pic.buffered_mode = 0; /* unbuffered mode */
-  BX_PIC_THIS s.slave_pic.master_slave  = 0; /* no meaning, buffered_mode=0 */
-  BX_PIC_THIS s.slave_pic.auto_eoi      = 0; /* manual EOI from CPU */
-  BX_PIC_THIS s.slave_pic.imr           = 0xFF; /* all IRQ's initially masked */
-  BX_PIC_THIS s.slave_pic.isr           = 0x00; /* no IRQ's in service */
-  BX_PIC_THIS s.slave_pic.irr           = 0x00; /* no IRQ's requested */
-  BX_PIC_THIS s.slave_pic.read_reg_select = 0; /* IRR */
-  BX_PIC_THIS s.slave_pic.irq = 0;
-  BX_PIC_THIS s.slave_pic.INT = 0;
-  BX_PIC_THIS s.slave_pic.init.in_init = 0;
-  BX_PIC_THIS s.slave_pic.init.requires_4 = 0;
-  BX_PIC_THIS s.slave_pic.init.byte_expected = 0;
-  BX_PIC_THIS s.slave_pic.special_mask = 0;
-  BX_PIC_THIS s.slave_pic.lowest_priority = 7;
-  BX_PIC_THIS s.slave_pic.polled = 0;
-  BX_PIC_THIS s.slave_pic.rotate_on_autoeoi = 0;
-
-  for (unsigned i=0; i<8; i++) { /* all IRQ lines low */
-    BX_PIC_THIS s.master_pic.IRQ_line[i] = 0;
-    BX_PIC_THIS s.slave_pic.IRQ_line[i] = 0;
-  }
-}
-
-  void
-bx_pic_c::reset(unsigned type)
-{
-}
-
-  // static IO port read callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-  Bit32u
-bx_pic_c::read_handler(void *this_ptr, Bit32u address, unsigned io_len)
-{
-#if !BX_USE_PIC_SMF
-  bx_pic_c *class_ptr = (bx_pic_c *) this_ptr;
-
-  return( class_ptr->read(address, io_len) );
-}
-
-
-
-  Bit32u
-bx_pic_c::read(Bit32u address, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif // !BX_USE_PIC_SMF
-
-  BX_DEBUG(("IO read from %04x", (unsigned) address));
-
-  /*
-   8259A PIC
-   */
-
-  if((address == 0x20 || address == 0x21) && BX_PIC_THIS s.master_pic.polled) {
-    // In polled mode. Treat this as an interrupt acknowledge
-    clear_highest_interrupt(& BX_PIC_THIS s.master_pic);
-    BX_PIC_THIS s.master_pic.polled = 0;
-    service_master_pic();
-    return io_len==1?BX_PIC_THIS s.master_pic.irq:(BX_PIC_THIS s.master_pic.irq)<<8|(BX_PIC_THIS s.master_pic.irq);  // Return the current irq requested
-  }
-
-  if((address == 0xa0 || address == 0xa1) && BX_PIC_THIS s.slave_pic.polled) {
-    // In polled mode. Treat this as an interrupt acknowledge
-    clear_highest_interrupt(& BX_PIC_THIS s.slave_pic);
-    BX_PIC_THIS s.slave_pic.polled = 0;
-    service_slave_pic();
-    return io_len==1?BX_PIC_THIS s.slave_pic.irq:(BX_PIC_THIS s.slave_pic.irq)<<8|(BX_PIC_THIS s.slave_pic.irq);  // Return the current irq requested
-  }
-
-
-  switch (address) {
-    case 0x20:
-      if (BX_PIC_THIS s.master_pic.read_reg_select) { /* ISR */
-        BX_DEBUG(("read master ISR = %02x",
-                  (unsigned) BX_PIC_THIS s.master_pic.isr));
-       return(BX_PIC_THIS s.master_pic.isr);
-       }
-      else { /* IRR */
-        BX_DEBUG(("read master IRR = %02x",
-                 (unsigned) BX_PIC_THIS s.master_pic.irr));
-       return(BX_PIC_THIS s.master_pic.irr);
-       }
-      break;
-    case 0x21:
-      BX_DEBUG(("read master IMR = %02x",
-               (unsigned) BX_PIC_THIS s.master_pic.imr));
-      return(BX_PIC_THIS s.master_pic.imr);
-      break;
-    case 0xA0:
-      if (BX_PIC_THIS s.slave_pic.read_reg_select) { /* ISR */
-        BX_DEBUG(("read slave ISR = %02x",
-                  (unsigned) BX_PIC_THIS s.slave_pic.isr));
-       return(BX_PIC_THIS s.slave_pic.isr);
-       }
-      else { /* IRR */
-        BX_DEBUG(("read slave IRR = %02x",
-                  (unsigned) BX_PIC_THIS s.slave_pic.irr));
-       return(BX_PIC_THIS s.slave_pic.irr);
-       }
-      break;
-    case 0xA1:
-      BX_DEBUG(("read slave IMR = %02x",
-                (unsigned) BX_PIC_THIS s.slave_pic.imr));
-      return(BX_PIC_THIS s.slave_pic.imr);
-      break;
-    }
-
-  BX_PANIC(("io read to address %04x", (unsigned) address));
-  return(0); /* default if not found above */
-}
-
-
-  // static IO port write callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-  void
-bx_pic_c::write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len)
-{
-#if !BX_USE_PIC_SMF
-  bx_pic_c *class_ptr = (bx_pic_c *) this_ptr;
-
-  class_ptr->write(address, value, io_len);
-}
-
-  void
-bx_pic_c::write(Bit32u address, Bit32u value, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif // !BX_USE_PIC_SMF
-
-  BX_DEBUG(("IO write to %04x = %02x", (unsigned) address, (unsigned) value));
-
-  /*
-   8259A PIC
-   */
-
-  switch (address) {
-    case 0x20:
-      if (value & 0x10) { /* initialization command 1 */
-        BX_DEBUG(("master: init command 1 found"));
-        BX_DEBUG(("        requires 4 = %u", (unsigned) (value & 0x01) ));
-        BX_DEBUG(("        cascade mode: [0=cascade,1=single] %u",
-                  (unsigned) ((value & 0x02) >> 1)));
-        BX_PIC_THIS s.master_pic.init.in_init = 1;
-        BX_PIC_THIS s.master_pic.init.requires_4 = (value & 0x01);
-        BX_PIC_THIS s.master_pic.init.byte_expected = 2; /* operation command 2 */
-        BX_PIC_THIS s.master_pic.imr           = 0x00; /* clear the irq mask register */
-        BX_PIC_THIS s.master_pic.isr           = 0x00; /* no IRQ's in service */
-        BX_PIC_THIS s.master_pic.irr           = 0x00; /* no IRQ's requested */
-        BX_PIC_THIS s.master_pic.lowest_priority = 7;
-        BX_PIC_THIS s.master_pic.INT = 0; /* reprogramming clears previous INTR request */
-        BX_PIC_THIS s.master_pic.auto_eoi = 0;
-        BX_PIC_THIS s.master_pic.rotate_on_autoeoi = 0;
-        if (value & 0x02)
-          BX_PANIC(("master: ICW1: single mode not supported"));
-        if (value & 0x08) {
-          BX_PANIC(("master: ICW1: level sensitive mode not supported"));
-         }
-       else {
-          BX_DEBUG(("master: ICW1: edge triggered mode selected"));
-         }
-        BX_SET_INTR(0);
-        return;
-        }
-
-      if ( (value & 0x18) == 0x08 ) { /* OCW3 */
-        Bit8u special_mask, poll, read_op;
-
-        special_mask = (value & 0x60) >> 5;
-        poll         = (value & 0x04) >> 2;
-        read_op      = (value & 0x03);
-        if (poll) {
-          BX_PIC_THIS s.master_pic.polled = 1;
-          return;
-        }
-        if (read_op == 0x02) /* read IRR */
-         BX_PIC_THIS s.master_pic.read_reg_select = 0;
-        else if (read_op == 0x03) /* read ISR */
-         BX_PIC_THIS s.master_pic.read_reg_select = 1;
-        if (special_mask == 0x02) { /* cancel special mask */
-          BX_PIC_THIS s.master_pic.special_mask = 0;
-          }
-        else if (special_mask == 0x03) { /* set specific mask */
-          BX_PIC_THIS s.master_pic.special_mask = 1;
-          service_master_pic();
-          }
-        return;
-        }
-
-      /* OCW2 */
-      switch (value) {
-        case 0x00: // Rotate in auto eoi mode clear
-        case 0x80: // Rotate in auto eoi mode set
-          BX_PIC_THIS s.master_pic.rotate_on_autoeoi = (value != 0);
-          break;
-       case 0x0A: /* select read interrupt request register */
-         BX_PIC_THIS s.master_pic.read_reg_select = 0;
-         break;
-       case 0x0B: /* select read interrupt in-service register */
-         BX_PIC_THIS s.master_pic.read_reg_select = 1;
-         break;
-
-        case 0xA0: // Rotate on non-specific end of interrupt
-        case 0x20: /* end of interrupt command */
-
-          clear_highest_interrupt(& BX_PIC_THIS s.master_pic);
-
-          if(value == 0xA0) {// Rotate in Auto-EOI mode
-            BX_PIC_THIS s.master_pic.lowest_priority ++;
-            if(BX_PIC_THIS s.master_pic.lowest_priority > 7)
-              BX_PIC_THIS s.master_pic.lowest_priority = 0;
-          }
-
-          service_master_pic();
-          break;
-
-        case 0x40: // Intel PIC spec-sheet seems to indicate this should be ignored
-          BX_INFO(("IRQ no-op"));
-          break;
-
-        case 0x60: /* specific EOI 0 */
-        case 0x61: /* specific EOI 1 */
-        case 0x62: /* specific EOI 2 */
-        case 0x63: /* specific EOI 3 */
-        case 0x64: /* specific EOI 4 */
-        case 0x65: /* specific EOI 5 */
-        case 0x66: /* specific EOI 6 */
-        case 0x67: /* specific EOI 7 */
-          BX_PIC_THIS s.master_pic.isr &= ~(1 << (value-0x60));
-          service_master_pic();
-          break;
-
-        // IRQ lowest priority commands
-        case 0xC0: // 0 7 6 5 4 3 2 1
-        case 0xC1: // 1 0 7 6 5 4 3 2
-        case 0xC2: // 2 1 0 7 6 5 4 3
-        case 0xC3: // 3 2 1 0 7 6 5 4
-        case 0xC4: // 4 3 2 1 0 7 6 5
-        case 0xC5: // 5 4 3 2 1 0 7 6
-        case 0xC6: // 6 5 4 3 2 1 0 7
-        case 0xC7: // 7 6 5 4 3 2 1 0
-          BX_INFO(("IRQ lowest command 0x%x", value));
-          BX_PIC_THIS s.master_pic.lowest_priority = value - 0xC0;
-          break;
-
-        case 0xE0: // specific EOI and rotate 0
-        case 0xE1: // specific EOI and rotate 1
-        case 0xE2: // specific EOI and rotate 2
-        case 0xE3: // specific EOI and rotate 3
-        case 0xE4: // specific EOI and rotate 4
-        case 0xE5: // specific EOI and rotate 5
-        case 0xE6: // specific EOI and rotate 6
-        case 0xE7: // specific EOI and rotate 7
-          BX_PIC_THIS s.master_pic.isr &= ~(1 << (value-0xE0));
-          BX_PIC_THIS s.master_pic.lowest_priority = (value - 0xE0);
-          service_master_pic();
-
-          break;
-
-        default:
-          BX_PANIC(("write to port 20h = %02x", value));
-       } /* switch (value) */
-      break;
-
-    case 0x21:
-      /* initialization mode operation */
-      if (BX_PIC_THIS s.master_pic.init.in_init) {
-        switch (BX_PIC_THIS s.master_pic.init.byte_expected) {
-          case 2:
-            BX_PIC_THIS s.master_pic.interrupt_offset = value & 0xf8;
-            BX_PIC_THIS s.master_pic.init.byte_expected = 3;
-            BX_DEBUG(("master: init command 2 = %02x", (unsigned) value));
-            BX_DEBUG(("        offset = INT %02x",
-                      BX_PIC_THIS s.master_pic.interrupt_offset));
-            return;
-            break;
-          case 3:
-            BX_DEBUG(("master: init command 3 = %02x", (unsigned) value));
-            if (BX_PIC_THIS s.master_pic.init.requires_4) {
-              BX_PIC_THIS s.master_pic.init.byte_expected = 4;
-             }
-            else {
-              BX_PIC_THIS s.master_pic.init.in_init = 0;
-             }
-            return;
-            break;
-          case 4:
-            BX_DEBUG(("master: init command 4 = %02x", (unsigned) value));
-            if (value & 0x02) {
-              BX_DEBUG(("       auto EOI"));
-              BX_PIC_THIS s.master_pic.auto_eoi = 1;
-              }
-            else {
-              BX_DEBUG(("normal EOI interrupt"));
-              BX_PIC_THIS s.master_pic.auto_eoi = 0;
-              }
-           if (value & 0x01) {
-                 BX_DEBUG(("       80x86 mode"));
-           } else
-                 BX_PANIC(("       not 80x86 mode"));
-            BX_PIC_THIS s.master_pic.init.in_init = 0;
-            return;
-            break;
-          default:
-            BX_PANIC(("master expecting bad init command"));
-          }
-        }
-
-      /* normal operation */
-      BX_DEBUG(("setting master pic IMR to %02x", value));
-      BX_PIC_THIS s.master_pic.imr = value;
-      service_master_pic();
-      return;
-      break;
-
-    case 0xA0:
-      if (value & 0x10) { /* initialization command 1 */
-        BX_DEBUG(("slave: init command 1 found"));
-        BX_DEBUG(("       requires 4 = %u",
-            (unsigned) (value & 0x01) ));
-        BX_DEBUG(("       cascade mode: [0=cascade,1=single] %u",
-            (unsigned) ((value & 0x02) >> 1)));
-        BX_PIC_THIS s.slave_pic.init.in_init = 1;
-        BX_PIC_THIS s.slave_pic.init.requires_4 = (value & 0x01);
-        BX_PIC_THIS s.slave_pic.init.byte_expected = 2; /* operation command 2 */
-        BX_PIC_THIS s.slave_pic.imr           = 0x00; /* clear irq mask */
-        BX_PIC_THIS s.slave_pic.isr           = 0x00; /* no IRQ's in service */
-        BX_PIC_THIS s.slave_pic.irr           = 0x00; /* no IRQ's requested */
-        BX_PIC_THIS s.slave_pic.lowest_priority = 7;
-        BX_PIC_THIS s.slave_pic.INT = 0; /* reprogramming clears previous INTR request */
-        BX_PIC_THIS s.slave_pic.auto_eoi = 0;
-        BX_PIC_THIS s.slave_pic.rotate_on_autoeoi = 0;
-        if (value & 0x02)
-          BX_PANIC(("slave: ICW1: single mode not supported"));
-        if (value & 0x08) {
-          BX_PANIC(("slave: ICW1: level sensitive mode not supported"));
-         }
-       else {
-          BX_DEBUG(("slave: ICW1: edge triggered mode selected"));
-         }
-        return;
-        }
-
-      if ( (value & 0x18) == 0x08 ) { /* OCW3 */
-        Bit8u special_mask, poll, read_op;
-
-        special_mask = (value & 0x60) >> 5;
-        poll         = (value & 0x04) >> 2;
-        read_op      = (value & 0x03);
-        if (poll) {
-          BX_PIC_THIS s.slave_pic.polled = 1;
-          return;
-        }
-        if (read_op == 0x02) /* read IRR */
-         BX_PIC_THIS s.slave_pic.read_reg_select = 0;
-        else if (read_op == 0x03) /* read ISR */
-         BX_PIC_THIS s.slave_pic.read_reg_select = 1;
-        if (special_mask == 0x02) { /* cancel special mask */
-          BX_PIC_THIS s.slave_pic.special_mask = 0;
-          }
-        else if (special_mask == 0x03) { /* set specific mask */
-          BX_PIC_THIS s.slave_pic.special_mask = 1;
-          service_slave_pic();
-          }
-        return;
-        }
-
-      switch (value) {
-        case 0x00: // Rotate in auto eoi mode clear
-        case 0x80: // Rotate in auto eoi mode set
-          BX_PIC_THIS s.slave_pic.rotate_on_autoeoi = (value != 0);
-          break;
-
-       case 0x0A: /* select read interrupt request register */
-         BX_PIC_THIS s.slave_pic.read_reg_select = 0;
-         break;
-       case 0x0B: /* select read interrupt in-service register */
-         BX_PIC_THIS s.slave_pic.read_reg_select = 1;
-         break;
-
-        case 0xA0: // Rotate on non-specific end of interrupt
-        case 0x20: /* end of interrupt command */
-
-          clear_highest_interrupt(& BX_PIC_THIS s.slave_pic);
-
-          if(value == 0xA0) {// Rotate in Auto-EOI mode
-            BX_PIC_THIS s.slave_pic.lowest_priority ++;
-            if(BX_PIC_THIS s.slave_pic.lowest_priority > 7)
-              BX_PIC_THIS s.slave_pic.lowest_priority = 0;
-          }
-
-          service_slave_pic();
-          break;
-
-        case 0x40: // Intel PIC spec-sheet seems to indicate this should be ignored
-          BX_INFO(("IRQ no-op"));
-          break;
-
-        case 0x60: /* specific EOI 0 */
-        case 0x61: /* specific EOI 1 */
-        case 0x62: /* specific EOI 2 */
-        case 0x63: /* specific EOI 3 */
-        case 0x64: /* specific EOI 4 */
-        case 0x65: /* specific EOI 5 */
-        case 0x66: /* specific EOI 6 */
-        case 0x67: /* specific EOI 7 */
-          BX_PIC_THIS s.slave_pic.isr &= ~(1 << (value-0x60));
-          service_slave_pic();
-          break;
-
-        // IRQ lowest priority commands
-        case 0xC0: // 0 7 6 5 4 3 2 1
-        case 0xC1: // 1 0 7 6 5 4 3 2
-        case 0xC2: // 2 1 0 7 6 5 4 3
-        case 0xC3: // 3 2 1 0 7 6 5 4
-        case 0xC4: // 4 3 2 1 0 7 6 5
-        case 0xC5: // 5 4 3 2 1 0 7 6
-        case 0xC6: // 6 5 4 3 2 1 0 7
-        case 0xC7: // 7 6 5 4 3 2 1 0
-          BX_INFO(("IRQ lowest command 0x%x", value));
-          BX_PIC_THIS s.slave_pic.lowest_priority = value - 0xC0;
-          break;
-
-        case 0xE0: // specific EOI and rotate 0
-        case 0xE1: // specific EOI and rotate 1
-        case 0xE2: // specific EOI and rotate 2
-        case 0xE3: // specific EOI and rotate 3
-        case 0xE4: // specific EOI and rotate 4
-        case 0xE5: // specific EOI and rotate 5
-        case 0xE6: // specific EOI and rotate 6
-        case 0xE7: // specific EOI and rotate 7
-          BX_PIC_THIS s.slave_pic.isr &= ~(1 << (value-0xE0));
-          BX_PIC_THIS s.slave_pic.lowest_priority = (value - 0xE0);
-          service_slave_pic();
-
-          break;
-
-        default:
-          BX_PANIC(("write to port A0h = %02x", value));
-       } /* switch (value) */
-      break;
-
-    case 0xA1:
-      /* initialization mode operation */
-      if (BX_PIC_THIS s.slave_pic.init.in_init) {
-        switch (BX_PIC_THIS s.slave_pic.init.byte_expected) {
-          case 2:
-            BX_PIC_THIS s.slave_pic.interrupt_offset = value & 0xf8;
-            BX_PIC_THIS s.slave_pic.init.byte_expected = 3;
-            BX_DEBUG(("slave: init command 2 = %02x", (unsigned) value));
-            BX_DEBUG(("       offset = INT %02x",
-                      BX_PIC_THIS s.slave_pic.interrupt_offset));
-            return;
-            break;
-          case 3:
-            BX_DEBUG(("slave: init command 3 = %02x", (unsigned) value));
-            if (BX_PIC_THIS s.slave_pic.init.requires_4) {
-              BX_PIC_THIS s.slave_pic.init.byte_expected = 4;
-               } else {
-              BX_PIC_THIS s.slave_pic.init.in_init = 0;
-             }
-            return;
-            break;
-          case 4:
-            BX_DEBUG(("slave: init command 4 = %02x", (unsigned) value));
-            if (value & 0x02) {
-              BX_DEBUG(("       auto EOI"));
-              BX_PIC_THIS s.slave_pic.auto_eoi = 1;
-              }
-            else {
-              BX_DEBUG(("normal EOI interrupt"));
-              BX_PIC_THIS s.slave_pic.auto_eoi = 0;
-              }
-           if (value & 0x01) {
-                 BX_DEBUG(("       80x86 mode"));
-           } else
-                 BX_PANIC(("       not 80x86 mode"));
-            BX_PIC_THIS s.slave_pic.init.in_init = 0;
-            return;
-            break;
-          default:
-            BX_PANIC(("slave: expecting bad init command"));
-          }
-        }
-
-      /* normal operation */
-      BX_DEBUG(("setting slave pic IMR to %02x", value));
-      BX_PIC_THIS s.slave_pic.imr = value;
-      service_slave_pic();
-      return;
-      break;
-    } /* switch (address) */
-
-  return;
-}
-
-// new IRQ signal handling routines
-
-  void
-bx_pic_c::lower_irq(unsigned irq_no)
-{
-#if BX_SUPPORT_APIC
-  // forward this function call to the ioapic too
-  if (DEV_ioapic_present())
-    bx_devices.ioapic->untrigger_irq (irq_no, -1);
-#endif
-
-  if ((irq_no <= 7) && (BX_PIC_THIS s.master_pic.IRQ_line[irq_no])) {
-    BX_DEBUG(("IRQ line %d now low", (unsigned) irq_no));
-    BX_PIC_THIS s.master_pic.IRQ_line[irq_no] = 0;
-    BX_PIC_THIS s.master_pic.irr &= ~(1 << irq_no);
-    if ((BX_PIC_THIS s.master_pic.irr & ~BX_PIC_THIS s.master_pic.imr) == 0) {
-      BX_SET_INTR(0);
-      BX_PIC_THIS s.master_pic.INT = 0;
-    }
-  } else if ((irq_no > 7) && (irq_no <= 15) &&
-             (BX_PIC_THIS s.slave_pic.IRQ_line[irq_no-8])) {
-    BX_DEBUG(("IRQ line %d now low", (unsigned) irq_no));
-    BX_PIC_THIS s.slave_pic.IRQ_line[irq_no - 8] = 0;
-    BX_PIC_THIS s.slave_pic.irr &= ~(1 << (irq_no - 8));
-    if ((BX_PIC_THIS s.slave_pic.irr & ~BX_PIC_THIS s.slave_pic.imr) == 0) {
-      BX_PIC_THIS s.slave_pic.INT = 0;
-      lower_irq(2);
-    }
-  }
-}
-
-  void
-bx_pic_c::raise_irq(unsigned irq_no)
-{
-#if BX_SUPPORT_APIC
-  // forward this function call to the ioapic too
-  bx_devices.ioapic->trigger_irq (irq_no, -1);
-#endif
-
-  if ((irq_no <= 7) && (!BX_PIC_THIS s.master_pic.IRQ_line[irq_no])) {
-    BX_DEBUG(("IRQ line %d now high", (unsigned) irq_no));
-    BX_PIC_THIS s.master_pic.IRQ_line[irq_no] = 1;
-    BX_PIC_THIS s.master_pic.irr |= (1 << irq_no);
-    service_master_pic();
-  } else if ((irq_no > 7) && (irq_no <= 15) &&
-             (!BX_PIC_THIS s.slave_pic.IRQ_line[irq_no-8])) {
-    BX_DEBUG(("IRQ line %d now high", (unsigned) irq_no));
-    BX_PIC_THIS s.slave_pic.IRQ_line[irq_no - 8] = 1;
-    BX_PIC_THIS s.slave_pic.irr |= (1 << (irq_no - 8));
-    service_slave_pic();
-  }
-}
-
-void  bx_pic_c::clear_highest_interrupt(bx_pic_t *pic)
-{
-  int irq;
-  int lowest_priority;
-  int highest_priority;
-
-  /* clear highest current in service bit */
-  lowest_priority = pic->lowest_priority;
-  highest_priority = lowest_priority + 1;
-  if(highest_priority > 7)
-    highest_priority = 0;
-
-  irq = highest_priority;
-  do {
-    if (pic->isr & (1 << irq)) {
-      pic->isr &= ~(1 << irq);
-      break; /* Return mask of bit cleared. */
-    }
-
-    irq ++;
-    if(irq > 7)
-      irq = 0;
-  } while(irq != highest_priority);
-
-}
-
-  /* */
-  void
-bx_pic_c::service_master_pic(void)
-{
-  Bit8u unmasked_requests;
-  int irq;
-  Bit8u isr, max_irq;
-  Bit8u highest_priority = BX_PIC_THIS s.master_pic.lowest_priority + 1;
-  if(highest_priority > 7)
-    highest_priority = 0;
-
-  if (BX_PIC_THIS s.master_pic.INT) { /* last interrupt still not acknowleged */
-    return;
-    }
-
-  if (BX_PIC_THIS s.master_pic.special_mask) {
-    /* all priorities may be enabled.  check all IRR bits except ones
-     * which have corresponding ISR bits set
-     */
-    max_irq = highest_priority;
-    }
-  else { /* normal mode */
-    /* Find the highest priority IRQ that is enabled due to current ISR */
-    isr = BX_PIC_THIS s.master_pic.isr;
-    if (isr) {
-      max_irq = highest_priority;
-      while ( (isr & (1 << max_irq)) == 0) {
-        max_irq++;
-        if(max_irq > 7)
-          max_irq = 0;
-        }
-      if (max_irq == highest_priority ) return; /* Highest priority interrupt in-service,
-                                                 * no other priorities allowed */
-      if (max_irq > 7) BX_PANIC(("error in service_master_pic()"));
-      }
-    else
-      max_irq = highest_priority; /* 0..7 bits in ISR are cleared */
-    }
-
-
-  /* now, see if there are any higher priority requests */
-  if ((unmasked_requests = (BX_PIC_THIS s.master_pic.irr & ~BX_PIC_THIS s.master_pic.imr)) ) {
-    irq = highest_priority;
-    do {
-      /* for special mode, since we're looking at all IRQ's, skip if
-       * current IRQ is already in-service
-       */
-      if ( ! (BX_PIC_THIS s.master_pic.special_mask && ((BX_PIC_THIS s.master_pic.isr >> irq) & 0x01)) ) {
-        if (unmasked_requests & (1 << irq)) {
-          BX_DEBUG(("signalling IRQ(%u)", (unsigned) irq));
-          BX_PIC_THIS s.master_pic.INT = 1;
-          BX_SET_INTR(1);
-          BX_PIC_THIS s.master_pic.irq = irq;
-          return;
-          } /* if (unmasked_requests & ... */
-        } 
-
-      irq ++;
-      if(irq > 7)
-        irq = 0;
-      } while(irq != max_irq); /* do ... */
-    } /* if (unmasked_requests = ... */
-}
-
-
-  void
-bx_pic_c::service_slave_pic(void)
-{
-  Bit8u unmasked_requests;
-  int irq;
-  Bit8u isr, max_irq;
-  Bit8u highest_priority = BX_PIC_THIS s.slave_pic.lowest_priority + 1;
-  if(highest_priority > 7)
-    highest_priority = 0;
-
-  if (BX_PIC_THIS s.slave_pic.INT) { /* last interrupt still not acknowleged */
-    return;
-    }
-
-  if (BX_PIC_THIS s.slave_pic.special_mask) {
-    /* all priorities may be enabled.  check all IRR bits except ones
-     * which have corresponding ISR bits set
-     */
-    max_irq = highest_priority;
-  }
-  else { /* normal mode */
-    /* Find the highest priority IRQ that is enabled due to current ISR */
-    isr = BX_PIC_THIS s.slave_pic.isr;
-    if (isr) {
-      max_irq = highest_priority;
-      while ( (isr & (1 << max_irq)) == 0) {
-        max_irq++;
-        if(max_irq > 7)
-          max_irq = 0;
-        }
-      if (max_irq == highest_priority ) return; /* Highest priority interrupt in-service,
-                                                 * no other priorities allowed */
-      if (max_irq > 7) BX_PANIC(("error in service_master_pic()"));
-      }
-    else
-      max_irq = highest_priority; /* 0..7 bits in ISR are cleared */
-  }
-
-
-  /* now, see if there are any higher priority requests */
-  if ((unmasked_requests = (BX_PIC_THIS s.slave_pic.irr & ~BX_PIC_THIS s.slave_pic.imr)) ) {
-    irq = highest_priority;
-    do {
-      /* for special mode, since we're looking at all IRQ's, skip if
-       * current IRQ is already in-service
-       */
-      if ( ! (BX_PIC_THIS s.slave_pic.special_mask && ((BX_PIC_THIS s.slave_pic.isr >> irq) & 0x01)) ) {
-        if (unmasked_requests & (1 << irq)) {
-          BX_DEBUG(("slave: signalling IRQ(%u)", (unsigned) 8 + irq));
-
-          BX_PIC_THIS s.slave_pic.INT = 1;
-          BX_PIC_THIS s.slave_pic.irq = irq;
-          BX_PIC_THIS raise_irq(2); /* request IRQ 2 on master pic */
-          return;
-          } /* if (unmasked_requests & ... */
-        }
-
-        irq ++;
-        if(irq > 7)
-          irq = 0;
-      } while(irq != max_irq); /* do ... */
-    } /* if (unmasked_requests = ... */
-}
-
-
-  /* CPU handshakes with PIC after acknowledging interrupt */
-  Bit8u
-bx_pic_c::IAC(void)
-{
-  Bit8u vector;
-  Bit8u irq;
-
-  BX_SET_INTR(0);
-  BX_PIC_THIS s.master_pic.INT = 0;
-  BX_PIC_THIS s.master_pic.irr &= ~(1 << BX_PIC_THIS s.master_pic.irq);
-  // In autoeoi mode don't set the isr bit.
-  if(!BX_PIC_THIS s.master_pic.auto_eoi)
-    BX_PIC_THIS s.master_pic.isr |= (1 << BX_PIC_THIS s.master_pic.irq);
-  else if(BX_PIC_THIS s.master_pic.rotate_on_autoeoi)
-    BX_PIC_THIS s.master_pic.lowest_priority = BX_PIC_THIS s.master_pic.irq;
-
-  if (BX_PIC_THIS s.master_pic.irq != 2) {
-    irq    = BX_PIC_THIS s.master_pic.irq;
-    vector = irq + BX_PIC_THIS s.master_pic.interrupt_offset;
-    }
-  else { /* IRQ2 = slave pic IRQ8..15 */
-    BX_PIC_THIS s.slave_pic.INT = 0;
-    BX_PIC_THIS s.master_pic.IRQ_line[2] = 0;
-    irq    = BX_PIC_THIS s.slave_pic.irq;
-    vector = irq + BX_PIC_THIS s.slave_pic.interrupt_offset;
-    BX_PIC_THIS s.slave_pic.irr &= ~(1 << BX_PIC_THIS s.slave_pic.irq);
-    // In autoeoi mode don't set the isr bit.
-    if(!BX_PIC_THIS s.slave_pic.auto_eoi)
-      BX_PIC_THIS s.slave_pic.isr |= (1 << BX_PIC_THIS s.slave_pic.irq);
-    else if(BX_PIC_THIS s.slave_pic.rotate_on_autoeoi)
-      BX_PIC_THIS s.slave_pic.lowest_priority = BX_PIC_THIS s.slave_pic.irq;
-    service_slave_pic();
-    irq += 8; // for debug printing purposes
-    }
-
-  service_master_pic();
-
-  BX_DBG_IAC_REPORT(vector, irq);
-  return(vector);
-}
-  Bit8u
-bx_pic_c::irq_to_vec(Bit8u irq)
-{
-  Bit8u vector = 0;
-
-  if (irq >= 8 && irq <= 15)
-    vector = irq + BX_PIC_THIS s.slave_pic.interrupt_offset;
-  else if (irq != 2 && irq <= 7)
-    vector = irq + BX_PIC_THIS s.master_pic.interrupt_offset;
-  else
-    BX_ERROR(("invalid irq!\n"));
-
-  return vector;
-}
-
-  void
-bx_pic_c::show_pic_state(void)
-{
-#if defined(BX_DEBUGGER) && (BX_DEBUGGER == 1)
-dbg_printf("s.master_pic.imr = %02x\n", BX_PIC_THIS s.master_pic.imr);
-dbg_printf("s.master_pic.isr = %02x\n", BX_PIC_THIS s.master_pic.isr);
-dbg_printf("s.master_pic.irr = %02x\n", BX_PIC_THIS s.master_pic.irr);
-dbg_printf("s.master_pic.irq = %02x\n", BX_PIC_THIS s.master_pic.irq);
-dbg_printf("s.slave_pic.imr = %02x\n", BX_PIC_THIS s.slave_pic.imr);
-dbg_printf("s.slave_pic.isr = %02x\n", BX_PIC_THIS s.slave_pic.isr);
-dbg_printf("s.slave_pic.irr = %02x\n", BX_PIC_THIS s.slave_pic.irr);
-dbg_printf("s.slave_pic.irq = %02x\n", BX_PIC_THIS s.slave_pic.irq);
-#endif
-}
diff --git a/tools/ioemu/iodev/pic.h b/tools/ioemu/iodev/pic.h
deleted file mode 100644 (file)
index 378809d..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: pic.h,v 1.11 2003/08/04 16:03:09 akrisak Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-#if BX_USE_PIC_SMF
-#  define BX_PIC_SMF  static
-#  define BX_PIC_THIS thePic->
-#else
-#  define BX_PIC_SMF
-#  define BX_PIC_THIS this->
-#endif
-
-
-
-typedef struct {
-  Bit8u single_PIC;        /* 0=cascaded PIC, 1=master only */
-  Bit8u interrupt_offset;  /* programmable interrupt vector offset */
-  union {
-    Bit8u   slave_connect_mask; /* for master, a bit for each interrupt line
-                                   0=not connect to a slave, 1=connected */
-    Bit8u   slave_id;           /* for slave, id number of slave PIC */
-    } u;
-  Bit8u sfnm;              /* specially fully nested mode: 0=no, 1=yes*/
-  Bit8u buffered_mode;     /* 0=no buffered mode, 1=buffered mode */
-  Bit8u master_slave;      /* master/slave: 0=slave PIC, 1=master PIC */
-  Bit8u auto_eoi;          /* 0=manual EOI, 1=automatic EOI */
-  Bit8u imr;               /* interrupt mask register, 1=masked */
-  Bit8u isr;               /* in service register */
-  Bit8u irr;               /* interrupt request register */
-  Bit8u read_reg_select;   /* 0=IRR, 1=ISR */
-  Bit8u irq;               /* current IRQ number */
-  Bit8u lowest_priority;   /* current lowest priority irq */
-  bx_bool INT;             /* INT request pin of PIC */
-  bx_bool IRQ_line[8];     /* IRQ pins of PIC */
-  struct {
-    bx_bool    in_init;
-    bx_bool    requires_4;
-    int        byte_expected;
-    } init;
-  bx_bool special_mask;
-  bx_bool polled;            /* Set when poll command is issued. */
-  bx_bool rotate_on_autoeoi; /* Set when should rotate in auto-eoi mode. */
-  } bx_pic_t;
-
-
-class bx_pic_c : public bx_pic_stub_c {
-public:
-  bx_pic_c(void);
-  ~bx_pic_c(void);
-  virtual void   init(void);
-  virtual void   reset(unsigned type);
-  virtual void   lower_irq(unsigned irq_no);
-  virtual void   raise_irq(unsigned irq_no);
-  virtual Bit8u  IAC(void);
-  virtual void   show_pic_state(void);
-  Bit8u  irq_to_vec(Bit8u);
-
-private:
-  struct {
-    bx_pic_t master_pic;
-    bx_pic_t slave_pic;
-    } s;
-
-  static Bit32u read_handler(void *this_ptr, Bit32u address, unsigned io_len);
-  static void   write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);
-#if !BX_USE_PIC_SMF
-  Bit32u read(Bit32u address, unsigned io_len);
-  void   write(Bit32u address, Bit32u value, unsigned io_len);
-#endif
-
-  BX_PIC_SMF void   service_master_pic(void);
-  BX_PIC_SMF void   service_slave_pic(void);
-  BX_PIC_SMF void   clear_highest_interrupt(bx_pic_t *pic);
-  };
diff --git a/tools/ioemu/iodev/pit.cc b/tools/ioemu/iodev/pit.cc
deleted file mode 100644 (file)
index cf4777a..0000000
+++ /dev/null
@@ -1,856 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: pit.cc,v 1.15 2003/07/31 12:04:48 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2001  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-
-#include "bochs.h"
-
-#if (BX_USE_NEW_PIT==0)
-
-#define LOG_THIS bx_pit.
-
-
-// NOTES ON THE 8253/8254 PIT MODES
-
-// MODE 0: Interrupt on Terminal Count
-// ===================================
-// Writing new count action:
-//   loaded upon next CLK pulse.  counting doesn't start until GATE=1
-// GATE 0..1 transition:
-//   ???
-// GATE 1..0 transition:
-// counter expiration action:
-//   wraps to FFFF
-// * OUT rises until new count val or new control word for mode 0 written
-
-// MODE 1: Programmable Monoflop
-// =============================
-// Writing new count action:
-//   not effective for current process
-// GATE 0..1 transition:
-//   loads counter
-// counter expiration action:
-//   wraps to FFFF
-// NOTES:
-//   OUT rises until new count val or new control word for mode 0 written
-
-// MODE 2: Rate Generator
-// ======================
-// Writing new count action:
-//   ???
-// GATE 0..1 transition:
-//   loads initial count val and starts counting
-// counter expiration action:
-//   reloads after count expires
-// NOTES:
-// * after control word & initial count val N loaded, PIT starts
-//   counting upon next CLK pulse.
-// * when counter reaches 1, OUT drops to a low level, for one
-//   CLK cycle. (short peak pulse generated)
-// * afterwards, the initial count val is automatically reloaded
-//   and the PIT restarts the same counting operation again.
-// * distance of two OUT pulses is N CLK cycles long.
-// * GATE=1 enables, GATE=0 disables counter.
-// * if GATE drops to low level during counting operation and rises
-//     to high level later, PIT loads initial count value at the
-//     rise and starts counting.
-// * PIT starts counting after last data byte written if GATE=1
-// * if the output is low when the gate goes low, the output is
-//   immediately set high.
-
-// MODE 3: Square Wave Generator
-// =============================
-// Writing new count action:
-//   ???
-// GATE 0..1 transition:
-//   ???
-// counter expiration action:
-//   reloads after count expires
-// NOTES:
-// * initially OUT at a high level
-// * drop of GATE to a low level while OUT low, raises OUT to a high level
-// * a rise from a low to a high level at GATE (trigger pulse),
-//   loads the counter with the initial count value and starts
-//   counting operation
-// * a new count value supplied during the course of an active
-//   counting operation doesn't affect the current process.
-//   At the end of the current half cycle, the PIT loads the new value
-// * if the GATE line goes low, count is temporarily halted until GATE
-//   returns high
-// * if the OUT line is high when GATE goes low, OUT is forced low.
-// ??? different for odd/even counts
-
-// MODE 4: Software Triggered Pulse
-// ================================
-// Writing new count action:
-//   ???
-// GATE 0..1 transition:
-//   ???
-// counter expiration action:
-//   wraps to FFFF
-// NOTES:
-
-// MODE 5: Hardware Triggered Pulse
-// ================================
-// Writing new count action:
-//   ???
-// GATE 0..1 transition:
-//   ???
-// counter expiration action:
-//   wraps to FFFF
-// NOTES:
-
-
-
-#define BX_PIT_LATCH_MODE_LSB   10
-#define BX_PIT_LATCH_MODE_MSB   11
-#define BX_PIT_LATCH_MODE_16BIT 12
-
-
-bx_pit_c bx_pit;
-#if BX_USE_PIT_SMF
-#define this (&bx_pit)
-#endif
-
-#ifdef OUT
-#  undef OUT
-#endif
-
-
-bx_pit_c::bx_pit_c( void )
-{
-  put("PIT");
-  settype(PITLOG);
-  memset(&s, 0, sizeof(s));
-
-  /* 8254 PIT (Programmable Interval Timer) */
-
-  BX_PIT_THIS s.timer_handle[1] = BX_NULL_TIMER_HANDLE;
-  BX_PIT_THIS s.timer_handle[2] = BX_NULL_TIMER_HANDLE;
-}
-
-bx_pit_c::~bx_pit_c( void )
-{
-}
-
-
-  int
-bx_pit_c::init( void )
-{
-  DEV_register_irq(0, "8254 PIT");
-  DEV_register_ioread_handler(this, read_handler, 0x0040, "8254 PIT", 1);
-  DEV_register_ioread_handler(this, read_handler, 0x0041, "8254 PIT", 1);
-  DEV_register_ioread_handler(this, read_handler, 0x0042, "8254 PIT", 1);
-  DEV_register_ioread_handler(this, read_handler, 0x0043, "8254 PIT", 1);
-  DEV_register_ioread_handler(this, read_handler, 0x0061, "8254 PIT", 1);
-
-  DEV_register_iowrite_handler(this, write_handler, 0x0040, "8254 PIT", 1);
-  DEV_register_iowrite_handler(this, write_handler, 0x0041, "8254 PIT", 1);
-  DEV_register_iowrite_handler(this, write_handler, 0x0042, "8254 PIT", 1);
-  DEV_register_iowrite_handler(this, write_handler, 0x0043, "8254 PIT", 1);
-  DEV_register_iowrite_handler(this, write_handler, 0x0061, "8254 PIT", 1);
-
-  BX_PIT_THIS s.speaker_data_on = 0;
-  BX_PIT_THIS s.refresh_clock_div2 = 0;
-
-  BX_PIT_THIS s.timer[0].mode        = 3;  /* periodic rate generator */
-  BX_PIT_THIS s.timer[0].latch_mode  = BX_PIT_LATCH_MODE_16BIT;
-  BX_PIT_THIS s.timer[0].input_latch_value = 0;
-  BX_PIT_THIS s.timer[0].input_latch_toggle = 0;
-  BX_PIT_THIS s.timer[0].output_latch_value = 0;
-  BX_PIT_THIS s.timer[0].output_latch_toggle = 0;
-  BX_PIT_THIS s.timer[0].output_latch_full = 0;
-  BX_PIT_THIS s.timer[0].counter_max = 0;  /* 0xFFFF + 1 : (1193182 / 65535 = 18.2Hz) */
-  BX_PIT_THIS s.timer[0].counter     = 0;  /* 0xFFFF + 1 : (1193182 / 65535 = 18.2Hz) */
-  BX_PIT_THIS s.timer[0].bcd_mode    = 0;  /* binary counting mode */
-  BX_PIT_THIS s.timer[0].GATE        = 1;  /* GATE tied to + logic */
-  BX_PIT_THIS s.timer[0].OUT         = 1;
-  BX_PIT_THIS s.timer[0].active      = 0;
-
-  BX_PIT_THIS s.timer[1].mode        = 3;  /* periodic rate generator */
-  BX_PIT_THIS s.timer[1].latch_mode  = BX_PIT_LATCH_MODE_16BIT;
-  BX_PIT_THIS s.timer[1].input_latch_value = 0;
-  BX_PIT_THIS s.timer[1].input_latch_toggle = 0;
-  BX_PIT_THIS s.timer[1].output_latch_value = 0;
-  BX_PIT_THIS s.timer[1].output_latch_toggle = 0;
-  BX_PIT_THIS s.timer[1].output_latch_full = 0;
-  BX_PIT_THIS s.timer[1].counter_max = 0;  /* 0xFFFF + 1 : (1193182 / 65535 = 18.2Hz) */
-  BX_PIT_THIS s.timer[1].counter     = 0;  /* 0xFFFF + 1 : (1193182 / 65535 = 18.2Hz) */
-  BX_PIT_THIS s.timer[1].bcd_mode    = 0;  /* binary counting mode */
-  BX_PIT_THIS s.timer[1].GATE        = 1;  /* GATE tied to + logic */
-  BX_PIT_THIS s.timer[1].OUT         = 1;
-  BX_PIT_THIS s.timer[1].active      = 0;
-
-  BX_PIT_THIS s.timer[2].mode        = 3;  /* periodic rate generator */
-  BX_PIT_THIS s.timer[2].latch_mode  = BX_PIT_LATCH_MODE_16BIT;
-  BX_PIT_THIS s.timer[2].input_latch_value = 0;
-  BX_PIT_THIS s.timer[2].input_latch_toggle = 0;
-  BX_PIT_THIS s.timer[2].output_latch_value = 0;
-  BX_PIT_THIS s.timer[2].output_latch_toggle = 0;
-  BX_PIT_THIS s.timer[2].output_latch_full = 0;
-  BX_PIT_THIS s.timer[2].counter_max = 0;  /* 0xFFFF + 1 : (1193182 / 65535 = 18.2Hz) */
-  BX_PIT_THIS s.timer[2].counter     = 0;  /* 0xFFFF + 1 : (1193182 / 65535 = 18.2Hz) */
-  BX_PIT_THIS s.timer[2].bcd_mode    = 0;  /* binary counting mode */
-  BX_PIT_THIS s.timer[2].GATE        = 0;  /* timer2 gate controlled by port 61h bit 0 */
-  BX_PIT_THIS s.timer[2].OUT         = 1;
-  BX_PIT_THIS s.timer[2].active      = 0;
-
-  return(1);
-}
-
-void bx_pit_c::reset(unsigned type) {
-}
-
-  // static IO port read callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-  Bit32u
-bx_pit_c::read_handler(void *this_ptr, Bit32u address, unsigned io_len)
-{
-#if !BX_USE_PIT_SMF
-  bx_pit_c *class_ptr = (bx_pit_c *) this_ptr;
-
-  return( class_ptr->read(address, io_len) );
-}
-
-
-  Bit32u
-bx_pit_c::read( Bit32u   address, unsigned int io_len )
-{
-#else
-  UNUSED(this_ptr);
-#endif  // !BX_USE_PIT_SMF
-  if (bx_dbg.pit)
-    BX_INFO(("pit: io read from port %04x", (unsigned) address));
-
-  switch (address) {
-    case 0x40: /* timer 0 - system ticks */
-      return( read_counter(0) );
-      break;
-
-    case 0x42: /* timer 2 read */
-      return( read_counter(2) );
-      break;
-
-    case 0x61:
-      /* AT, port 61h */
-      BX_PIT_THIS s.refresh_clock_div2 = !BX_PIT_THIS s.refresh_clock_div2;
-      return( (BX_PIT_THIS s.timer[2].OUT<<5) |
-              (BX_PIT_THIS s.refresh_clock_div2<<4) |
-              (BX_PIT_THIS s.speaker_data_on<<1) |
-              (BX_PIT_THIS s.timer[2].GATE) );
-      break;
-
-    default:
-      BX_PANIC(("pit: unsupported io read from port %04x", address));
-    }
-  return(0); /* keep compiler happy */
-}
-
-
-  // static IO port write callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-  void
-bx_pit_c::write_handler(void *this_ptr, Bit32u address, Bit32u dvalue, unsigned io_len)
-{
-#if !BX_USE_PIT_SMF
-  bx_pit_c *class_ptr = (bx_pit_c *) this_ptr;
-
-  class_ptr->write(address, dvalue, io_len);
-}
-
-  void
-bx_pit_c::write( Bit32u   address, Bit32u   dvalue,
-                unsigned int io_len )
-{
-#else
-  UNUSED(this_ptr);
-#endif  // !BX_USE_PIT_SMF
-  Bit8u    command, mode, bcd_mode;
-  Bit8u   value;
-
-  value = (Bit8u  ) dvalue;
-
-  if (bx_dbg.pit)
-    BX_INFO(("pit: write to port %04x = %02x",
-      (unsigned) address, (unsigned) value));
-
-  switch (address) {
-    case 0x40: /* timer 0: write count register */
-      write_count_reg( value, 0 );
-      break;
-
-    case 0x41: /* timer 1: write count register */
-      write_count_reg( value, 1 );
-      break;
-
-    case 0x42: /* timer 2: write count register */
-      write_count_reg( value, 2 );
-      break;
-
-    case 0x43: /* timer 0-2 mode control */
-      /* |7 6 5 4|3 2 1|0|
-       * |-------|-----|-|
-       * |command|mode |bcd/binary|
-       */
-      command  = value >> 4;
-      mode     = (value >> 1) & 0x07;
-      bcd_mode = value & 0x01;
-#if 0
-BX_INFO(("timer 0-2 mode control: comm:%02x mode:%02x bcd_mode:%u",
-  (unsigned) command, (unsigned) mode, (unsigned) bcd_mode));
-#endif
-
-      if ( (mode > 5) || (command > 0x0e) )
-        BX_PANIC(("pit: outp(43h)=%02xh out of range", (unsigned) value));
-      if (bcd_mode)
-        BX_PANIC(("pit: outp(43h)=%02xh: bcd mode unhandled",
-          (unsigned) bcd_mode));
-
-      switch (command) {
-        case 0x0: /* timer 0: counter latch */
-          latch( 0 );
-          break;
-
-        case 0x1: /* timer 0: LSB mode */
-        case 0x2: /* timer 0: MSB mode */
-          BX_PANIC(("pit: outp(43h): command %02xh unhandled",
-            (unsigned) command));
-          break;
-        case 0x3: /* timer 0: 16-bit mode */
-          BX_PIT_THIS s.timer[0].mode = mode;
-          BX_PIT_THIS s.timer[0].latch_mode   = BX_PIT_LATCH_MODE_16BIT;
-          BX_PIT_THIS s.timer[0].input_latch_value = 0;
-          BX_PIT_THIS s.timer[0].input_latch_toggle = 0;
-          BX_PIT_THIS s.timer[0].bcd_mode    = bcd_mode;
-          if ( (mode!=3 && mode!=2 && mode!=0) || bcd_mode!=0 )
-            BX_PANIC(("pit: outp(43h): comm 3, mode %02x, bcd %02x unhandled",
-              (unsigned) mode, bcd_mode));
-          break;
-        case 0x4: /* timer 1: counter latch */
-          latch( 1 );
-          break;
-
-        case 0x5: /* timer 1: LSB mode */
-        case 0x6: /* timer 1: MSB mode */
-          BX_INFO(("pit: outp(43h): command %02xh unhandled (ignored)",
-            (unsigned) command));
-          break;
-        case 0x7: /* timer 1: 16-bit mode */
-          BX_PIT_THIS s.timer[1].mode = mode;
-          BX_PIT_THIS s.timer[1].latch_mode   = BX_PIT_LATCH_MODE_16BIT;
-          BX_PIT_THIS s.timer[1].input_latch_value = 0;
-          BX_PIT_THIS s.timer[1].input_latch_toggle = 0;
-          BX_PIT_THIS s.timer[1].bcd_mode    = bcd_mode;
-          if ( (mode!=3 && mode!=2 && mode!=0) || bcd_mode!=0 )
-            BX_PANIC(("pit: outp(43h): comm 7, mode %02x, bcd %02x unhandled",
-              (unsigned) mode, bcd_mode));
-          break;
-        case 0x8: /* timer 2: counter latch */
-          latch( 2 );
-          break;
-
-        case 0x9: /* timer 2: LSB mode */
-        case 0xa: /* timer 2: MSB mode */
-          BX_PANIC(("pit: outp(43h): command %02xh unhandled",
-            (unsigned) command));
-          break;
-        case 0xb: /* timer 2: 16-bit mode */
-          BX_PIT_THIS s.timer[2].mode = mode;
-          BX_PIT_THIS s.timer[2].latch_mode   = BX_PIT_LATCH_MODE_16BIT;
-          BX_PIT_THIS s.timer[2].input_latch_value = 0;
-          BX_PIT_THIS s.timer[2].input_latch_toggle = 0;
-          BX_PIT_THIS s.timer[2].bcd_mode    = bcd_mode;
-          if ( (mode!=3 && mode!=2 && mode!=0) || bcd_mode!=0 )
-            BX_PANIC(("pit: outp(43h): comm Bh, mode %02x, bcd %02x unhandled",
-              (unsigned) mode, bcd_mode));
-          break;
-#if 0
-        case 0xd: /* general counter latch */
-          if (value & 0x08) /* select counter 2 */
-            latch( 2 );
-          if (value & 0x04) /* select counter 1 */
-            latch( 1 );
-          if (value & 0x02) /* select counter 0 */
-            latch( 0 );
-          break;
-
-        case 0xe: /* latch status of timers */
-          BX_PANIC(("pit: outp(43h): command %02xh unhandled",
-            (unsigned) command);
-          break;
-#endif
-        case 0x0c: case 0x0d: case 0x0e: case 0x0f:
-          BX_INFO(("pit: ignoring 8254 command %u", (unsigned) command));
-          break;
-
-        default: /* 0xc & 0xf */
-          BX_PANIC(("pit: outp(43h) command %1xh unhandled",
-            (unsigned) command));
-          break;
-        }
-      break;
-
-    case 0x61:
-      BX_PIT_THIS s.speaker_data_on = (value >> 1) & 0x01;
-/*??? only on AT+ */
-      set_GATE(2, value & 0x01);
-#if BX_CPU_LEVEL < 2
-      /* ??? XT: */
-      bx_kbd_port61h_write(value);
-#endif
-      break;
-
-    default:
-      BX_PANIC(("pit: unsupported io write to port %04x = %02x",
-        (unsigned) address, (unsigned) value));
-    }
-}
-
-
-
-
-  void
-bx_pit_c::write_count_reg( Bit8u   value, unsigned timerid )
-{
-  bx_bool xfer_complete;
-
-  switch ( BX_PIT_THIS s.timer[timerid].latch_mode ) {
-    case BX_PIT_LATCH_MODE_16BIT: /* write1=LSB, write2=MSB */
-      if (BX_PIT_THIS s.timer[timerid].input_latch_toggle==0) {
-        BX_PIT_THIS s.timer[timerid].input_latch_value = value;
-        BX_PIT_THIS s.timer[timerid].input_latch_toggle = 1;
-        xfer_complete = 0;
-        if (bx_dbg.pit)
-          BX_INFO(("pit: BX_PIT_THIS s.timer[timerid] write L = %02x", (unsigned) value));
-        }
-      else {
-        BX_PIT_THIS s.timer[timerid].input_latch_value |= (value << 8);
-        BX_PIT_THIS s.timer[timerid].input_latch_toggle = 0;
-        xfer_complete = 1;
-        if (bx_dbg.pit)
-          BX_INFO(("pit: BX_PIT_THIS s.timer[timerid] write H = %02x", (unsigned) value));
-        }
-      break;
-
-    case BX_PIT_LATCH_MODE_MSB: /* write1=MSB, LSB=0 */
-      BX_PIT_THIS s.timer[timerid].input_latch_value = (value << 8);
-      xfer_complete = 1;
-      if (bx_dbg.pit)
-        BX_INFO(("pit: BX_PIT_THIS s.timer[timerid] write H = %02x", (unsigned) value));
-      break;
-
-    case BX_PIT_LATCH_MODE_LSB: /* write1=LSB, MSB=0 */
-      BX_PIT_THIS s.timer[timerid].input_latch_value = value;
-      xfer_complete = 1;
-      if (bx_dbg.pit)
-        BX_INFO(("pit: BX_PIT_THIS s.timer[timerid] write L = %02x", (unsigned) value));
-      break;
-
-    default:
-      BX_PANIC(("write_count_reg: latch_mode unknown"));
-      xfer_complete = 0;
-    }
-
-  if (xfer_complete) {
-    BX_PIT_THIS s.timer[timerid].counter_max = BX_PIT_THIS s.timer[timerid].input_latch_value;
-
-    // reprogramming counter clears latch
-    BX_PIT_THIS s.timer[timerid].output_latch_full = 0;
-
-    // counter bounds
-    // mode      minimum    maximum
-    //  0           1          0
-    //  1           1          0
-    //  2           2          0
-    //  3           2          0
-    //  4           1          0
-    //  5           1          0
-    switch (BX_PIT_THIS s.timer[timerid].mode) {
-      case 0:
-        BX_PIT_THIS s.timer[timerid].counter = BX_PIT_THIS s.timer[timerid].counter_max;
-        BX_PIT_THIS s.timer[timerid].active = 1;
-        if (BX_PIT_THIS s.timer[timerid].GATE) {
-          BX_PIT_THIS s.timer[timerid].OUT = 0; // OUT pin starts low
-          start( timerid );
-          }
-        break;
-      case 1:
-        BX_PANIC(("pit:write_count_reg(%u): mode1 unsupported",
-                 timerid));
-        break;
-      case 2:
-        if ( BX_PIT_THIS s.timer[timerid].counter_max == 1 )
-          BX_PANIC(("pit:write_count_reg(%u): mode %u counter_max=1",
-                   timerid, (unsigned) BX_PIT_THIS s.timer[timerid].mode));
-        if ( BX_PIT_THIS s.timer[timerid].GATE && !BX_PIT_THIS s.timer[timerid].active ) {
-          // software triggered
-          BX_PIT_THIS s.timer[timerid].counter = BX_PIT_THIS s.timer[timerid].counter_max;
-          BX_PIT_THIS s.timer[timerid].active  = 1;
-          BX_PIT_THIS s.timer[timerid].OUT     = 1; // initially set high
-          start( timerid );
-          }
-        break;
-      case 3:
-        if ( BX_PIT_THIS s.timer[timerid].counter_max == 1 )
-          BX_PANIC(("pit:write_count_reg(%u): mode %u counter_max=1",
-                   timerid, (unsigned) BX_PIT_THIS s.timer[timerid].mode));
-        BX_PIT_THIS s.timer[timerid].counter_max = BX_PIT_THIS s.timer[timerid].counter_max & 0xfffe;
-        if ( BX_PIT_THIS s.timer[timerid].GATE && !BX_PIT_THIS s.timer[timerid].active ) {
-          // software triggered
-          BX_PIT_THIS s.timer[timerid].counter = BX_PIT_THIS s.timer[timerid].counter_max;
-          BX_PIT_THIS s.timer[timerid].active  = 1;
-          BX_PIT_THIS s.timer[timerid].OUT     = 1; // initially set high
-          start( timerid );
-          }
-        break;
-      case 4:
-        BX_PANIC(("pit:write_count_reg(%u): mode4 unsupported",
-                 timerid));
-        break;
-      case 5:
-        BX_PANIC(("pit:write_count_reg(%u): mode5 unsupported",
-                 timerid));
-        break;
-      }
-    }
-}
-
-
-  Bit8u
-bx_pit_c::read_counter( unsigned timerid )
-{
-  Bit16u  counter_value;
-  Bit8u    retval;
-
-  if (BX_PIT_THIS s.timer[timerid].output_latch_full) { /* latched read */
-    counter_value = BX_PIT_THIS s.timer[timerid].output_latch_value;
-    }
-  else { /* direct unlatched read */
-    counter_value = BX_PIT_THIS s.timer[timerid].counter;
-BX_INFO(("CV=%04x", (unsigned) BX_PIT_THIS s.timer[timerid].counter));
-    }
-
-  switch (BX_PIT_THIS s.timer[timerid].latch_mode) {
-    case BX_PIT_LATCH_MODE_LSB:
-      retval = (Bit8u  ) counter_value;
-      BX_PIT_THIS s.timer[timerid].output_latch_full = 0;
-      break;
-    case BX_PIT_LATCH_MODE_MSB:
-      retval = (Bit8u  ) ( counter_value >> 8 );
-      BX_PIT_THIS s.timer[timerid].output_latch_full = 0;
-      break;
-    case BX_PIT_LATCH_MODE_16BIT:
-      if (BX_PIT_THIS s.timer[timerid].output_latch_toggle==0) { /* LSB 1st */
-        retval = (Bit8u  ) counter_value;
-        }
-      else { /* MSB 2nd */
-        retval = (Bit8u  ) ( counter_value >> 8 );
-        }
-      BX_PIT_THIS s.timer[timerid].output_latch_toggle = !BX_PIT_THIS s.timer[timerid].output_latch_toggle;
-      if (BX_PIT_THIS s.timer[timerid].output_latch_toggle == 0)
-        BX_PIT_THIS s.timer[timerid].output_latch_full = 0;
-      break;
-    default:
-      BX_PANIC(("pit: io read from port 40h: unknown latch mode"));
-      retval = 0; /* keep compiler happy */
-    }
-  return( retval );
-}
-
-
-  void
-bx_pit_c::latch( unsigned timerid )
-{
-  /* subsequent counter latch commands are ignored until value read out */
-  if (BX_PIT_THIS s.timer[timerid].output_latch_full) {
-    BX_INFO(("pit: pit(%u) latch: output latch full, ignoring",
-              timerid));
-    return;
-    }
-
-  BX_PIT_THIS s.timer[timerid].output_latch_value = BX_PIT_THIS s.timer[timerid].counter;
-
-  if (bx_dbg.pit)
-    BX_INFO(("pit: latch_value = %u", (unsigned) BX_PIT_THIS s.timer[timerid].output_latch_value));
-  BX_PIT_THIS s.timer[timerid].output_latch_toggle = 0;
-  BX_PIT_THIS s.timer[timerid].output_latch_full   = 1;
-}
-
-  void
-bx_pit_c::set_GATE(unsigned pit_id, unsigned value)
-{
-  // GATE's for Timer 0 & Timer 1 are tied high.
-  if (pit_id != 2)
-    BX_PANIC(("pit:set_GATE: pit_id != 2"));
-
-  value = (value > 0);
-
-  /* if no transition of GATE input line, then nothing to do */
-  if (value == BX_PIT_THIS s.timer[2].GATE)
-    return;
-
-  if (value) { /* PIT2: GATE transition from 0 to 1 */
-    BX_PIT_THIS s.timer[2].GATE  = 1;
-    switch ( BX_PIT_THIS s.timer[2].mode ) {
-      case 0:
-        BX_PIT_THIS s.timer[2].counter = BX_PIT_THIS s.timer[2].counter_max;
-        if (BX_PIT_THIS s.timer[2].active) {
-          BX_PIT_THIS s.timer[2].OUT = 0;
-          }
-        start( 2 );
-        break;
-      case 2:
-        // begin counting, reload counter
-        BX_PIT_THIS s.timer[2].active = 1;
-        BX_PIT_THIS s.timer[2].OUT = 1;
-        BX_PIT_THIS s.timer[2].counter = BX_PIT_THIS s.timer[2].counter_max;
-        start( 2 );
-        break;
-      case 3:
-        // begin counting, reload counter
-        BX_PIT_THIS s.timer[2].active = 1;
-        BX_PIT_THIS s.timer[2].OUT = 1;
-        BX_PIT_THIS s.timer[2].counter = BX_PIT_THIS s.timer[2].counter_max;
-        start( 2 );
-        break;
-      case 1:
-      case 4:
-      case 5:
-      default:
-        BX_PANIC(("bx_pit_c::set_GATE: unhandled timer2 mode %u",
-                 (unsigned) BX_PIT_THIS s.timer[2].mode));
-      }
-    }
-  else {       // PIT2: GATE transition from 1 to 0, deactivate
-    BX_PIT_THIS s.timer[2].GATE  = 0;
-    switch ( BX_PIT_THIS s.timer[2].mode ) {
-      case 0:
-        break;
-      case 2:
-        // 1) stops count, 2) OUT goes immediately high
-        BX_PIT_THIS s.timer[2].active = 0;
-        BX_PIT_THIS s.timer[2].OUT = 1;
-        break;
-      case 3:
-        // 1) stops count, 2) OUT goes immediately high
-        BX_PIT_THIS s.timer[2].active = 0;
-        BX_PIT_THIS s.timer[2].OUT = 1;
-        break;
-      case 1:
-      case 4:
-      case 5:
-      default:
-        BX_PANIC(("bx_pit_c::set_GATE: unhandled timer2 mode %u",
-                 (unsigned) BX_PIT_THIS s.timer[2].mode));
-      }
-    }
-}
-
-
-  void
-bx_pit_c::start(unsigned timerid)
-{
-  unsigned long period_hz;
-
-  if (BX_PIT_THIS s.timer[timerid].counter_max == 0x0000) {
-    period_hz   = 1193182 / 65536;
-    }
-  else {
-    period_hz = 1193182 / BX_PIT_THIS s.timer[timerid].counter_max;
-    }
-  BX_INFO(("timer%u period set to %lu hz", timerid, period_hz));
-
-
-  switch (BX_PIT_THIS s.timer[timerid].mode) {
-    case 0: /* single timeout */
-      break;
-    case 1: /* retriggerable one-shot */
-      BX_PANIC(("start: mode %u unhandled",
-               (unsigned) BX_PIT_THIS s.timer[timerid].mode));
-      break;
-    case 2: /* rate generator */
-      break;
-    case 3: /* square wave mode */
-      break;
-    case 4: /* software triggered strobe */
-      BX_PANIC(("start: mode %u unhandled",
-               (unsigned) BX_PIT_THIS s.timer[timerid].mode));
-      break;
-    case 5: /* hardware retriggerable strobe */
-      BX_PANIC(("start: mode %u unhandled",
-               (unsigned) BX_PIT_THIS s.timer[timerid].mode));
-      break;
-    default:
-      BX_PANIC(("start: timer%u has bad mode",
-               (unsigned) BX_PIT_THIS s.timer[timerid].mode));
-    }
-}
-
-
-
-
-  int
-bx_pit_c::SaveState( class state_file *fd )
-{
-  fd->write_check ("8254 start");
-  fd->write (&BX_PIT_THIS s, sizeof (BX_PIT_THIS s));
-  fd->write_check ("8254 end");
-  return(0);
-}
-
-
-  int
-bx_pit_c::LoadState( class state_file *fd )
-{
-  fd->read_check ("8254 start");
-  fd->read (&BX_PIT_THIS s, sizeof (BX_PIT_THIS s));
-  fd->read_check ("8254 end");
-  return(0);
-}
-
-
-#if 0
-  void
-bx_kbd_port61h_write(Bit8u   value)
-{
-//  PcError("KBD_PORT61H_WRITE(): not implemented yet");
-  UNUSED( value );
-}
-#endif
-
-
-  bx_bool
-bx_pit_c::periodic( Bit32u   usec_delta )
-{
-  bx_bool prev_timer0_out;
-
-  prev_timer0_out = BX_PIT_THIS s.timer[0].OUT;
-
-  for (unsigned i = 0; i < 3; i++) {
-    // is timer enabled and active?
-    if ( BX_PIT_THIS s.timer[i].GATE && BX_PIT_THIS s.timer[i].active ) {
-      switch ( BX_PIT_THIS s.timer[i].mode ) {
-        case 0: // Mode 0: Single Timeout
-          // wraps after count expires
-          if ( BX_PIT_THIS s.timer[i].counter == 0 ) {
-            // counter previously expired, wrap counter
-            BX_PIT_THIS s.timer[i].counter = 0xffff;
-            }
-          else if ( usec_delta >= BX_PIT_THIS s.timer[i].counter ) {
-            // counter expired
-            BX_PIT_THIS s.timer[i].counter = 0;
-            BX_PIT_THIS s.timer[i].OUT     = 1;
-            }
-          else {
-            // decrement counter by elapsed useconds
-            BX_PIT_THIS s.timer[i].counter -= (Bit16u ) usec_delta;
-            }
-          break;
-
-        case 1: // Mode 1: Retriggerable One-Shot
-          // wraps after count expires
-          BX_PANIC(("bx_pit_c::periodic: bad mode: timer[%u], mode %u",
-                        i, (unsigned) BX_PIT_THIS s.timer[i].mode));
-          break;
-
-        case 2: // Mode 2: Rate Generator
-          // reloads after count expires
-          // OUT is low when counter=1, high otherwise
-          // min count=2, max count=0
-          if ( BX_PIT_THIS s.timer[i].counter == 0 ) {
-            // max counter val, just wrap
-            BX_PIT_THIS s.timer[i].counter = 0xffff;
-            BX_PIT_THIS s.timer[i].OUT     = 1;
-            }
-          else if ( BX_PIT_THIS s.timer[i].counter == 1 ) {
-            // counter previously expired, reload
-            BX_PIT_THIS s.timer[i].counter = BX_PIT_THIS s.timer[i].counter_max;
-            BX_PIT_THIS s.timer[i].OUT     = 1;
-            }
-          else if ( (BX_PIT_THIS s.timer[i].counter == 2) ||
-                    (usec_delta >= (Bit32u(BX_PIT_THIS s.timer[i].counter) - 1)) ) {
-            // in either case, counter will reach 1
-            BX_PIT_THIS s.timer[i].counter = 1;
-            BX_PIT_THIS s.timer[i].OUT = 0;
-            }
-          else {
-            // decrement counter by elapsed useconds
-            BX_PIT_THIS s.timer[i].counter -= (Bit16u ) usec_delta;
-            }
-          break;
-
-        case 3: // Mode 3: Square Wave Mode
-          // reloads after count expires
-          // min count=2, max count=0
-          if ( BX_PIT_THIS s.timer[i].counter == 0 ) {
-            // max count, dec by 2
-            BX_PIT_THIS s.timer[i].counter = 0xfffe;
-            }
-          else if ( (BX_PIT_THIS s.timer[i].counter <= 2) ||
-                    ( (usec_delta*2) >= BX_PIT_THIS s.timer[i].counter ) ) {
-            // counter expired, reload
-            BX_PIT_THIS s.timer[i].counter = BX_PIT_THIS s.timer[i].counter_max;
-            BX_PIT_THIS s.timer[i].OUT     = !BX_PIT_THIS s.timer[i].OUT;
-            //BX_INFO(("CV: reload t%u to %04x", (unsigned) i, (unsigned)
-            //  BX_PIT_THIS s.timer[i].counter));
-            }
-          else {
-            // decrement counter by elapsed useconds
-            BX_PIT_THIS s.timer[i].counter -= (Bit16u ) ( 2*usec_delta );
-            //BX_INFO(("CV: dec count to %04x",
-            //          (unsigned) BX_PIT_THIS s.timer[i].counter));
-            }
-          break;
-
-        case 4: // Mode 4: Software Triggered Strobe
-          // wraps after count expires
-          BX_PANIC(("bx_pit_c::periodic: bad mode: timer[%u], mode %u",
-                        i, (unsigned) BX_PIT_THIS s.timer[i].mode));
-          break;
-
-        case 5: // Mode 5: Hardware Retriggerable Strobe
-          // wraps after count expires
-          BX_PANIC(("bx_pit_c::periodic: bad mode: timer[%u], mode %u",
-                        i, (unsigned) BX_PIT_THIS s.timer[i].mode));
-          break;
-        default:
-          BX_PANIC(("bx_pit_c::periodic: bad mode: timer[%u], mode %u",
-                        i, (unsigned) BX_PIT_THIS s.timer[i].mode));
-          break;
-        } // switch ( BX_PIT_THIS s.tim...
-      } // if ( BX_PIT_THIS s.timer[i]...
-    } // for (unsigned i...
-
-  // see if there's a rising edge on timer0's output to trigger an IRQ0.
-  if ( (prev_timer0_out==0) && (BX_PIT_THIS s.timer[0].OUT==1) )
-    return(1); // request IRQ 0
-  else
-    return(0);
-}
-
-#endif // #if (BX_USE_NEW_PIT==0)
diff --git a/tools/ioemu/iodev/pit.h b/tools/ioemu/iodev/pit.h
deleted file mode 100644 (file)
index 49b663b..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: pit.h,v 1.10 2002/10/25 11:44:40 bdenney Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2001  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-#ifndef _BX_PIT_H
-#define _BX_PIT_H
-
-#include "config.h"
-
-#if (BX_USE_NEW_PIT==0)
-
-#if BX_USE_PIT_SMF
-#  define BX_PIT_SMF  static
-#  define BX_PIT_THIS bx_pit.
-#else
-#  define BX_PIT_SMF
-#  define BX_PIT_THIS this->
-#endif
-
-#ifdef OUT
-#  undef OUT
-#endif
-
-
-typedef struct {
-  Bit8u      mode;
-  Bit8u      latch_mode;
-  Bit16u     input_latch_value;
-  bx_bool    input_latch_toggle;
-  Bit16u     output_latch_value;
-  bx_bool    output_latch_toggle;
-  bx_bool    output_latch_full;
-  Bit16u     counter_max;
-  Bit16u     counter;
-  bx_bool    bcd_mode;
-  bx_bool    active;
-  bx_bool    GATE;     // GATE input  pin
-  bx_bool    OUT;      // OUT  output pin
-  } bx_pit_t;
-
-
-
-
-class bx_pit_c : public logfunctions {
-public:
-  bx_pit_c( void );
-  ~bx_pit_c( void );
-  BX_PIT_SMF int init(void);
-  BX_PIT_SMF void reset( unsigned type);
-  BX_PIT_SMF bx_bool periodic( Bit32u   usec_delta );
-
-  BX_PIT_SMF int SaveState( class state_file *fd );
-  BX_PIT_SMF int LoadState( class state_file *fd );
-
-private:
-
-  static Bit32u read_handler(void *this_ptr, Bit32u address, unsigned io_len);
-  static void   write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);
-#if !BX_USE_PIT_SMF
-  Bit32u   read( Bit32u   addr, unsigned int len );
-  void write( Bit32u   addr, Bit32u   Value, unsigned int len );
-#endif
-
-  struct s_type {
-    bx_pit_t timer[3];
-    Bit8u   speaker_data_on;
-    bx_bool refresh_clock_div2;
-    int  timer_handle[3];
-    } s;
-
-  BX_PIT_SMF void  write_count_reg( Bit8u   value, unsigned timerid );
-  BX_PIT_SMF Bit8u read_counter( unsigned timerid );
-  BX_PIT_SMF void  latch( unsigned timerid );
-  BX_PIT_SMF void  set_GATE(unsigned pit_id, unsigned value);
-  BX_PIT_SMF void  start(unsigned timerid);
-  };
-
-extern bx_pit_c bx_pit;
-
-#endif  // #if (BX_USE_NEW_PIT==0)
-#endif  // #ifndef _BX_PIT_H
diff --git a/tools/ioemu/iodev/pit82c54.cc b/tools/ioemu/iodev/pit82c54.cc
deleted file mode 100644 (file)
index 493faf6..0000000
+++ /dev/null
@@ -1,930 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: pit82c54.cc,v 1.23 2003/06/29 17:24:52 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-/*
- * Emulator of an Intel 8254/82C54 Programmable Interval Timer.
- * Greg Alexander <yakovlev@usa.com>
- *
- * 
- * Things I am unclear on (greg):
- * 1.)What happens if both the status and count registers are latched,
- *  but the first of the two count registers has already been read?
- *  I.E.: 
- *   latch count 0 (16-bit)
- *   Read count 0 (read LSByte)
- *   READ_BACK status of count 0
- *   Read count 0 - do you get MSByte or status?
- *  This will be flagged as an error.
- * 2.)What happens when we latch the output in the middle of a 2-part
- *  unlatched read?
- * 3.)I assumed that programming a counter removes a latched status.
- * 4.)I implemented the 8254 description of mode 0, not the 82C54 one.
- * 5.)clock() calls represent a rising clock edge followed by a falling
- *  clock edge.
- * 6.)What happens when we trigger mode 1 in the middle of a 2-part 
- *  write?
- */
-
-#include "bochs.h"
-#include "pit82c54.h"
-#define LOG_THIS this->
-
-
-void pit_82C54::print_counter(counter_type & thisctr) {
-#if 1
-  BX_INFO(("Printing Counter"));
-  BX_INFO(("count: %d",thisctr.count));
-  BX_INFO(("count_binary: %x",thisctr.count_binary));
-  BX_INFO(("counter gate: %x",thisctr.GATE));
-  BX_INFO(("counter OUT: %x",thisctr.OUTpin));
-  BX_INFO(("next_change_time: %d",thisctr.next_change_time));
-  BX_INFO(("End Counter Printout"));
-#endif
-}
-
-void pit_82C54::print_cnum(Bit8u cnum) {
-  if(cnum>MAX_COUNTER) {
-    BX_ERROR(("Bad counter index to print_cnum"));
-  } else {
-    print_counter(counter[cnum]);
-  }
-}
-
-  void pit_82C54::latch_counter(counter_type & thisctr) {
-    if(thisctr.count_LSB_latched || thisctr.count_MSB_latched) {
-      //Do nothing because previous latch has not been read.;
-    } else {
-      switch(thisctr.read_state) {
-      case MSByte:
-       thisctr.outlatch=thisctr.count & 0xFFFF;
-       thisctr.count_MSB_latched=1;
-       break;
-      case LSByte:
-       thisctr.outlatch=thisctr.count & 0xFFFF;
-       thisctr.count_LSB_latched=1;
-       break;
-      case LSByte_multiple:
-       thisctr.outlatch=thisctr.count & 0xFFFF;
-       thisctr.count_LSB_latched=1;
-       thisctr.count_MSB_latched=1;
-       break;
-      case MSByte_multiple:
-       if(!(seen_problems & UNL_2P_READ)) {
-//       seen_problems|=UNL_2P_READ;
-         BX_ERROR(("Unknown behavior when latching during 2-part read."));
-         BX_ERROR(("  This message will not be repeated."));
-       }
-       //I guess latching and resetting to LSB first makes sense;
-       BX_DEBUG(("Setting read_state to LSB_mult"));
-       thisctr.read_state=LSByte_multiple;
-       thisctr.outlatch=thisctr.count & 0xFFFF;
-       thisctr.count_LSB_latched=1;
-       thisctr.count_MSB_latched=1;
-       break;
-      default:
-       BX_ERROR(("Unknown read mode found during latch command."));
-       break;
-      }
-    }
-  }
-
-  void pit_82C54::set_OUT (counter_type & thisctr, bool data) {
-    //This will probably have a callback, so I put it here.
-    thisctr.OUTpin=data;
-  }
-
-  void  BX_CPP_AttrRegparmN(2)
-pit_82C54::set_count (counter_type & thisctr, Bit32u data) {
-    thisctr.count=data & 0xFFFF;
-    set_binary_to_count(thisctr);
-  }
-
-  void  BX_CPP_AttrRegparmN(1)
-pit_82C54::set_count_to_binary(counter_type & thisctr) {
-    if(thisctr.bcd_mode) {
-      thisctr.count=
-       (((thisctr.count_binary/1)%10)<<0) |
-       (((thisctr.count_binary/10)%10)<<4) |
-       (((thisctr.count_binary/100)%10)<<8) |
-       (((thisctr.count_binary/1000)%10)<<12)
-       ;
-    } else {
-      thisctr.count=thisctr.count_binary;
-    }
-  }
-
-  void  BX_CPP_AttrRegparmN(1)
-pit_82C54::set_binary_to_count(counter_type & thisctr) {
-    if(thisctr.bcd_mode) {
-      thisctr.count_binary=
-       (1*((thisctr.count>>0)&0xF)) +
-       (10*((thisctr.count>>4)&0xF)) +
-       (100*((thisctr.count>>8)&0xF)) +
-       (1000*((thisctr.count>>12)&0xF))
-       ;
-    } else {
-      thisctr.count_binary=thisctr.count;
-    }
-  }
-
-  void  BX_CPP_AttrRegparmN(1)
-pit_82C54::decrement (counter_type & thisctr) {
-    if(!thisctr.count) {
-      if(thisctr.bcd_mode) {
-       thisctr.count=0x9999;
-       thisctr.count_binary=9999;
-      } else {
-       thisctr.count=0xFFFF;
-       thisctr.count_binary=0xFFFF;
-      }
-    } else {
-      thisctr.count_binary--;
-      set_count_to_binary(thisctr);
-    }
-  }
-
-  void pit_82C54::init (void) {
-    Bit8u i;
-
-    put("PIT81");
-    settype(PIT81LOG);
-
-    for(i=0;i<3;i++) {
-      BX_DEBUG(("Setting read_state to LSB"));
-      counter[i].read_state=LSByte;
-      counter[i].write_state=LSByte;
-      counter[i].GATE=1;
-      counter[i].OUTpin=1;
-      counter[i].triggerGATE=0;
-      counter[i].mode=4;
-      counter[i].first_pass=0;
-      counter[i].bcd_mode=0;
-      counter[i].count=0;
-      counter[i].count_binary=0;
-      counter[i].state_bit_1=0;
-      counter[i].state_bit_2=0;
-      counter[i].null_count=0;
-      counter[i].rw_mode=1;
-      counter[i].count_written=1;
-      counter[i].count_LSB_latched=0;
-      counter[i].count_MSB_latched=0;
-      counter[i].status_latched=0;
-      counter[i].next_change_time=0;
-    }
-    seen_problems=0;
-  }
-
-  pit_82C54::pit_82C54 (void) {
-    init();
-  }
-
-  void pit_82C54::reset (unsigned type) {
-  }
-
-void  BX_CPP_AttrRegparmN(2)
-pit_82C54::decrement_multiple(counter_type & thisctr, Bit32u cycles) {
-  while(cycles>0) {
-    if(cycles<=thisctr.count_binary) {
-      thisctr.count_binary-=cycles;
-      cycles-=cycles;
-      set_count_to_binary(thisctr);
-    } else {
-      cycles-=(thisctr.count_binary+1);
-      thisctr.count_binary-=thisctr.count_binary;
-      set_count_to_binary(thisctr);
-      decrement(thisctr);
-    }
-  }
-}
-
-void pit_82C54::clock_multiple(Bit8u cnum, Bit32u cycles) {
-  if(cnum>MAX_COUNTER) {
-    BX_ERROR(("Counter number too high in clock"));
-  } else {
-    counter_type & thisctr = counter[cnum];
-    while(cycles>0) {
-      if(thisctr.next_change_time==0) {
-       if(thisctr.count_written) {
-         switch(thisctr.mode) {
-         case 0:
-           if(thisctr.GATE && (thisctr.write_state!=MSByte_multiple)) {
-             decrement_multiple(thisctr, cycles);
-           }
-           break;
-         case 1:
-           decrement_multiple(thisctr, cycles);
-           break;
-         case 2:
-           if( (!thisctr.first_pass) && thisctr.GATE ) {
-             decrement_multiple(thisctr, cycles);
-           }
-           break;
-         case 3:
-           if( (!thisctr.first_pass) && thisctr.GATE ) {
-             decrement_multiple(thisctr, 2*cycles);
-           }
-           break;
-         case 4:
-           if(thisctr.GATE) {
-             decrement_multiple(thisctr, cycles);
-           }
-           break;
-         case 5:
-           decrement_multiple(thisctr, cycles);
-           break;
-         default:
-           break;
-         }
-       }
-       cycles-=cycles;
-      } else {
-       switch(thisctr.mode) {
-       case 0:
-       case 1:
-       case 2:
-       case 4:
-       case 5:
-         if( thisctr.next_change_time > cycles ) {
-           decrement_multiple(thisctr,cycles);
-           thisctr.next_change_time-=cycles;
-           cycles-=cycles;
-         } else {
-           decrement_multiple(thisctr,(thisctr.next_change_time-1));
-           cycles-=thisctr.next_change_time;
-           clock(cnum);
-         }
-         break;
-       case 3:
-         if( thisctr.next_change_time > cycles ) {
-           decrement_multiple(thisctr,cycles*2);
-           thisctr.next_change_time-=cycles;
-           cycles-=cycles;
-         } else {
-           decrement_multiple(thisctr,(thisctr.next_change_time-1)*2);
-           cycles-=thisctr.next_change_time;
-           clock(cnum);
-         }
-         break;
-       default:
-         cycles-=cycles;
-         break;
-       }
-      }
-    }
-#if 0
-    print_counter(thisctr);
-#endif
-  }
-}
-
-  void  BX_CPP_AttrRegparmN(1)
-pit_82C54::clock(Bit8u cnum) {
-    if(cnum>MAX_COUNTER) {
-      BX_ERROR(("Counter number too high in clock"));
-    } else {
-      counter_type & thisctr = counter[cnum];
-      switch(thisctr.mode) {
-      case 0:
-       if(thisctr.count_written) {
-         if(thisctr.null_count) {
-           set_count(thisctr, thisctr.inlatch);
-           if(thisctr.GATE) {
-              if(thisctr.count_binary==0) {
-               thisctr.next_change_time=1;
-              } else {
-               thisctr.next_change_time=thisctr.count_binary & 0xFFFF;
-             }
-           } else {
-             thisctr.next_change_time=0;
-           }
-           thisctr.null_count=0;
-         } else {
-           if(thisctr.GATE && (thisctr.write_state!=MSByte_multiple)) {
-             decrement(thisctr);
-             if(!thisctr.OUTpin) {
-               thisctr.next_change_time=thisctr.count_binary & 0xFFFF;
-               if(!thisctr.count) {
-                 set_OUT(thisctr,1);
-               }
-             } else {
-               thisctr.next_change_time=0;
-             }
-           } else {
-             thisctr.next_change_time=0; //if the clock isn't moving.
-           }
-         }
-       } else {
-         thisctr.next_change_time=0; //default to 0.
-       }
-       thisctr.triggerGATE=0;
-       break;
-      case 1:
-       if(thisctr.count_written) {
-         if(thisctr.triggerGATE) {
-           set_count(thisctr, thisctr.inlatch);
-            if(thisctr.count_binary==0) {
-              thisctr.next_change_time=1;
-            } else {
-              thisctr.next_change_time=thisctr.count_binary & 0xFFFF;
-            }
-           thisctr.null_count=0;
-           set_OUT(thisctr,0);
-           if(thisctr.write_state==MSByte_multiple) {
-             BX_ERROR(("Undefined behavior when loading a half loaded count."));
-           }
-         } else {
-           decrement(thisctr);
-           if(!thisctr.OUTpin) {
-              if(thisctr.count_binary==0) {
-               thisctr.next_change_time=1;
-              } else {
-               thisctr.next_change_time=thisctr.count_binary & 0xFFFF;
-             }
-             if(thisctr.count==0) {
-               set_OUT(thisctr,1);
-             }
-           } else {
-             thisctr.next_change_time=0;
-           }
-         }
-       } else {
-         thisctr.next_change_time=0; //default to 0.
-       }
-       thisctr.triggerGATE=0;
-       break;
-      case 2:
-       if(thisctr.count_written) {
-         if(thisctr.triggerGATE || thisctr.first_pass) {
-           set_count(thisctr, thisctr.inlatch);
-           thisctr.next_change_time=(thisctr.count_binary-1) & 0xFFFF;
-           thisctr.null_count=0;
-           if(thisctr.inlatch==1) {
-             BX_ERROR(("ERROR: count of 1 is invalid in pit mode 2."));
-           }
-           if(!thisctr.OUTpin) {
-             set_OUT(thisctr,1);
-           }
-           if(thisctr.write_state==MSByte_multiple) {
-             BX_ERROR(("Undefined behavior when loading a half loaded count."));
-           }
-           thisctr.first_pass=0;
-         } else {
-           if(thisctr.GATE) {
-             decrement(thisctr);
-             thisctr.next_change_time=(thisctr.count_binary-1) & 0xFFFF;
-             if(thisctr.count==1) {
-               thisctr.next_change_time=1;
-               set_OUT(thisctr,0);
-               thisctr.first_pass=1;
-             }
-           } else {
-             thisctr.next_change_time=0;
-           }
-         }
-       } else {
-         thisctr.next_change_time=0;
-       }
-       thisctr.triggerGATE=0;
-       break;
-      case 3:
-       if(thisctr.count_written) {
-         if( (thisctr.triggerGATE || thisctr.first_pass
-            || thisctr.state_bit_2) && thisctr.GATE ) {
-           set_count(thisctr, thisctr.inlatch & 0xFFFE);
-           thisctr.state_bit_1=thisctr.inlatch & 0x1;
-           if( (!thisctr.OUTpin) || (!(thisctr.state_bit_1))) {
-              if(((thisctr.count_binary/2)-1)==0) {
-                thisctr.next_change_time=1;
-              } else {
-               thisctr.next_change_time=((thisctr.count_binary/2)-1) & 0xFFFF;
-              }
-           } else {
-              if((thisctr.count_binary/2)==0) {
-                thisctr.next_change_time=1;
-              } else {
-               thisctr.next_change_time=(thisctr.count_binary/2) & 0xFFFF;
-              }
-           }
-           thisctr.null_count=0;
-           if(thisctr.inlatch==1) {
-             BX_ERROR(("Count of 1 is invalid in pit mode 3."));
-           }
-           if(!thisctr.OUTpin) {
-             set_OUT(thisctr,1);
-           } else if(thisctr.OUTpin && !thisctr.first_pass) {
-             set_OUT(thisctr,0);
-           }
-           if(thisctr.write_state==MSByte_multiple) {
-             BX_ERROR(("Undefined behavior when loading a half loaded count."));
-           }
-           thisctr.state_bit_2=0;
-           thisctr.first_pass=0;
-         } else {
-           if(thisctr.GATE) {
-             decrement(thisctr);
-             decrement(thisctr);
-             if( (!thisctr.OUTpin) || (!(thisctr.state_bit_1))) {
-               thisctr.next_change_time=((thisctr.count_binary/2)-1) & 0xFFFF;
-             } else {
-               thisctr.next_change_time=(thisctr.count_binary/2) & 0xFFFF;
-             }
-             if(thisctr.count==0) {
-               thisctr.state_bit_2=1;
-               thisctr.next_change_time=1;
-             }
-             if( (thisctr.count==2) &&
-                ( (!thisctr.OUTpin) || (!(thisctr.state_bit_1)))
-                ) {
-               thisctr.state_bit_2=1;
-               thisctr.next_change_time=1;
-             }
-           } else {
-             thisctr.next_change_time=0;
-           }
-         }
-       } else {
-         thisctr.next_change_time=0;
-       }
-       thisctr.triggerGATE=0;
-       break;
-      case 4:
-       if(thisctr.count_written) {
-         if(!thisctr.OUTpin) {
-           set_OUT(thisctr,1);
-         }
-         if(thisctr.null_count) {
-           set_count(thisctr, thisctr.inlatch);
-           if(thisctr.GATE) {
-              if(thisctr.count_binary==0) {
-               thisctr.next_change_time=1;
-             } else {
-               thisctr.next_change_time=thisctr.count_binary & 0xFFFF;
-             }
-           } else {
-             thisctr.next_change_time=0;
-           }
-           thisctr.null_count=0;
-           if(thisctr.write_state==MSByte_multiple) {
-             BX_ERROR(("Undefined behavior when loading a half loaded count."));
-           }
-           thisctr.first_pass=1;
-         } else {
-           if(thisctr.GATE) {
-             decrement(thisctr);
-             if(thisctr.first_pass) {
-               thisctr.next_change_time=thisctr.count_binary & 0xFFFF;
-               if(!thisctr.count) {
-                 set_OUT(thisctr,0);
-                 thisctr.next_change_time=1;
-                 thisctr.first_pass=0;
-               }
-             } else {
-               thisctr.next_change_time=0;
-             }
-           } else {
-             thisctr.next_change_time=0;
-           }
-         }
-       } else {
-         thisctr.next_change_time=0;
-       }
-       thisctr.triggerGATE=0;
-       break;
-      case 5:
-       if(thisctr.count_written) {
-         if(!thisctr.OUTpin) {
-           set_OUT(thisctr,1);
-         }
-         if(thisctr.triggerGATE) {
-           set_count(thisctr, thisctr.inlatch);
-            if(thisctr.count_binary==0) {
-             thisctr.next_change_time=1;
-           } else {
-              thisctr.next_change_time=thisctr.count_binary & 0xFFFF;
-            }
-           thisctr.null_count=0;
-           if(thisctr.write_state==MSByte_multiple) {
-             BX_ERROR(("Undefined behavior when loading a half loaded count."));
-           }
-           thisctr.first_pass=1;
-         } else {
-           decrement(thisctr);
-           if(thisctr.first_pass) {
-             thisctr.next_change_time=thisctr.count_binary & 0xFFFF;
-             if(!thisctr.count) {
-               set_OUT(thisctr,0);
-               thisctr.next_change_time=1;
-               thisctr.first_pass=0;
-             }
-           } else {
-             thisctr.next_change_time=0;
-           }
-         }
-       } else {
-         thisctr.next_change_time=0;
-       }
-       thisctr.triggerGATE=0;
-       break;
-      default:
-       BX_ERROR(("Mode not implemented."));
-       thisctr.next_change_time=0;
-       thisctr.triggerGATE=0;
-       break;
-      }
-    }
-  }
-
-  void pit_82C54::clock_all(Bit32u cycles) {
-    BX_DEBUG(("clock_all:  cycles=%d",cycles));
-    clock_multiple(0,cycles);
-    clock_multiple(1,cycles);
-    clock_multiple(2,cycles);
-  }
-
-  Bit8u pit_82C54::read(Bit8u address) {
-    if(address>MAX_ADDRESS) {
-      BX_ERROR(("Counter address incorrect in data read."));
-    } else if(address==CONTROL_ADDRESS) {
-      BX_DEBUG(("PIT Read: Control Word Register."));
-      //Read from control word register;
-      /* This might be okay.  If so, 0 seems the most logical
-       *  return value from looking at the docs.
-       */
-      BX_ERROR(("Read from control word register not defined."));
-      return 0;
-    } else {
-      //Read from a counter;
-      BX_DEBUG(("PIT Read: Counter %d.",address));
-      counter_type & thisctr=counter[address];
-      if(thisctr.status_latched) {
-       //Latched Status Read;
-       if(thisctr.count_MSB_latched &&
-          (thisctr.read_state==MSByte_multiple) ) {
-         BX_ERROR(("Undefined output when status latched and count half read."));
-       } else {
-         thisctr.status_latched=0;
-         return thisctr.status_latch;
-       }
-      } else {
-       //Latched Count Read;
-       if(thisctr.count_LSB_latched) {
-         //Read Least Significant Byte;
-         if(thisctr.read_state==LSByte_multiple) {
-           BX_DEBUG(("Setting read_state to MSB_mult"));
-           thisctr.read_state=MSByte_multiple;
-         }
-         thisctr.count_LSB_latched=0;
-         return (thisctr.outlatch & 0xFF);
-       } else if(thisctr.count_MSB_latched) {
-         //Read Most Significant Byte;
-         if(thisctr.read_state==MSByte_multiple) {
-           BX_DEBUG(("Setting read_state to LSB_mult"));
-           thisctr.read_state=LSByte_multiple;
-         }
-         thisctr.count_MSB_latched=0;
-         return ((thisctr.outlatch>>8) & 0xFF);
-       } else {
-         //Unlatched Count Read;
-         if(!(thisctr.read_state & 0x1)) {
-           //Read Least Significant Byte;
-           if(thisctr.read_state==LSByte_multiple) {
-             thisctr.read_state=MSByte_multiple;
-             BX_DEBUG(("Setting read_state to MSB_mult"));
-           }
-           return (thisctr.count & 0xFF);
-         } else {
-           //Read Most Significant Byte;
-           if(thisctr.read_state==MSByte_multiple) {
-             BX_DEBUG(("Setting read_state to LSB_mult"));
-             thisctr.read_state=LSByte_multiple;
-           }
-           return ((thisctr.count>>8) & 0xFF);
-         }
-       }
-      }
-    }
-    //Should only get here on errors;
-    return 0;
-  }
-
-#ifdef BX_VMX_PIT
-//extra operations when use vmx pit device model
-  void pit_82C54::write_initcount_vmx(Bit8u cnum) {
-    if(cnum>MAX_COUNTER) {
-      BX_ERROR(("Counter number incorrect\n"));
-    }
-
-    ioreq_t *req = &((vcpu_iodata_t *) shared_page)->vp_ioreq;
-    extern bx_pic_c *thePic;
-    counter_type & thisctr = counter[cnum];
-    if(req->pdata_valid) {
-      BX_ERROR(("VMX_PIT:err!pit is port io!\n"));
-    }
-
-    if (thisctr.mode == 2) {//periodic mode, need HV to help send interrupt
-      req->state = STATE_IORESP_HOOK;
-
-//      req->u.data = thisctr.inlatch * 1000 / PIT_FREQ;//init count:16 bit
-      req->u.data = thisctr.inlatch;                   //init count:16 bit
-      //get the pit irq(0)'s vector from pic DM
-      req->u.data |= ((thePic->irq_to_vec(0)) << 16 ); //timer vec:8 bit
-      req->u.data |= (cnum << 24);                     //PIT channel(0~2):2 bit
-      req->u.data |= ((thisctr.rw_mode) << 26);                //rw mode:2 bit
-
-      BX_INFO(("VMX_PIT:whole pit hook packet = 0x%llx \n", (req->u.data ) ));
-      BX_INFO(("VMX_PIT:init counter = %d ms\n", (req->u.data & 0xFFFF) ));
-    }
-
-  }
-#endif
-
-  void pit_82C54::write(Bit8u address, Bit8u data) {
-    if(address>MAX_ADDRESS) {
-      BX_ERROR(("Counter address incorrect in data write."));
-    } else if(address==CONTROL_ADDRESS) {
-      Bit8u SC, RW, M, BCD;
-      controlword=data;
-      BX_DEBUG(("Control Word Write."));
-      SC = (controlword>>6) & 0x3;
-      RW = (controlword>>4) & 0x3;
-      M = (controlword>>1) & 0x7;
-      BCD = controlword & 0x1;
-      if(SC == 3) {
-       //READ_BACK command;
-       int i;
-       BX_DEBUG(("READ_BACK command."));
-       for(i=0;i<=MAX_COUNTER;i++) {
-         if((M>>i) & 0x1) {
-           //If we are using this counter;
-           counter_type & thisctr=counter[i];
-           if(!((controlword>>5) & 1)) {
-             //Latch Count;
-             latch_counter(thisctr);
-           }
-           if(!((controlword>>4) & 1)) {
-             //Latch Status;
-             if(thisctr.status_latched) {
-               //Do nothing because latched status has not been read.;
-             } else {
-               thisctr.status_latch=
-                 ((thisctr.OUTpin & 0x1) << 7) |
-                 ((thisctr.null_count & 0x1) << 6) |
-                 ((thisctr.rw_mode & 0x3) << 4) |
-                 ((thisctr.mode & 0x7) << 1) |
-                 (thisctr.bcd_mode&0x1)
-                 ;
-               thisctr.status_latched=1;
-             }
-           }
-         }
-       }
-      } else {
-       counter_type & thisctr = counter[SC];
-       if(!RW) {
-         //Counter Latch command;
-         BX_DEBUG(("Counter Latch command.  SC=%d",SC));
-         latch_counter(thisctr);
-       } else {
-         //Counter Program Command;
-         BX_DEBUG(("Counter Program command.  SC=%d, RW=%d, M=%d, BCD=%d",SC,RW,M,BCD));
-         thisctr.null_count=1;
-         thisctr.count_LSB_latched=0;
-         thisctr.count_MSB_latched=0;
-         thisctr.status_latched=0;
-         thisctr.inlatch=0;
-         thisctr.count_written=0;
-         thisctr.first_pass=1;
-         thisctr.rw_mode=RW;
-         thisctr.bcd_mode=(BCD > 0);
-         thisctr.mode=M;
-         switch(RW) {
-         case 0x1:
-           BX_DEBUG(("Setting read_state to LSB"));
-           thisctr.read_state=LSByte;
-           thisctr.write_state=LSByte;
-           break;
-         case 0x2:
-           BX_DEBUG(("Setting read_state to MSB"));
-           thisctr.read_state=MSByte;
-           thisctr.write_state=MSByte;
-           break;
-         case 0x3:
-           BX_DEBUG(("Setting read_state to LSB_mult"));
-           thisctr.read_state=LSByte_multiple;
-           thisctr.write_state=LSByte_multiple;
-           break;
-         default:
-           BX_ERROR(("RW field invalid in control word write."));
-           break;
-         }
-         //All modes except mode 0 have initial output of 1.;
-         if(M) {
-           set_OUT(thisctr, 1);
-         } else {
-           set_OUT(thisctr, 0);
-         }
-         thisctr.next_change_time=0;
-       }
-      }
-    } else {
-      //Write to counter initial value.
-      counter_type & thisctr = counter[address];
-      BX_DEBUG(("Write Initial Count: counter=%d, count=%d",address,data));
-      switch(thisctr.write_state) {
-      case LSByte_multiple:
-       thisctr.inlatch=(thisctr.inlatch & (0xFF<<8)) | data;
-       thisctr.write_state=MSByte_multiple;
-       break;
-      case LSByte:
-       thisctr.inlatch=(thisctr.inlatch & (0xFF<<8)) | data;
-       thisctr.null_count=1;
-       thisctr.count_written=1;
-#ifdef BX_VMX_PIT
-       write_initcount_vmx(address);
-#endif
-       break;
-      case MSByte_multiple:
-       thisctr.write_state=LSByte_multiple;
-      case MSByte: //shared between MSB_multiple and MSByte
-       thisctr.inlatch=(thisctr.inlatch & 0xFF) | (data<<8);
-       thisctr.null_count=1;
-       thisctr.count_written=1;
-#ifdef BX_VMX_PIT
-       write_initcount_vmx(address);
-#endif
-       break;
-      default:
-       BX_ERROR(("write counter in invalid write state."));
-       break;
-      }
-      switch(thisctr.mode) {
-      case 0:
-       if(thisctr.write_state==MSByte_multiple) {
-         set_OUT(thisctr,0);
-       }
-       thisctr.next_change_time=1;
-       break;
-      case 1:
-       if(thisctr.triggerGATE) { //for initial writes, if already saw trigger.
-         thisctr.next_change_time=1;
-       } //Otherwise, no change.
-       break;
-      case 6:
-      case 2:
-       thisctr.next_change_time=1; //FIXME: this could be loosened.
-       break;
-      case 7:
-      case 3:
-       thisctr.next_change_time=1; //FIXME: this could be loosened.
-       break;
-      case 4:
-       thisctr.next_change_time=1;
-       break;
-      case 5:
-       if(thisctr.triggerGATE) { //for initial writes, if already saw trigger.
-         thisctr.next_change_time=1;
-       } //Otherwise, no change.
-       break;
-      }
-    }
-  }
-
-  void pit_82C54::set_GATE(Bit8u cnum, bool data) {
-    if(cnum>MAX_COUNTER) {
-      BX_ERROR(("Counter number incorrect in 82C54 set_GATE"));
-    } else {
-      counter_type & thisctr = counter[cnum];
-      if(!( (thisctr.GATE&&data) || (!(thisctr.GATE||data)) )) {
-        BX_INFO(("Changing GATE %d to: %d",cnum,data));
-       thisctr.GATE=data;
-       if(thisctr.GATE) {
-         thisctr.triggerGATE=1;
-       }
-       switch(thisctr.mode) {
-       case 0:
-         if(data && thisctr.count_written) {
-           if(thisctr.null_count) {
-             thisctr.next_change_time=1;
-           } else {
-             if( (!thisctr.OUTpin) &&
-                 (thisctr.write_state!=MSByte_multiple)
-                 ) {
-                if(thisctr.count_binary==0) {
-                 thisctr.next_change_time=1;
-                } else {
-                 thisctr.next_change_time=thisctr.count_binary & 0xFFFF;
-               }
-             } else {
-               thisctr.next_change_time=0;
-             }
-           }
-         } else {
-           if(thisctr.null_count) {
-             thisctr.next_change_time=1;
-           } else {
-             thisctr.next_change_time=0;
-           }
-         }
-         break;
-       case 1:
-         if(data && thisctr.count_written) { //only triggers cause a change.
-           thisctr.next_change_time=1;
-         }
-         break;
-       case 2:
-         if(!data) {
-           set_OUT(thisctr,1);
-           thisctr.next_change_time=0;
-         } else {
-           if(thisctr.count_written) {
-             thisctr.next_change_time=1;
-           } else {
-             thisctr.next_change_time=0;
-           }
-         }
-         break;
-       case 3:
-         if(!data) {
-           set_OUT(thisctr,1);
-           thisctr.first_pass=1;
-           thisctr.next_change_time=0;
-         } else {
-           if(thisctr.count_written) {
-             thisctr.next_change_time=1;
-           } else {
-             thisctr.next_change_time=0;
-           }
-         }
-         break;
-       case 4:
-         if(!thisctr.OUTpin || thisctr.null_count) {
-           thisctr.next_change_time=1;
-         } else {
-           if(data && thisctr.count_written) {
-             if(thisctr.first_pass) {
-                if(thisctr.count_binary==0) {
-                 thisctr.next_change_time=1;
-                } else {
-                 thisctr.next_change_time=thisctr.count_binary & 0xFFFF;
-               }
-             } else {
-               thisctr.next_change_time=0;
-             }
-           } else {
-             thisctr.next_change_time=0;
-           }
-         }
-         break;
-       case 5:
-         if(data && thisctr.count_written) { //only triggers cause a change.
-           thisctr.next_change_time=1;
-         }
-         break;
-       default:
-         break;
-       }
-      }
-    }
-  }
-
-  bool pit_82C54::read_OUT(Bit8u cnum) {
-    if(cnum>MAX_COUNTER) {
-      BX_ERROR(("Counter number incorrect in 82C54 read_OUT"));
-      return 0;
-    } else {
-      return counter[cnum].OUTpin;
-    }
-  }
-
-  bool pit_82C54::read_GATE(Bit8u cnum) {
-    if(cnum>MAX_COUNTER) {
-      BX_ERROR(("Counter number incorrect in 82C54 read_GATE"));
-      return 0;
-    } else {
-      return counter[cnum].GATE;
-    }
-  }
-
-Bit32u pit_82C54::get_clock_event_time(Bit8u cnum) {
-  if(cnum>MAX_COUNTER) {
-    BX_ERROR(("Counter number incorrect in 82C54 read_GATE"));
-    return 0;
-  } else {
-    return counter[cnum].next_change_time;
-  }
-}
-
-Bit32u pit_82C54::get_next_event_time(void) {
-  Bit32u out;
-  Bit32u time0=get_clock_event_time(0);
-  Bit32u time1=get_clock_event_time(1);
-  Bit32u time2=get_clock_event_time(2);
-
-  out=time0;
-  if(time1 && (time1<out))
-    out=time1;
-  if(time2 && (time2<out))
-    out=time2;
-  return out;
-}
diff --git a/tools/ioemu/iodev/pit82c54.h b/tools/ioemu/iodev/pit82c54.h
deleted file mode 100644 (file)
index 95d36b3..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: pit82c54.h,v 1.12 2003/03/02 23:59:11 cbothamy Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-/*
- * Emulator of an Intel 8254/82C54 Programmable Interval Timer.
- * Greg Alexander <yakovlev@usa.com>
- *
- * This code is not yet linked into Bochs, but has been included so
- * that you can experiment with it.  (bbd)
- */
-
-#ifndef _PIT_82C54_H_
-#define _PIT_82C54_H_ 1
-
-#include "bochs.h"
-
-#ifdef BX_USE_VMX
-#define BX_VMX_PIT 1
-#define PIT_FREQ 1193181
-#endif
-
-
-class pit_82C54 : public logfunctions {
-
-public:
-  //Please do not use these.  They are public because they have to be
-  // to compile on some platforms.  They are not to be used by other
-  // classes.
-
-  enum rw_status {
-    LSByte=0,
-    MSByte=1,
-    LSByte_multiple=2,
-    MSByte_multiple=3
-  };
-
-private:
-
-  enum {
-    MAX_COUNTER=2,
-    MAX_ADDRESS=3,
-    CONTROL_ADDRESS=3,
-    MAX_MODE=5
-  };
-
-  enum real_RW_status {
-    LSB_real=1,
-    MSB_real=2,
-    BOTH_real=3
-  };
-
-  enum problem_type {
-    UNL_2P_READ=1
-  };
-
-  struct counter_type {
-    //Chip IOs;
-    bool GATE; //GATE Input value at end of cycle
-    bool OUTpin; //OUT output this cycle
-
-    //Architected state;
-    Bit32u count; //Counter value this cycle
-    Bit16u outlatch; //Output latch this cycle
-    Bit16u inlatch; //Input latch this cycle
-    Bit8u status_latch;
-
-    //Status Register data;
-    Bit8u rw_mode; //2-bit R/W mode from command word register.
-    Bit8u mode; //3-bit mode from command word register.
-    bool bcd_mode; //1-bit BCD vs. Binary setting.
-    bool null_count; //Null count bit of status register.
-
-    //Latch status data;
-    bool count_LSB_latched;
-    bool count_MSB_latched;
-    bool status_latched;
-
-    //Miscelaneous State;
-    Bit32u count_binary; //Value of the count in binary.
-    bool triggerGATE; //Whether we saw GATE rise this cycle.
-    rw_status write_state; //Read state this cycle
-    rw_status read_state; //Read state this cycle
-    bool count_written; //Whether a count written since programmed
-    bool first_pass; //Whether or not this is the first loaded count.
-    bool state_bit_1; //Miscelaneous state bits.
-    bool state_bit_2;
-    Bit32u next_change_time; //Next time something besides count changes.
-                             //0 means never.
-  };
-
-  counter_type counter[3];
-
-  Bit8u controlword;
-
-  int seen_problems;
-
-  void latch_counter(counter_type & thisctr);
-
-  void set_OUT (counter_type & thisctr, bool data);
-
-  void set_count (counter_type & thisctr, Bit32u data) BX_CPP_AttrRegparmN(2);
-
-  void set_count_to_binary (counter_type & thisctr) BX_CPP_AttrRegparmN(1);
-
-  void set_binary_to_count (counter_type & thisctr) BX_CPP_AttrRegparmN(1);
-
-  void decrement (counter_type & thisctr) BX_CPP_AttrRegparmN(1);
-
-  void decrement_multiple(counter_type & thisctr, Bit32u cycles) BX_CPP_AttrRegparmN(2);
-
-  void clock(Bit8u cnum) BX_CPP_AttrRegparmN(1);
-
-  void print_counter(counter_type & thisctr);
-
-#ifdef BX_USE_VMX
-  void write_initcount_vmx(Bit8u cnum);
-#endif
-
-public:
-  void init (void);
-  void reset (unsigned type);
-  pit_82C54 (void);
-
-  void clock_all(Bit32u cycles);
-  void clock_multiple(Bit8u cnum, Bit32u cycles);
-
-  Bit8u read(Bit8u address);
-  void write(Bit8u address, Bit8u data);
-
-  void set_GATE(Bit8u cnum, bool data);
-  bool read_GATE(Bit8u cnum);
-
-  bool read_OUT(Bit8u cnum);
-
-  Bit32u get_clock_event_time(Bit8u cnum);
-  Bit32u get_next_event_time(void);
-
-  void print_cnum(Bit8u cnum);
-
-};
-
-#endif
diff --git a/tools/ioemu/iodev/pit_wrap.cc b/tools/ioemu/iodev/pit_wrap.cc
deleted file mode 100644 (file)
index 5fd1721..0000000
+++ /dev/null
@@ -1,444 +0,0 @@
-////////////////////////////////////////////////////////////////////////
-// $Id: pit_wrap.cc,v 1.52 2003/08/19 00:10:38 cbothamy Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-#include "bochs.h"
-
-#if BX_USE_NEW_PIT
-
-#include "pit_wrap.h"
-
-
-//Important constant #defines:
-#define USEC_PER_SECOND (1000000)
-//1.193181MHz Clock
-#define TICKS_PER_SECOND (1193181)
-
-
-// define a macro to convert floating point numbers into 64-bit integers.
-// In MSVC++ you can convert a 64-bit float into a 64-bit signed integer,
-// but it will not convert a 64-bit float into a 64-bit unsigned integer.
-// This macro works around that.
-#define F2I(x)  ((Bit64u)(Bit64s) (x))
-#define I2F(x)  ((double)(Bit64s) (x))
-
-//DEBUG configuration:
-
-//Set up Logging.
-#define LOG_THIS bx_pit.
-
-//A single instance.
-bx_pit_c bx_pit;
-#if BX_USE_PIT_SMF
-#define this (&bx_pit)
-#endif
-
-//Workaround for environments where OUT is defined.
-#ifdef OUT
-#  undef OUT
-#endif
-
-
-//Generic MAX and MIN Functions
-#define BX_MAX(a,b) ( ((a)>(b))?(a):(b) )
-#define BX_MIN(a,b) ( ((a)>(b))?(b):(a) )
-
-
-//USEC_ALPHA is multiplier for the past.
-//USEC_ALPHA_B is 1-USEC_ALPHA, or multiplier for the present.
-#define USEC_ALPHA ((double)(.8))
-#define USEC_ALPHA_B ((double)(((double)1)-USEC_ALPHA))
-#define USEC_ALPHA2 ((double)(.5))
-#define USEC_ALPHA2_B ((double)(((double)1)-USEC_ALPHA2))
-#define ALPHA_LOWER(old,new) ((Bit64u)((old<new)?((USEC_ALPHA*(I2F(old)))+(USEC_ALPHA_B*(I2F(new)))):((USEC_ALPHA2*(I2F(old)))+(USEC_ALPHA2_B*(I2F(new))))))
-
-
-//PIT tick to usec conversion functions:
-//Direct conversions:
-#define TICKS_TO_USEC(a) ( ((a)*USEC_PER_SECOND)/TICKS_PER_SECOND )
-#define USEC_TO_TICKS(a) ( ((a)*TICKS_PER_SECOND)/USEC_PER_SECOND )
-
-
-bx_pit_c::bx_pit_c( void )
-{
-  put("PIT");
-  settype(PITLOG);
-  s.speaker_data_on=0;
-
-  /* 8254 PIT (Programmable Interval Timer) */
-
-  BX_PIT_THIS s.timer_handle[1] = BX_NULL_TIMER_HANDLE;
-  BX_PIT_THIS s.timer_handle[2] = BX_NULL_TIMER_HANDLE;
-  BX_PIT_THIS s.timer_handle[0] = BX_NULL_TIMER_HANDLE;
-}
-
-bx_pit_c::~bx_pit_c( void )
-{
-}
-
-  int
-bx_pit_c::init( void )
-{
-  DEV_register_irq(0, "8254 PIT");
-  DEV_register_ioread_handler(this, read_handler, 0x0040, "8254 PIT", 1);
-  DEV_register_ioread_handler(this, read_handler, 0x0041, "8254 PIT", 1);
-  DEV_register_ioread_handler(this, read_handler, 0x0042, "8254 PIT", 1);
-  DEV_register_ioread_handler(this, read_handler, 0x0043, "8254 PIT", 1);
-  DEV_register_ioread_handler(this, read_handler, 0x0061, "8254 PIT", 1);
-
-  DEV_register_iowrite_handler(this, write_handler, 0x0040, "8254 PIT", 1);
-  DEV_register_iowrite_handler(this, write_handler, 0x0041, "8254 PIT", 1);
-  DEV_register_iowrite_handler(this, write_handler, 0x0042, "8254 PIT", 1);
-  DEV_register_iowrite_handler(this, write_handler, 0x0043, "8254 PIT", 1);
-  DEV_register_iowrite_handler(this, write_handler, 0x0061, "8254 PIT", 1);
-
-  BX_DEBUG(("pit: starting init"));
-
-  BX_PIT_THIS s.speaker_data_on = 0;
-  BX_PIT_THIS s.refresh_clock_div2 = 0;
-
-  BX_PIT_THIS s.timer.init();
-
-  Bit64u my_time_usec = bx_virt_timer.time_usec();
-
-  if (BX_PIT_THIS s.timer_handle[0] == BX_NULL_TIMER_HANDLE) {
-    BX_PIT_THIS s.timer_handle[0] = bx_virt_timer.register_timer(this, timer_handler, (unsigned) 100 , 1, 1, "pit_wrap");
-  }
-  BX_DEBUG(("pit: RESETting timer."));
-  bx_virt_timer.deactivate_timer(BX_PIT_THIS s.timer_handle[0]);
-  BX_DEBUG(("deactivated timer."));
-  if(BX_PIT_THIS s.timer.get_next_event_time()) {
-    bx_virt_timer.activate_timer(BX_PIT_THIS s.timer_handle[0], 
-                               (Bit32u)BX_MAX(1,TICKS_TO_USEC(BX_PIT_THIS s.timer.get_next_event_time())),
-                               0);
-    BX_DEBUG(("activated timer."));
-  }
-  BX_PIT_THIS s.last_next_event_time = BX_PIT_THIS s.timer.get_next_event_time();
-  BX_PIT_THIS s.last_usec=my_time_usec;
-
-  BX_PIT_THIS s.total_ticks=0;
-  BX_PIT_THIS s.total_usec=0;
-
-  BX_DEBUG(("pit: finished init"));
-
-  BX_DEBUG(("s.last_usec="FMT_LL"d",BX_PIT_THIS s.last_usec));
-  BX_DEBUG(("s.timer_id=%d",BX_PIT_THIS s.timer_handle[0]));
-  BX_DEBUG(("s.timer.get_next_event_time=%d",BX_PIT_THIS s.timer.get_next_event_time()));
-  BX_DEBUG(("s.last_next_event_time=%d",BX_PIT_THIS s.last_next_event_time));
-
-  return(1);
-}
-
-  void
-bx_pit_c::reset(unsigned type)
-{
-}
-
-void
-bx_pit_c::timer_handler(void *this_ptr) {
-  bx_pit_c * class_ptr = (bx_pit_c *) this_ptr;
-
-  class_ptr->handle_timer();
-}
-
-void
-bx_pit_c::handle_timer() {
-  Bit64u my_time_usec = bx_virt_timer.time_usec();
-  Bit64u time_passed = my_time_usec-BX_PIT_THIS s.last_usec;
-  Bit32u time_passed32 = (Bit32u)time_passed;
-
-  BX_DEBUG(("pit: entering timer handler"));
-
-  if(time_passed32) {
-    periodic(time_passed32);
-  }
-  BX_PIT_THIS s.last_usec=BX_PIT_THIS s.last_usec + time_passed;
-  if(time_passed ||
-     (BX_PIT_THIS s.last_next_event_time
-      != BX_PIT_THIS s.timer.get_next_event_time())
-     ) {
-    BX_DEBUG(("pit: RESETting timer."));
-    bx_virt_timer.deactivate_timer(BX_PIT_THIS s.timer_handle[0]);
-    BX_DEBUG(("deactivated timer."));
-    if(BX_PIT_THIS s.timer.get_next_event_time()) {
-      bx_virt_timer.activate_timer(BX_PIT_THIS s.timer_handle[0], 
-                                 (Bit32u)BX_MAX(1,TICKS_TO_USEC(BX_PIT_THIS s.timer.get_next_event_time())),
-                                 0);
-      BX_DEBUG(("activated timer."));
-    }
-    BX_PIT_THIS s.last_next_event_time = BX_PIT_THIS s.timer.get_next_event_time();
-  }
-  BX_DEBUG(("s.last_usec="FMT_LL"d",BX_PIT_THIS s.last_usec));
-  BX_DEBUG(("s.timer_id=%d",BX_PIT_THIS s.timer_handle[0]));
-  BX_DEBUG(("s.timer.get_next_event_time=%x",BX_PIT_THIS s.timer.get_next_event_time()));
-  BX_DEBUG(("s.last_next_event_time=%d",BX_PIT_THIS s.last_next_event_time));
-}
-
-
-  // static IO port read callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-  Bit32u
-bx_pit_c::read_handler(void *this_ptr, Bit32u address, unsigned io_len)
-{
-#if !BX_USE_PIT_SMF
-  bx_pit_c *class_ptr = (bx_pit_c *) this_ptr;
-
-  return( class_ptr->read(address, io_len) );
-}
-
-
-  Bit32u
-bx_pit_c::read( Bit32u   address, unsigned int io_len )
-{
-#else
-  UNUSED(this_ptr);
-#endif  // !BX_USE_PIT_SMF
-  BX_DEBUG(("pit: entering read handler"));
-
-  handle_timer();
-
-  Bit64u my_time_usec = bx_virt_timer.time_usec();
-
-  if (bx_dbg.pit)
-    BX_INFO(("pit: io read from port %04x", (unsigned) address));
-
-  switch (address) {
-
-    case 0x40: /* timer 0 - system ticks */
-      return(BX_PIT_THIS s.timer.read(0));
-      break;
-    case 0x41: /* timer 1 read */
-      return(BX_PIT_THIS s.timer.read(1));
-      break;
-    case 0x42: /* timer 2 read */
-      return(BX_PIT_THIS s.timer.read(2));
-      break;
-    case 0x43: /* timer 1 read */
-      return(BX_PIT_THIS s.timer.read(3));
-      break;
-
-    case 0x61:
-      /* AT, port 61h */
-      BX_PIT_THIS s.refresh_clock_div2 = (bx_bool)((my_time_usec / 15) & 1);
-      return( (BX_PIT_THIS s.timer.read_OUT(2)<<5) |
-              (BX_PIT_THIS s.refresh_clock_div2<<4) |
-              (BX_PIT_THIS s.speaker_data_on<<1) |
-              (BX_PIT_THIS s.timer.read_GATE(2)?1:0) );
-      break;
-
-    default:
-      BX_PANIC(("pit: unsupported io read from port %04x", address));
-  }
-  return(0); /* keep compiler happy */
-}
-
-
-  // static IO port write callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-  void
-bx_pit_c::write_handler(void *this_ptr, Bit32u address, Bit32u dvalue, unsigned io_len)
-{
-#if !BX_USE_PIT_SMF
-  bx_pit_c *class_ptr = (bx_pit_c *) this_ptr;
-
-  class_ptr->write(address, dvalue, io_len);
-}
-
-  void
-bx_pit_c::write( Bit32u   address, Bit32u   dvalue,
-                unsigned int io_len )
-{
-#else
-  UNUSED(this_ptr);
-#endif  // !BX_USE_PIT_SMF
-  Bit8u   value;
-  Bit64u my_time_usec = bx_virt_timer.time_usec();
-  Bit64u time_passed = my_time_usec-BX_PIT_THIS s.last_usec;
-  Bit32u time_passed32 = (Bit32u)time_passed;
-
-  BX_DEBUG(("pit: entering write handler"));
-
-  if(time_passed32) {
-    periodic(time_passed32);
-  }
-  BX_PIT_THIS s.last_usec=BX_PIT_THIS s.last_usec + time_passed;
-
-  value = (Bit8u  ) dvalue;
-
-  if (bx_dbg.pit)
-    BX_INFO(("pit: write to port %04x = %02x",
-      (unsigned) address, (unsigned) value));
-
-  switch (address) {
-    case 0x40: /* timer 0: write count register */
-      BX_PIT_THIS s.timer.write(0,value);
-      break;
-
-    case 0x41: /* timer 1: write count register */
-      BX_PIT_THIS s.timer.write( 1,value );
-      break;
-
-    case 0x42: /* timer 2: write count register */
-      BX_PIT_THIS s.timer.write( 2,value );
-      break;
-
-    case 0x43: /* timer 0-2 mode control */
-      BX_PIT_THIS s.timer.write( 3,value );
-      break;
-
-    case 0x61:
-      BX_PIT_THIS s.speaker_data_on = (value >> 1) & 0x01;
-/*??? only on AT+ */
-      BX_PIT_THIS s.timer.set_GATE(2, value & 0x01);
-#if BX_CPU_LEVEL < 2
-      /* ??? XT: */
-      bx_kbd_port61h_write(value);
-#endif
-      break;
-
-    default:
-      BX_PANIC(("pit: unsupported io write to port %04x = %02x",
-        (unsigned) address, (unsigned) value));
-  }
-
-#ifndef BX_VMX_PIT
-  if ((BX_PIT_THIS s.timer.read_OUT(0))==1) {
-    DEV_pic_raise_irq(0);
-  } else {
-    DEV_pic_lower_irq(0);
-  }
-#endif
-
-  if(time_passed ||
-     (BX_PIT_THIS s.last_next_event_time
-      != BX_PIT_THIS s.timer.get_next_event_time())
-     ) {
-    BX_DEBUG(("pit: RESETting timer."));
-    bx_virt_timer.deactivate_timer(BX_PIT_THIS s.timer_handle[0]);
-    BX_DEBUG(("deactivated timer."));
-    if(BX_PIT_THIS s.timer.get_next_event_time()) {
-      bx_virt_timer.activate_timer(BX_PIT_THIS s.timer_handle[0], 
-                                 (Bit32u)BX_MAX(1,TICKS_TO_USEC(BX_PIT_THIS s.timer.get_next_event_time())),
-                                 0);
-      BX_DEBUG(("activated timer."));
-    }
-    BX_PIT_THIS s.last_next_event_time = BX_PIT_THIS s.timer.get_next_event_time();
-  }
-  BX_DEBUG(("s.last_usec="FMT_LL"d",BX_PIT_THIS s.last_usec));
-  BX_DEBUG(("s.timer_id=%d",BX_PIT_THIS s.timer_handle[0]));
-  BX_DEBUG(("s.timer.get_next_event_time=%x",BX_PIT_THIS s.timer.get_next_event_time()));
-  BX_DEBUG(("s.last_next_event_time=%d",BX_PIT_THIS s.last_next_event_time));
-
-}
-
-
-
-
-  int
-bx_pit_c::SaveState( class state_file *fd )
-{
-  fd->write_check ("8254 start");
-  fd->write (&BX_PIT_THIS s, sizeof (BX_PIT_THIS s));
-  fd->write_check ("8254 end");
-  return(0);
-}
-
-
-  int
-bx_pit_c::LoadState( class state_file *fd )
-{
-  fd->read_check ("8254 start");
-  fd->read (&BX_PIT_THIS s, sizeof (BX_PIT_THIS s));
-  fd->read_check ("8254 end");
-  return(0);
-}
-
-
-#if 0
-  void
-bx_kbd_port61h_write(Bit8u   value)
-{
-//  PcError("KBD_PORT61H_WRITE(): not implemented yet");
-  UNUSED( value );
-}
-#endif
-
-
-  bx_bool
-bx_pit_c::periodic( Bit32u   usec_delta )
-{
-  bx_bool prev_timer0_out = BX_PIT_THIS s.timer.read_OUT(0);
-  bx_bool want_interrupt = 0;
-  Bit32u ticks_delta = 0;
-
-#ifdef BX_SCHEDULED_DIE_TIME
-  if (bx_pc_system.time_ticks() > BX_SCHEDULED_DIE_TIME) {
-    BX_ERROR (("ticks exceeded scheduled die time, quitting"));
-    BX_EXIT (2);
-  }
-#endif
-
-  BX_PIT_THIS s.total_usec += usec_delta;
-  ticks_delta=(Bit32u)((USEC_TO_TICKS((Bit64u)(BX_PIT_THIS s.total_usec)))-BX_PIT_THIS s.total_ticks);
-  BX_PIT_THIS s.total_ticks += ticks_delta;
-
-  while ((BX_PIT_THIS s.total_ticks >= TICKS_PER_SECOND) && (BX_PIT_THIS s.total_usec >= USEC_PER_SECOND)) {
-    BX_PIT_THIS s.total_ticks -= TICKS_PER_SECOND;
-    BX_PIT_THIS s.total_usec  -= USEC_PER_SECOND;
-  }
-
-  while(ticks_delta>0) {
-    Bit32u maxchange=BX_PIT_THIS s.timer.get_next_event_time();
-    Bit32u timedelta=maxchange;
-    if((maxchange==0) || (maxchange>ticks_delta)) {
-      timedelta=ticks_delta;
-    }
-    BX_PIT_THIS s.timer.clock_all(timedelta);
-    if ( (prev_timer0_out==0) ) {
-      if ((BX_PIT_THIS s.timer.read_OUT(0))==1) {
-#ifndef BX_VMX_PIT
-       DEV_pic_raise_irq(0);
-#endif
-        prev_timer0_out=1;
-      }
-    } else {
-      if ((BX_PIT_THIS s.timer.read_OUT(0))==0) {
-#ifndef BX_VMX_PIT
-       DEV_pic_lower_irq(0);
-#endif
-        prev_timer0_out=0;
-      }
-    }
-    prev_timer0_out=BX_PIT_THIS s.timer.read_OUT(0);
-    ticks_delta-=timedelta;
-  }
-
-  return(want_interrupt);
-}
-
-#endif // #if BX_USE_NEW_PIT
diff --git a/tools/ioemu/iodev/pit_wrap.h b/tools/ioemu/iodev/pit_wrap.h
deleted file mode 100644 (file)
index e45e1e6..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: pit_wrap.h,v 1.17 2003/08/19 00:10:38 cbothamy Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2001  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-#ifndef _BX_PIT_WRAP_H
-#define _BX_PIT_WRAP_H
-
-#include "bochs.h"
-
-#if BX_USE_NEW_PIT
-
-#include "pit82c54.h"
-
-#if BX_USE_PIT_SMF
-#  define BX_PIT_SMF  static
-#  define BX_PIT_THIS bx_pit.
-#else
-#  define BX_PIT_SMF
-#  define BX_PIT_THIS this->
-#endif
-
-#ifdef OUT
-#  undef OUT
-#endif
-
-class bx_pit_c : public logfunctions {
-public:
-  bx_pit_c( void );
-  ~bx_pit_c( void );
-  BX_PIT_SMF int init( void );
-  BX_PIT_SMF void reset( unsigned type);
-  BX_PIT_SMF bx_bool periodic( Bit32u   usec_delta );
-
-  BX_PIT_SMF int SaveState( class state_file *fd );
-  BX_PIT_SMF int LoadState( class state_file *fd );
-
-private:
-
-  static Bit32u read_handler(void *this_ptr, Bit32u address, unsigned io_len);
-  static void   write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);
-#if !BX_USE_PIT_SMF
-  Bit32u   read( Bit32u   addr, unsigned int len );
-  void write( Bit32u   addr, Bit32u   Value, unsigned int len );
-#endif
-
-  struct s_type {
-    pit_82C54 timer;
-    Bit8u   speaker_data_on;
-    bx_bool refresh_clock_div2;
-    int  timer_handle[3];
-    Bit64u last_usec;
-    Bit32u last_next_event_time;
-    Bit64u total_ticks;
-    Bit64u usec_per_second;
-    Bit64u ticks_per_second;
-    Bit64u total_sec;
-    Bit64u last_time;
-    Bit64u last_sec_usec;
-    Bit64u max_ticks;
-    Bit64u stored_delta;
-    Bit64u total_usec;
-    Bit64u em_last_realtime;
-    Bit64u last_realtime_delta;
-    Bit64u last_realtime_ticks;
-    } s;
-
-  static void timer_handler(void *this_ptr);
-  BX_PIT_SMF void handle_timer();
-
-  BX_PIT_SMF void  write_count_reg( Bit8u   value, unsigned timerid );
-  BX_PIT_SMF Bit8u read_counter( unsigned timerid );
-  BX_PIT_SMF void  latch( unsigned timerid );
-  BX_PIT_SMF void  set_GATE(unsigned pit_id, unsigned value);
-  BX_PIT_SMF void  start(unsigned timerid);
-
-  BX_PIT_SMF void  second_update_data(void);
-};
-
-extern bx_pit_c bx_pit;
-
-#endif  // #if BX_USE_NEW_PIT
-#endif  // #ifndef _BX_PIT_WRAP_H
diff --git a/tools/ioemu/iodev/plugin.cc b/tools/ioemu/iodev/plugin.cc
deleted file mode 100644 (file)
index 136065d..0000000
+++ /dev/null
@@ -1,554 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: plugin.cc,v 1.8 2003/07/31 12:04:47 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-// This file defines the plugin and plugin-device registration functions and
-// the device registration functions.  It handles dynamic loading of modules,
-// using the LTDL library for cross-platform support.
-//
-// This file is based on the plugin.c file from plex86, but with significant
-// changes to make it work in Bochs.
-// Plex86 is Copyright (C) 1999-2000  The plex86 developers team
-//
-/////////////////////////////////////////////////////////////////////////
-
-#include "bochs.h"
-#include "plugin.h"
-
-#define LOG_THIS genlog->
-
-#define PLUGIN_INIT_FMT_STRING  "lib%s_LTX_plugin_init"
-#define PLUGIN_FINI_FMT_STRING  "lib%s_LTX_plugin_fini"
-#define PLUGIN_PATH ""
-
-#ifndef WIN32
-#define PLUGIN_FILENAME_FORMAT "libbx_%s.la"
-#else
-#define PLUGIN_FILENAME_FORMAT "bx_%s.dll"
-#endif
-
-
-
-void  (*pluginRegisterIRQ)(unsigned irq, const char* name) = 0;
-void  (*pluginUnregisterIRQ)(unsigned irq, const char* name) = 0;
-
-void  (* pluginResetSignal)(unsigned sig) = 0;
-
-void (*pluginSetHRQ)(unsigned val) = 0;
-void (*pluginSetHRQHackCallback)( void (*callback)(void) ) = 0;
-
-int (*pluginRegisterIOReadHandler)(void *thisPtr, ioReadHandler_t callback,
-                            unsigned base, const char *name, Bit8u mask) = 0;
-int (*pluginRegisterIOWriteHandler)(void *thisPtr, ioWriteHandler_t callback,
-                             unsigned base, const char *name, Bit8u mask) = 0;
-int (*pluginRegisterDefaultIOReadHandler)(void *thisPtr, ioReadHandler_t callback,
-                            const char *name, Bit8u mask) = 0;
-int (*pluginRegisterDefaultIOWriteHandler)(void *thisPtr, ioWriteHandler_t callback,
-                             const char *name, Bit8u mask) = 0;
-int (*pluginRegisterTimer)(void *this_ptr, void (*funct)(void *),
-                       Bit32u useconds, bx_bool continuous, 
-                       bx_bool active, const char* name) = 0;
-void (*pluginActivateTimer)(unsigned id, Bit32u usec, bx_bool continuous) = 0;
-
-void (*pluginHRQHackCallback)(void);
-unsigned pluginHRQ = 0;
-
-plugin_t *plugins = NULL;      /* Head of the linked list of plugins  */
-#if BX_PLUGINS
-static void plugin_init_one(plugin_t *plugin);
-#endif
-
-device_t *devices = NULL;      /* Head of the linked list of registered devices  */
-
-plugin_t *current_plugin_context = NULL;
-
-/************************************************************************/
-/* Builtins declarations                                                */
-/************************************************************************/
-
-  static void  
-builtinRegisterIRQ(unsigned irq, const char* name) 
-{
-#if 0
-  pluginlog->panic("builtinRegisterIRQ called, no pic plugin loaded?");
-#else
-  bx_devices.register_irq(irq, name);
-#endif
-}
-
-  static void  
-builtinUnregisterIRQ(unsigned irq, const char* name)
-{
-#if 0
-  pluginlog->panic("builtinUnregisterIRQ called, no pic plugin loaded?");
-#else
-  bx_devices.unregister_irq(irq, name);
-#endif
-}
-
-  static void
-builtinSetHRQ(unsigned val)
-{
-#if 0
-  pluginlog->panic("builtinSetHRQ called, no plugin loaded?");
-#else
-  pluginHRQ = val;
-#endif
-}
-
-  static void
-builtinSetHRQHackCallback( void (*callback)(void) )
-{
-#if 0
-  pluginlog->panic("builtinSetHRQHackCallback called, no plugin loaded?");
-#else
-  pluginHRQHackCallback = callback;
-#endif
-}
-
-  static void
-builtinResetSignal( unsigned )
-{
-  pluginlog->panic("builtinResetSignal called, no plugin loaded?");
-}
-
-  static int
-builtinRegisterIOReadHandler(void *thisPtr, ioReadHandler_t callback,
-                            unsigned base, const char *name, Bit8u mask)
-{
-  BX_ASSERT (mask<8);
-  bx_devices.register_io_read_handler (thisPtr, callback, base, name, mask);
-  pluginlog->ldebug("plugin %s registered I/O read address at %04x", name, base);
-  return 0;
-}
-
-  static int
-builtinRegisterIOWriteHandler(void *thisPtr, ioWriteHandler_t callback,
-                             unsigned base, const char *name, Bit8u mask)
-{
-  BX_ASSERT (mask<8);
-  bx_devices.register_io_write_handler (thisPtr, callback, base, name, mask);
-  pluginlog->ldebug("plugin %s registered I/O write address at %04x", name, base);
-  return 0;
-}
-
-  static int
-builtinRegisterDefaultIOReadHandler(void *thisPtr, ioReadHandler_t callback,
-                            const char *name, Bit8u mask)
-{
-  BX_ASSERT (mask<8);
-  bx_devices.register_default_io_read_handler (thisPtr, callback, name, mask);
-  pluginlog->ldebug("plugin %s registered default I/O read ", name);
-  return 0;
-}
-
-  static int
-builtinRegisterDefaultIOWriteHandler(void *thisPtr, ioWriteHandler_t callback,
-                             const char *name, Bit8u mask)
-{
-  BX_ASSERT (mask<8);
-  bx_devices.register_default_io_write_handler (thisPtr, callback, name, mask);
-  pluginlog->ldebug("plugin %s registered default I/O write ", name);
-  return 0;
-}
-
-  static int
-builtinRegisterTimer(void *this_ptr, void (*funct)(void *),
-                       Bit32u useconds, bx_bool continuous, 
-                       bx_bool active, const char* name)
-{
-  int id = bx_pc_system.register_timer (this_ptr, funct, useconds, continuous, active, name);
-  pluginlog->ldebug("plugin %s registered timer %d", name, id);
-  return id;
-}
-
-  static void
-builtinActivateTimer(unsigned id, Bit32u usec, bx_bool continuous)
-{
-  bx_pc_system.activate_timer (id, usec, continuous);
-  pluginlog->ldebug("plugin activated timer %d", id);
-}
-
-#if BX_PLUGINS
-/************************************************************************/
-/* Plugin initialization / deinitialization                             */
-/************************************************************************/
-
-  void
-plugin_init_all (void)
-{
-    plugin_t *plugin;
-
-    pluginlog->info("Initializing plugins");
-
-    for (plugin = plugins; plugin; plugin = plugin->next)
-    {
-        char *arg_ptr = plugin->args;
-
-        /* process the command line */
-        plugin->argc = 0;
-        while (plugin->argc < MAX_ARGC)
-        {
-            while (*arg_ptr && isspace (*arg_ptr))
-                arg_ptr++;
-
-            if (!*arg_ptr)
-                break;
-            plugin->argv[plugin->argc++] = arg_ptr;
-
-            while (*arg_ptr && !isspace (*arg_ptr))
-                arg_ptr++;
-
-            if (!*arg_ptr)
-                break;
-            *arg_ptr++ = '\0';
-        }
-
-        /* initialize the plugin */
-        if (plugin->plugin_init (plugin, plugin->type, plugin->argc, plugin->argv))
-        {
-            pluginlog->panic("Plugin initialization failed for %s", plugin->name);
-            plugin_abort();
-        }
-
-        plugin->initialized = 1;
-    }
-
-    return;
-}
-
-void
-plugin_init_one(plugin_t *plugin)
-{
-        char *arg_ptr = plugin->args;
-        /* process the command line */
-        plugin->argc = 0;
-        while (plugin->argc < MAX_ARGC)
-        {
-            while (*arg_ptr && isspace (*arg_ptr))
-                arg_ptr++;
-            if (!*arg_ptr)
-                break;
-            plugin->argv[plugin->argc++] = arg_ptr;
-            while (*arg_ptr && !isspace (*arg_ptr))
-                arg_ptr++;
-            if (!*arg_ptr)
-                break;
-            *arg_ptr++ = '\0';
-        }
-        /* initialize the plugin */
-        if (plugin->plugin_init (plugin, plugin->type, plugin->argc, plugin->argv))
-        {
-            pluginlog->info("Plugin initialization failed for %s", plugin->name);
-            plugin_abort();
-        }
-        plugin->initialized = 1;
-}
-
-
-  plugin_t *
-plugin_unload(plugin_t *plugin)
-{
-    plugin_t *dead_plug;
-
-    if (plugin->initialized)
-        plugin->plugin_fini ();
-
-    lt_dlclose (plugin->handle);
-    free (plugin->name);
-    free (plugin->args);
-
-    dead_plug = plugin;
-    plugin = plugin->next;
-    free (dead_plug);
-
-    return plugin;
-}
-
-
-void
-plugin_fini_all (void)
-{
-    plugin_t *plugin;
-
-    for (plugin = plugins; plugin; plugin = plugin_unload (plugin));
-
-    return;
-}
-
-  void
-plugin_load (char *name, char *args, plugintype_t type)
-{
-    plugin_t *plugin;
-
-    plugin = (plugin_t *)malloc (sizeof (plugin_t));
-    if (!plugin)
-    {
-      BX_PANIC (("malloc plugin_t failed"));
-    }
-
-    plugin->type = type;
-    plugin->name = name;
-    plugin->args = args;
-    plugin->initialized = 0;
-       
-       char plugin_filename[BX_PATHNAME_LEN], buf[BX_PATHNAME_LEN];
-       sprintf (buf, PLUGIN_FILENAME_FORMAT, name);
-       sprintf(plugin_filename, "%s%s", PLUGIN_PATH, buf);
-
-    // Set context so that any devices that the plugin registers will
-    // be able to see which plugin created them.  The registration will
-    // be called from either dlopen (global constructors) or plugin_init.
-    BX_ASSERT (current_plugin_context == NULL);
-    current_plugin_context = plugin;
-    plugin->handle = lt_dlopen (plugin_filename);
-    BX_INFO (("lt_dlhandle is %p", plugin->handle));
-    if (!plugin->handle)
-    {
-      current_plugin_context = NULL;
-      BX_PANIC (("dlopen failed for module '%s': %s", name, lt_dlerror ()));
-      free (plugin);
-      return;
-    }
-
-       sprintf (buf, PLUGIN_INIT_FMT_STRING, name);
-    plugin->plugin_init =  
-      (int  (*)(struct _plugin_t *, enum plugintype_t, int, char *[])) /* monster typecast */
-      lt_dlsym (plugin->handle, buf);
-    if (plugin->plugin_init == NULL) {
-        pluginlog->panic("could not find plugin_init: %s", lt_dlerror ());
-        plugin_abort ();
-    }
-
-       sprintf (buf, PLUGIN_FINI_FMT_STRING, name);
-    plugin->plugin_fini = (void (*)(void)) lt_dlsym (plugin->handle, buf);
-    if (plugin->plugin_init == NULL) {
-        pluginlog->panic("could not find plugin_fini: %s", lt_dlerror ());
-        plugin_abort ();
-    }
-    pluginlog->info("loaded plugin %s",plugin_filename);
-
-
-    /* Insert plugin at the _end_ of the plugin linked list. */
-    plugin->next = NULL;
-
-    if (!plugins)
-    {
-        /* Empty list, this become the first entry. */
-        plugins = plugin;
-    }
-    else
-    {
-        /* Non-empty list.  Add to end. */
-        plugin_t *temp = plugins;
-
-        while (temp->next)
-            temp = temp->next;
-
-        temp->next = plugin;
-    }
-
-    plugin_init_one(plugin);
-
-    // check that context didn't change.  This should only happen if we
-    // need a reentrant plugin_load.
-    BX_ASSERT (current_plugin_context == plugin);
-    current_plugin_context = NULL;
-
-    return;
-}
-
-void
-plugin_abort (void)
-{
-    pluginlog->panic("plugin load aborted");
-}
-
-#endif   /* end of #if BX_PLUGINS */
-
-/************************************************************************/
-/* Plugin system: initialisation of plugins entry points                */
-/************************************************************************/
-
-  void
-plugin_startup(void)
-{
-  pluginRegisterIRQ = builtinRegisterIRQ;
-  pluginUnregisterIRQ = builtinUnregisterIRQ;
-
-  pluginResetSignal = builtinResetSignal;
-
-  pluginSetHRQHackCallback = builtinSetHRQHackCallback;
-  pluginSetHRQ = builtinSetHRQ;
-  
-  pluginRegisterIOReadHandler = builtinRegisterIOReadHandler;
-  pluginRegisterIOWriteHandler = builtinRegisterIOWriteHandler;
-
-  pluginRegisterDefaultIOReadHandler = builtinRegisterDefaultIOReadHandler;
-  pluginRegisterDefaultIOWriteHandler = builtinRegisterDefaultIOWriteHandler;
-
-  pluginRegisterTimer = builtinRegisterTimer;
-  pluginActivateTimer = builtinActivateTimer;
-
-#if BX_PLUGINS
-  pluginlog = new logfunctions();
-  pluginlog->put("PLGIN");
-  pluginlog->settype(PLUGINLOG);
-  int status = lt_dlinit ();
-  if (status != 0) {
-    BX_ERROR (("initialization error in ltdl library (for loading plugins)"));
-    BX_PANIC (("error message was: %s", lt_dlerror ()));
-  }
-#endif
-}
-
-
-/************************************************************************/
-/* Plugin system: Device registration                                   */
-/************************************************************************/
-
-void pluginRegisterDeviceDevmodel(plugin_t *plugin, plugintype_t type, bx_devmodel_c *devmodel, char *name)
-{
-    device_t *device;
-
-    device = (device_t *)malloc (sizeof (device_t));
-    if (!device)
-    {
-        pluginlog->panic("can't allocate device_t");
-    }
-
-    device->name = name;
-    BX_ASSERT (devmodel != NULL);
-    device->devmodel = devmodel;
-    device->plugin = plugin;  // this can be NULL
-    device->use_devmodel_interface = 1;
-    device->device_init_mem = NULL;  // maybe should use 1 to detect any use?
-    device->device_init_dev = NULL;
-    device->device_reset = NULL;
-    device->device_load_state = NULL;
-    device->device_save_state = NULL;
-    device->next = NULL;
-
-    // Don't add every kind of device to the list.
-    switch (type) {
-      case PLUGTYPE_CORE:
-       // Core devices are present whether or not we are using plugins, so
-       // they are managed by the same code in iodev/devices.cc whether
-       // plugins are on or off.  
-       return; // Do not add core devices to the devices list.
-      case PLUGTYPE_OPTIONAL:
-      case PLUGTYPE_USER:
-      default:
-       // The plugin system will manage optional and user devices only.
-       break;
-    }
-
-    if (!devices)
-    {
-        /* Empty list, this become the first entry. */
-        devices = device;
-    }
-    else
-    {
-        /* Non-empty list.  Add to end. */
-        device_t *temp = devices;
-
-        while (temp->next)
-            temp = temp->next;
-
-        temp->next = device;
-    }
-}
-
-/************************************************************************/
-/* Plugin system: Check if a plugin is loaded                           */
-/************************************************************************/
-
-bx_bool pluginDevicePresent(char *name)
-{
-    device_t *device;
-
-    for (device = devices; device; device = device->next)
-    {
-      if (strcmp(device->name,name)==0) return true;
-    }
-
-    return false;
-}
-
-#if BX_PLUGINS
-/************************************************************************/
-/* Plugin system: Load one plugin                                       */
-/************************************************************************/
-
-int bx_load_plugin (const char *name, plugintype_t type)
-{
-  char *namecopy = new char[1+strlen(name)];
-  strcpy (namecopy, name);
-  plugin_load (namecopy, "", type);
-  return 0;
-}
-#endif   /* end of #if BX_PLUGINS */
-
-/*************************************************************************/
-/* Plugin system: Execute init function of all registered plugin-devices */
-/*************************************************************************/
-
-void bx_init_plugins()
-{
-    device_t *device;
-
-    // two loops
-    for (device = devices; device; device = device->next)
-    {
-      if (!device->use_devmodel_interface) {
-        if (device->device_init_mem != NULL) {
-            pluginlog->info("init_mem of '%s' plugin device by function pointer",device->name);
-            device->device_init_mem(BX_MEM(0));
-       }
-      } else {
-       pluginlog->info("init_mem of '%s' plugin device by virtual method",device->name);
-       device->devmodel->init_mem (BX_MEM(0));
-      }
-    }
-
-    for (device = devices; device; device = device->next)
-    {
-      if (!device->use_devmodel_interface) {
-        if (device->device_init_dev != NULL) {
-            pluginlog->info("init_dev of '%s' plugin device by function pointer",device->name);
-            device->device_init_dev();
-       }
-      } else {
-       pluginlog->info("init_dev of '%s' plugin device by virtual method",device->name);
-       device->devmodel->init ();
-      }
-    } 
-}
-
-/**************************************************************************/
-/* Plugin system: Execute reset function of all registered plugin-devices */
-/**************************************************************************/
-
-void bx_reset_plugins(unsigned signal)
-{
-    device_t *device;
-    for (device = devices; device; device = device->next)
-    {
-      if (!device->use_devmodel_interface) {
-        if (device->device_reset != NULL) {
-            pluginlog->info("reset of '%s' plugin device by function pointer",device->name);
-            device->device_reset(signal);
-        }
-      } else {
-       pluginlog->info("reset of '%s' plugin device by virtual method",device->name);
-       device->devmodel->reset (signal);
-      }
-    }
-}
diff --git a/tools/ioemu/iodev/scancodes.cc b/tools/ioemu/iodev/scancodes.cc
deleted file mode 100644 (file)
index 63efed4..0000000
+++ /dev/null
@@ -1,770 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: scancodes.cc,v 1.5 2002/10/24 21:07:51 bdenney Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-// Define BX_PLUGGABLE in files that can be compiled into plugins.  For
-// platforms that require a special tag on exported symbols, BX_PLUGGABLE 
-// is used to know when we are exporting symbols and when we are importing.
-#define BX_PLUGGABLE
-
-#include "bochs.h"
-#include "scancodes.h"
-
-unsigned char translation8042[256] = {
-  0xff,0x43,0x41,0x3f,0x3d,0x3b,0x3c,0x58,0x64,0x44,0x42,0x40,0x3e,0x0f,0x29,0x59,
-  0x65,0x38,0x2a,0x70,0x1d,0x10,0x02,0x5a,0x66,0x71,0x2c,0x1f,0x1e,0x11,0x03,0x5b,
-  0x67,0x2e,0x2d,0x20,0x12,0x05,0x04,0x5c,0x68,0x39,0x2f,0x21,0x14,0x13,0x06,0x5d,
-  0x69,0x31,0x30,0x23,0x22,0x15,0x07,0x5e,0x6a,0x72,0x32,0x24,0x16,0x08,0x09,0x5f,
-  0x6b,0x33,0x25,0x17,0x18,0x0b,0x0a,0x60,0x6c,0x34,0x35,0x26,0x27,0x19,0x0c,0x61,
-  0x6d,0x73,0x28,0x74,0x1a,0x0d,0x62,0x6e,0x3a,0x36,0x1c,0x1b,0x75,0x2b,0x63,0x76,
-  0x55,0x56,0x77,0x78,0x79,0x7a,0x0e,0x7b,0x7c,0x4f,0x7d,0x4b,0x47,0x7e,0x7f,0x6f,
-  0x52,0x53,0x50,0x4c,0x4d,0x48,0x01,0x45,0x57,0x4e,0x51,0x4a,0x37,0x49,0x46,0x54,
-  0x80,0x81,0x82,0x41,0x54,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,
-  0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f,
-  0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,
-  0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf,
-  0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,
-  0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf,
-  0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef,
-  0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff
-  };
-
-
-// Definition of scancodes make and break, 
-// for each set (mf1/xt , mf2/at , mf3/ps2)
-// The table must be in BX_KEY order
-//
-scancode scancodes[BX_KEY_NBKEYS][3] =
-{
- { // BX_KEY_CTRL_L ( ibm 58)
-   { "\x1D" , "\x9D" },
-   { "\x14" , "\xF0\x14" },
-   { "\x11" , "\xF0\x11" },
- },
-
- { // BX_KEY_SHIFT_L ( ibm 44)
-   { "\x2A" , "\xAA" },
-   { "\x12" , "\xF0\x12" },
-   { "\x12" , "\xF0\x12" },
- },
-
- { // BX_KEY_F1 ( ibm 112 )
-   { "\x3B" , "\xBB" },
-   { "\x05" , "\xF0\x05" },
-   { "\x07" , "\xF0\x07" },
- },
-
- { // BX_KEY_F2 ( ibm 113 ) 
-   { "\x3C" , "\xBC" },
-   { "\x06" , "\xF0\x06" },
-   { "\x0F" , "\xF0\x0F" },
- },
-
- { // BX_KEY_F3 ( ibm 114 ) 
-   { "\x3D" , "\xBD" },
-   { "\x04" , "\xF0\x04" },
-   { "\x17" , "\xF0\x17" },
- },
-
- { // BX_KEY_F4 ( ibm 115 ) 
-   { "\x3E" , "\xBE" },
-   { "\x0C" , "\xF0\x0C" },
-   { "\x1F" , "\xF0\x1F" },
- },
-
- { // BX_KEY_F5 ( ibm 116 ) 
-   { "\x3F" , "\xBF" },
-   { "\x03" , "\xF0\x03" },
-   { "\x27" , "\xF0\x27" },
- },
-
- { // BX_KEY_F6 ( ibm 117 ) 
-   { "\x40" , "\xC0" },
-   { "\x0B" , "\xF0\x0B" },
-   { "\x2F" , "\xF0\x2F" },
- },
-
- { // BX_KEY_F7 ( ibm 118 ) 
-   { "\x41" , "\xC1" },
-   { "\x83" , "\xF0\x83" },
-   { "\x37" , "\xF0\x37" },
-},
-
- { // BX_KEY_F8 ( ibm 119 ) 
-   { "\x42" , "\xC2" },
-   { "\x0A" , "\xF0\x0A" },
-   { "\x3F" , "\xF0\x3F" },
- },
-
- { // BX_KEY_F9 ( ibm 120 ) 
-   { "\x43" , "\xC3" },
-   { "\x01" , "\xF0\x01" },
-   { "\x47" , "\xF0\x47" },
- },
-
- { // BX_KEY_F10 ( ibm 121 ) 
-   { "\x44" , "\xC4" },
-   { "\x09" , "\xF0\x09" },
-   { "\x4F" , "\xF0\x4F" },
- },
-
- { // BX_KEY_F11 ( ibm 122 ) 
-   { "\x57" , "\xD7" },
-   { "\x78" , "\xF0\x78" },
-   { "\x56" , "\xF0\x56" },
- },
-
- { // BX_KEY_F12 ( ibm 123 ) 
-   { "\x58" , "\xD8" },
-   { "\x07" , "\xF0\x07" },
-   { "\x5E" , "\xF0\x5E" },
- },
-
- { // BX_KEY_CTRL_R ( ibm 64 ) 
-   { "\xE0\x1D" , "\xE0\x9D" },
-   { "\xE0\x14" , "\xE0\xF0\x14" },
-   { "\x58" ,     "\xF0x58" },
- },
-
- { // BX_KEY_SHIFT_R ( ibm 57 ) 
-   { "\x36" , "\xB6" },
-   { "\x59" , "\xF0\x59" },
-   { "\x59" , "\xF0\x59" },
- },
-
- { // BX_KEY_CAPS_LOCK ( ibm 30 ) 
-   { "\x3A" , "\xBA" },
-   { "\x58" , "\xF0\x58" },
-   { "\x14" , "\xF0\x14" },
- },
-
- { // BX_KEY_NUM_LOCK ( ibm 90 ) 
-   { "\x45" , "\xC5" },
-   { "\x77" , "\xF0\x77" },
-   { "\x76" , "\xF0\x76" },
- },
-
- { // BX_KEY_ALT_L ( ibm 60 ) 
-   { "\x38" , "\xB8" },
-   { "\x11" , "\xF0\x11" },
-   { "\x19" , "\xF0\x19" },
- },
-
- { // BX_KEY_ALT_R ( ibm 62 ) 
-   { "\xE0\x38" , "\xE0\xB8" },
-   { "\xE0\x11" , "\xE0\xF0\x11" },
-   { "\x39" ,     "\xF0\x39" },
- },
-
- { // BX_KEY_A ( ibm 31 ) 
-   { "\x1E" , "\x9E" },
-   { "\x1C" , "\xF0\x1C" },
-   { "\x1C" , "\xF0\x1C" },
- },
-
- { // BX_KEY_B ( ibm 50 ) 
-   { "\x30" , "\xB0" },
-   { "\x32" , "\xF0\x32" },
-   { "\x32" , "\xF0\x32" },
- },
-
- { // BX_KEY_C ( ibm 48 ) 
-   { "\x2E" , "\xAE" },
-   { "\x21" , "\xF0\x21" },
-   { "\x21" , "\xF0\x21" },
- },
-
- { // BX_KEY_D ( ibm 33 ) 
-   { "\x20" , "\xA0" },
-   { "\x23" , "\xF0\x23" },
-   { "\x23" , "\xF0\x23" },
- },
-
- { // BX_KEY_E ( ibm 19 ) 
-   { "\x12" , "\x92" },
-   { "\x24" , "\xF0\x24" },
-   { "\x24" , "\xF0\x24" },
- },
-
- { // BX_KEY_F ( ibm 34 ) 
-   { "\x21" , "\xA1" },
-   { "\x2B" , "\xF0\x2B" },
-   { "\x2B" , "\xF0\x2B" },
- },
-
- { // BX_KEY_G ( ibm 35 ) 
-   { "\x22" , "\xA2" },
-   { "\x34" , "\xF0\x34" },
-   { "\x34" , "\xF0\x34" },
- },
-
- { // BX_KEY_H ( ibm 36 ) 
-   { "\x23" , "\xA3" },
-   { "\x33" , "\xF0\x33" },
-   { "\x33" , "\xF0\x33" },
- },
-
- { // BX_KEY_I ( ibm 24 ) 
-   { "\x17" , "\x97" },
-   { "\x43" , "\xF0\x43" },
-   { "\x43" , "\xF0\x43" },
- },
-
- { // BX_KEY_J ( ibm 37 ) 
-   { "\x24" , "\xA4" },
-   { "\x3B" , "\xF0\x3B" },
-   { "\x3B" , "\xF0\x3B" },
- },
-
- { // BX_KEY_K ( ibm 38 ) 
-   { "\x25" , "\xA5" },
-   { "\x42" , "\xF0\x42" },
-   { "\x42" , "\xF0\x42" },
- },
-
- { // BX_KEY_L ( ibm 39 ) 
-   { "\x26" , "\xA6" },
-   { "\x4B" , "\xF0\x4B" },
-   { "\x4B" , "\xF0\x4B" },
- },
-
- { // BX_KEY_M ( ibm 52 ) 
-   { "\x32" , "\xB2" },
-   { "\x3A" , "\xF0\x3A" },
-   { "\x3A" , "\xF0\x3A" },
- },
-
- { // BX_KEY_N ( ibm 51 ) 
-   { "\x31" , "\xB1" },
-   { "\x31" , "\xF0\x31" },
-   { "\x31" , "\xF0\x31" },
- },
-
- { // BX_KEY_O ( ibm 25 ) 
-   { "\x18" , "\x98" },
-   { "\x44" , "\xF0\x44" },
-   { "\x44" , "\xF0\x44" },
- },
-
- { // BX_KEY_P ( ibm 26 ) 
-   { "\x19" , "\x99" },
-   { "\x4D" , "\xF0\x4D" },
-   { "\x4D" , "\xF0\x4D" },
- },
-
- { // BX_KEY_Q ( ibm 17 ) 
-   { "\x10" , "\x90" },
-   { "\x15" , "\xF0\x15" },
-   { "\x15" , "\xF0\x15" },
- },
-
- { // BX_KEY_R ( ibm 20 ) 
-   { "\x13" , "\x93" },
-   { "\x2D" , "\xF0\x2D" },
-   { "\x2D" , "\xF0\x2D" },
- },
-
- { // BX_KEY_S ( ibm 32 ) 
-   { "\x1F" , "\x9F" },
-   { "\x1B" , "\xF0\x1B" },
-   { "\x1B" , "\xF0\x1B" },
- },
-
- { // BX_KEY_T ( ibm 21 ) 
-   { "\x14" , "\x94" },
-   { "\x2C" , "\xF0\x2C" },
-   { "\x2C" , "\xF0\x2C" },
- },
-
- { // BX_KEY_U ( ibm 23 ) 
-   { "\x16" , "\x96" },
-   { "\x3C" , "\xF0\x3C" },
-   { "\x3C" , "\xF0\x3C" },
- },
-
- { // BX_KEY_V ( ibm 49 ) 
-   { "\x2F" , "\xAF" },
-   { "\x2A" , "\xF0\x2A" },
-   { "\x2A" , "\xF0\x2A" },
- },
-
- { // BX_KEY_W ( ibm 18 ) 
-   { "\x11" , "\x91" },
-   { "\x1D" , "\xF0\x1D" },
-   { "\x1D" , "\xF0\x1D" },
- },
-
- { // BX_KEY_X ( ibm 47 ) 
-   { "\x2D" , "\xAD" },
-   { "\x22" , "\xF0\x22" },
-   { "\x22" , "\xF0\x22" },
- },
-
- { // BX_KEY_Y ( ibm 22 ) 
-   { "\x15" , "\x95" },
-   { "\x35" , "\xF0\x35" },
-   { "\x35" , "\xF0\x35" },
- },
-
- { // BX_KEY_Z ( ibm 46 ) 
-   { "\x2C" , "\xAC" },
-   { "\x1A" , "\xF0\x1A" },
-   { "\x1A" , "\xF0\x1A" },
- },
-
- { // BX_KEY_0 ( ibm 11 ) 
-   { "\x0B" , "\x8B" },
-   { "\x45" , "\xF0\x45" },
-   { "\x45" , "\xF0\x45" },
- },
-
- { // BX_KEY_1 ( ibm 2 ) 
-   { "\x02" , "\x82" },
-   { "\x16" , "\xF0\x16" },
-   { "\x16" , "\xF0\x16" },
- },
-
- { // BX_KEY_2 ( ibm 3 ) 
-   { "\x03" , "\x83" },
-   { "\x1E" , "\xF0\x1E" },
-   { "\x1E" , "\xF0\x1E" },
- },
-
- { // BX_KEY_3 ( ibm 4 ) 
-   { "\x04" , "\x84" },
-   { "\x26" , "\xF0\x26" },
-   { "\x26" , "\xF0\x26" },
- },
-
- { // BX_KEY_4 ( ibm 5 ) 
-   { "\x05" , "\x85" },
-   { "\x25" , "\xF0\x25" },
-   { "\x25" , "\xF0\x25" },
- },
-
- { // BX_KEY_5 ( ibm 6 ) 
-   { "\x06" , "\x86" },
-   { "\x2E" , "\xF0\x2E" },
-   { "\x2E" , "\xF0\x2E" },
- },
-
- { // BX_KEY_6 ( ibm 7 ) 
-   { "\x07" , "\x87" },
-   { "\x36" , "\xF0\x36" },
-   { "\x36" , "\xF0\x36" },
- },
-
- { // BX_KEY_7 ( ibm 8 ) 
-   { "\x08" , "\x88" },
-   { "\x3D" , "\xF0\x3D" },
-   { "\x3D" , "\xF0\x3D" },
- },
-
- { // BX_KEY_8 ( ibm 9 ) 
-   { "\x09" , "\x89" },
-   { "\x3E" , "\xF0\x3E" },
-   { "\x3E" , "\xF0\x3E" },
- },
-
- { // BX_KEY_9 ( ibm 10 ) 
-   { "\x0A" , "\x8A" },
-   { "\x46" , "\xF0\x46" },
-   { "\x46" , "\xF0\x46" },
- },
-
- { // BX_KEY_ESC ( ibm 110 ) 
-   { "\x01" , "\x81" },
-   { "\x76" , "\xF0\x76" },
-   { "\x08" , "\xF0\x08" },
- },
-
- { // BX_KEY_SPACE ( ibm 61 ) 
-   { "\x39" , "\xB9" },
-   { "\x29" , "\xF0\x29" },
-   { "\x29" , "\xF0\x29" },
- },
-
- { // BX_KEY_SINGLE_QUOTE ( ibm 41 ) 
-   { "\x28" , "\xA8" },
-   { "\x52" , "\xF0\x52" },
-   { "\x52" , "\xF0\x52" },
- },
-
- { // BX_KEY_COMMA ( ibm 53 ) 
-   { "\x33" , "\xB3" },
-   { "\x41" , "\xF0\x41" },
-   { "\x41" , "\xF0\x41" },
- },
-
- { // BX_KEY_PERIOD ( ibm 54 ) 
-   { "\x34" , "\xB4" },
-   { "\x49" , "\xF0\x49" },
-   { "\x49" , "\xF0\x49" },
- },
-
- { // BX_KEY_SLASH ( ibm 55 ) 
-   { "\x35" , "\xB5" },
-   { "\x4A" , "\xF0\x4A" },
-   { "\x4A" , "\xF0\x4A" },
- },
-
- { // BX_KEY_SEMICOLON ( ibm 40 ) 
-   { "\x27" , "\xA7" },
-   { "\x4C" , "\xF0\x4C" },
-   { "\x4C" , "\xF0\x4C" },
- },
-
- { // BX_KEY_EQUALS ( ibm 13 ) 
-   { "\x0D" , "\x8D" },
-   { "\x55" , "\xF0\x55" },
-   { "\x55" , "\xF0\x55" },
- },
-
- { // BX_KEY_LEFT_BRACKET ( ibm 27 ) 
-   { "\x1A" , "\x9A" },
-   { "\x54" , "\xF0\x54" },
-   { "\x54" , "\xF0\x54" },
- },
-
- { // BX_KEY_BACKSLASH ( ibm 42, 29)
-   { "\x2B" , "\xAB" },
-   { "\x5D" , "\xF0\x5D" },
-   { "\x53" , "\xF0\x53" },
- },
-
- { // BX_KEY_RIGHT_BRACKET ( ibm 28 ) 
-   { "\x1B" , "\x9B" },
-   { "\x5B" , "\xF0\x5B" },
-   { "\x5B" , "\xF0\x5B" },
- },
-
- { // BX_KEY_MINUS ( ibm 12 ) 
-   { "\x0C" , "\x8C" },
-   { "\x4E" , "\xF0\x4E" },
-   { "\x4E" , "\xF0\x4E" },
- },
-
- { // BX_KEY_GRAVE ( ibm 1 ) 
-   { "\x29" , "\xA9" },
-   { "\x0E" , "\xF0\x0E" },
-   { "\x0E" , "\xF0\x0E" },
- },
-
- { // BX_KEY_BACKSPACE ( ibm 15 ) 
-   { "\x0E" , "\x8E" },
-   { "\x66" , "\xF0\x66" },
-   { "\x66" , "\xF0\x66" },
- },
-
- { // BX_KEY_ENTER ( ibm 43 ) 
-   { "\x1C" , "\x9C" },
-   { "\x5A" , "\xF0\x5A" },
-   { "\x5A" , "\xF0\x5A" },
- },
-
- { // BX_KEY_TAB ( ibm 16 ) 
-   { "\x0F" , "\x8F" },
-   { "\x0D" , "\xF0\x0D" },
-   { "\x0D" , "\xF0\x0D" },
- },
-
- { // BX_KEY_LEFT_BACKSLASH ( ibm 45 ) 
-   { "\x56" , "\xD6" },
-   { "\x61" , "\xF0\x61" },
-   { "\x13" , "\xF0\x13" },
- },
-
- { // BX_KEY_PRINT ( ibm 124 ) 
-   { "\xE0\x37" , "\xE0\xB7" },
-   { "\xE0\x7C" , "\xE0\xF0\x7C" },
-   { "\x57" ,     "\xF0\x57" },
- },
-
- { // BX_KEY_SCRL_LOCK ( ibm 125 ) 
-   { "\x46" , "\xC6" },
-   { "\x7E" , "\xF0\x7E" },
-   { "\x5F" , "\xF0\x5F" },
- },
-
- { // BX_KEY_PAUSE ( ibm 126 ) 
-   { "\xE1\x1D\x45\xE1\x9D\xC5" ,         "" },
-   { "\xE1\x14\x77\xE1\xF0\x14\xF0\x77" , "" },
-   { "\x62" ,                             "\xF0\x62" },
- },
-
- { // BX_KEY_INSERT ( ibm 75 ) 
-   { "\xE0\x52" , "\xE0\xD2" },
-   { "\xE0\x70" , "\xE0\xF0\x70" },
-   { "\x67" ,     "\xF0\x67" },
- },
-
- { // BX_KEY_DELETE ( ibm 76 ) 
-   { "\xE0\x53" , "\xE0\xD3" },
-   { "\xE0\x71" , "\xE0\xF0\x71" },
-   { "\x64" ,     "\xF0\x64" },
- },
-
- { // BX_KEY_HOME ( ibm 80 ) 
-   { "\xE0\x47" , "\xE0\xC7" },
-   { "\xE0\x6C" , "\xE0\xF0\x6C" },
-   { "\x6E" ,     "\xF0\x6E" },
- },
-
- { // BX_KEY_END ( ibm 81 ) 
-   { "\xE0\x4F" , "\xE0\xCF" },
-   { "\xE0\x69" , "\xE0\xF0\x69" },
-   { "\x65" ,     "\xF0\x65" },
- },
-
- { // BX_KEY_PAGE_UP ( ibm 85 ) 
-   { "\xE0\x49" , "\xE0\xC9" },
-   { "\xE0\x7D" , "\xE0\xF0\x7D" },
-   { "\x6F" ,     "\xF0\x6F" },
- },
-
- { // BX_KEY_PAGE_DOWN ( ibm 86 ) 
-   { "\xE0\x51" , "\xE0\xD1" },
-   { "\xE0\x7A" , "\xE0\xF0\x7A" },
-   { "\x6D" ,     "\xF0\x6D" },
- },
-
- { // BX_KEY_KP_ADD ( ibm 106 ) 
-   { "\x4E" , "\xCE" },
-   { "\x79" , "\xF0\x79" },
-   { "\x7C" , "\xF0\x7C" },
- },
-
- { // BX_KEY_KP_SUBTRACT ( ibm 105 ) 
-   { "\x4A" , "\xCA" },
-   { "\x7B" , "\xF0\x7B" },
-   { "\x84" , "\xF0\x84" },
- },
-
- { // BX_KEY_KP_END ( ibm 93 ) 
-   { "\x4F" , "\xCF" },
-   { "\x69" , "\xF0\x69" },
-   { "\x69" , "\xF0\x69" },
- },
-
- { // BX_KEY_KP_DOWN ( ibm 98 ) 
-   { "\x50" , "\xD0" },
-   { "\x72" , "\xF0\x72" },
-   { "\x72" , "\xF0\x72" },
- },
-
- { // BX_KEY_KP_PAGE_DOWN ( ibm 103 ) 
-   { "\x51" , "\xD1" },
-   { "\x7A" , "\xF0\x7A" },
-   { "\x7A" , "\xF0\x7A" },
- },
-
- { // BX_KEY_KP_LEFT ( ibm 92 ) 
-   { "\x4B" , "\xCB" },
-   { "\x6B" , "\xF0\x6B" },
-   { "\x6B" , "\xF0\x6B" },
- },
-
- { // BX_KEY_KP_RIGHT ( ibm 102 ) 
-   { "\x4D" , "\xCD" },
-   { "\x74" , "\xF0\x74" },
-   { "\x74" , "\xF0\x74" },
- },
-
- { // BX_KEY_KP_HOME ( ibm 91 ) 
-   { "\x47" , "\xC7" },
-   { "\x6C" , "\xF0\x6C" },
-   { "\x6C" , "\xF0\x6C" },
- },
-
- { // BX_KEY_KP_UP ( ibm 96 ) 
-   { "\x48" , "\xC8" },
-   { "\x75" , "\xF0\x75" },
-   { "\x75" , "\xF0\x75" },
- },
-
- { // BX_KEY_KP_PAGE_UP ( ibm 101 ) 
-   { "\x49" , "\xC9" },
-   { "\x7D" , "\xF0\x7D" },
-   { "\x7D" , "\xF0\x7D" },
- },
-
- { // BX_KEY_KP_INSERT ( ibm 99 ) 
-   { "\x52" , "\xD2" },
-   { "\x70" , "\xF0\x70" },
-   { "\x70" , "\xF0\x70" },
- },
-
- { // BX_KEY_KP_DELETE ( ibm 104 ) 
-   { "\x53" , "\xD3" },
-   { "\x71" , "\xF0\x71" },
-   { "\x71" , "\xF0\x71" },
- },
-
- { // BX_KEY_KP_5 ( ibm 97 ) 
-   { "\x4C" , "\xCC" },
-   { "\x73" , "\xF0\x73" },
-   { "\x73" , "\xF0\x73" },
- },
-
- { // BX_KEY_UP ( ibm 83 ) 
-   { "\xE0\x48" , "\xE0\xC8" },
-   { "\xE0\x75" , "\xE0\xF0\x75" },
-   { "\x63" ,     "\xF0\x63" },
- },
-
- { // BX_KEY_DOWN ( ibm 84 ) 
-   { "\xE0\x50" , "\xE0\xD0" },
-   { "\xE0\x72" , "\xE0\xF0\x72" },
-   { "\x60" ,     "\xF0\x60" },
- },
-
- { // BX_KEY_LEFT ( ibm 79 ) 
-   { "\xE0\x4B" , "\xE0\xCB" },
-   { "\xE0\x6B" , "\xE0\xF0\x6B" },
-   { "\x61" ,     "\xF0\x61" },
- },
-
- { // BX_KEY_RIGHT ( ibm 89 ) 
-   { "\xE0\x4D" , "\xE0\xCD" },
-   { "\xE0\x74" , "\xE0\xF0\x74" },
-   { "\x6A" ,     "\xF0\x6A" },
- },
-
- { // BX_KEY_KP_ENTER ( ibm 108 ) 
-   { "\xE0\x1C" , "\xE0\x9C" },
-   { "\xE0\x5A" , "\xE0\xF0\x5A" },
-   { "\x79" ,     "\xF0\x79" },
- },
-
- { // BX_KEY_KP_MULTIPLY ( ibm 100 ) 
-   { "\x37" , "\xB7" },
-   { "\x7C" , "\xF0\x7C" },
-   { "\x7E" , "\xF0\x7E" },
- },
-
- { // BX_KEY_KP_DIVIDE ( ibm 95 ) 
-   { "\xE0\x35" , "\xE0\xB5" },
-   { "\xE0\x4A" , "\xE0\xF0\x4A" },
-   { "\x77" ,     "\xF0\x77" },
- },
-
- { // BX_KEY_WIN_L 
-   { "\xE0\x5B" , "\xE0\xDB" },
-   { "\xE0\x1F" , "\xE0\xF0\x1F" },
-   { "\x8B" ,     "\xF0\x8B" },
- },
-
- { // BX_KEY_WIN_R
-   { "\xE0\x5C" , "\xE0\xDC" },
-   { "\xE0\x27" , "\xE0\xF0\x27" },
-   { "\x8C" ,     "\xF0\x8C" },
- },
-
- { // BX_KEY_MENU
-   { "\xE0\x5D" , "\xE0\xDD" },
-   { "\xE0\x2F" , "\xE0\xF0\x2F" },
-   { "\x8D" ,     "\xF0\x8D" },
- },
-
- { // BX_KEY_ALT_SYSREQ
-   { "\x54" ,   "\xD4" },
-   { "\x84" ,   "\xF0\x84" },
-   { "\x57" ,   "\xF0\x57" },
- },
-
- { // BX_KEY_CTRL_BREAK
-   { "\xE0\x46" , "\xE0\xC6" },
-   { "\xE0\x7E" , "\xE0\xF0\x7E" },
-   { "\x62" ,     "\xF0\x62" },
- },
-
- { // BX_KEY_INT_BACK
-   { "\xE0\x6A" , "\xE0\xEA" },
-   { "\xE0\x38" , "\xE0\xF0\x38" },
-   { "\x38" ,     "\xF0\x38" },
- },
-
- { // BX_KEY_INT_FORWARD
-   { "\xE0\x69" , "\xE0\xE9" },
-   { "\xE0\x30" , "\xE0\xF0\x30" },
-   { "\x30" ,     "\xF0\x30" },
- },
-
- { // BX_KEY_INT_STOP
-   { "\xE0\x68" , "\xE0\xE8" },
-   { "\xE0\x28" , "\xE0\xF0\x28" },
-   { "\x28" ,     "\xF0\x28" },
- },
-
- { // BX_KEY_INT_MAIL
-   { "\xE0\x6C" , "\xE0\xEC" },
-   { "\xE0\x48" , "\xE0\xF0\x48" },
-   { "\x48" ,     "\xF0\x48" },
- },
-
- { // BX_KEY_INT_SEARCH
-   { "\xE0\x65" , "\xE0\xE5" },
-   { "\xE0\x10" , "\xE0\xF0\x10" },
-   { "\x10" ,     "\xF0\x10" },
- },
-
- { // BX_KEY_INT_FAV
-   { "\xE0\x66" , "\xE0\xE6" },
-   { "\xE0\x18" , "\xE0\xF0\x18" },
-   { "\x18" ,     "\xF0\x18" },
- },
-
- { // BX_KEY_INT_HOME
-   { "\xE0\x32" , "\xE0\xB2" },
-   { "\xE0\x3A" , "\xE0\xF0\x3A" },
-   { "\x97" ,     "\xF0\x97" },
- },
-
- { // BX_KEY_POWER_MYCOMP
-   { "\xE0\x6B" , "\xE0\xEB" },
-   { "\xE0\x40" , "\xE0\xF0\x40" },
-   { "\x40" ,     "\xF0\x40" },
- },
-
- { // BX_KEY_POWER_CALC
-   { "\xE0\x21" , "\xE0\xA1" },
-   { "\xE0\x2B" , "\xE0\xF0\x2B" },
-   { "\x99" ,     "\xF0\x99" },
- },
-
- { // BX_KEY_POWER_SLEEP
-   { "\xE0\x5F" , "\xE0\xDF" },
-   { "\xE0\x3F" , "\xE0\xF0\x3F" },
-   { "\x7F" ,     "\xF0\x7F" },
- },
-
- { // BX_KEY_POWER_POWER
-   { "\xE0\x5E" , "\xE0\xDE" },
-   { "\xE0\x37" , "\xE0\xF0\x37" },
-   { "" ,         "" },
- },
-
- { // BX_KEY_POWER_WAKE
-   { "\xE0\x63" , "\xE0\xE3" },
-   { "\xE0\x5E" , "\xE0\xF0\x5E" },
-   { "" ,         "" },
- },
-
-};
diff --git a/tools/ioemu/iodev/scancodes.h b/tools/ioemu/iodev/scancodes.h
deleted file mode 100644 (file)
index f26491b..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: scancodes.h,v 1.4 2002/10/24 21:07:51 bdenney Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-// Translation table of the 8042
-extern unsigned char translation8042[256];
-
-typedef struct { 
-  const char *make;
-  const char *brek;
-  }scancode;
-
-// Scancodes table
-extern scancode scancodes[BX_KEY_NBKEYS][3];
diff --git a/tools/ioemu/iodev/scsi_commands.h b/tools/ioemu/iodev/scsi_commands.h
deleted file mode 100644 (file)
index c516fde..0000000
+++ /dev/null
@@ -1,418 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: scsi_commands.h,v 1.3 2001/10/03 13:10:38 bdenney Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-/* scsi/commands.h
-   Used only in cdrom_amigaos.cc.
-
-       Operation codes for SCSI-2 commands
-
-   30 Nov 94   Peter Urbanec    Created file
-   10 Jan 95   Peter Urbanec    Added SCSI_ prefix to all commands
-   31 Jan 95   Peter Urbanec    Released to public
-
-*/
-
-
-/* All device types */
-
-#define SCSI_CHANGE_DEFINITION                 0x40
-#define SCSI_COMPARE                           0x39
-#define SCSI_COPY                              0x18
-#define SCSI_COPY_AND_VERIFY                   0x3a
-#define SCSI_INQUIRY                           0x12
-#define SCSI_LOG_SELECT                                0x4c
-#define SCSI_LOG_SENSE                         0x4d
-#define SCSI_MODE_SELECT_6                     0x15
-#define SCSI_MODE_SELECT_10                    0x55
-#define SCSI_MODE_SENSE_6                      0x1a
-#define SCSI_MODE_SENSE_10                     0x5a
-#define SCSI_READ_BUFFER                       0x3c
-#define SCSI_RECEIVE_DIAGNOSTIC_RESULTS                0x1c
-#define SCSI_REQUEST_SENSE                     0x03
-#define SCSI_SEND_DIAGNOSTIC                   0x1d
-#define SCSI_TEST_UNIT_READY                   0x00
-#define SCSI_WRITE_BUFFER                      0x3b
-
-
-/* Direct Access devices */
-
-#define SCSI_DA_CHANGE_DEFINITION              0x40
-#define SCSI_DA_COMPARE                                0x39
-#define SCSI_DA_COPY                           0x18
-#define SCSI_DA_COPY_AND_VERIFY                        0x3a
-#define SCSI_DA_FORMAT_UNIT                    0x04
-#define SCSI_DA_INQUIRY                                0x12
-#define SCSI_DA_LOCK_UNLOCK_CACHE              0x36
-#define SCSI_DA_LOG_SELECT                     0x4c
-#define SCSI_DA_LOG_SENSE                      0x4d
-#define SCSI_DA_MODE_SELECT_6                  0x15
-#define SCSI_DA_MODE_SELECT_10                 0x55
-#define SCSI_DA_MODE_SENSE_6                   0x1a
-#define SCSI_DA_MODE_SENSE_10                  0x5a
-#define SCSI_DA_PRE_FETCH                      0x34
-#define SCSI_DA_PREVENT_ALLOW_MEDIUM_REMOVAL   0x1e
-#define SCSI_DA_READ_6                         0x08
-#define SCSI_DA_READ_10                                0x28
-#define SCSI_DA_READ_BUFFER                    0x3c
-#define SCSI_DA_READ_CAPACITY                  0x25
-#define SCSI_DA_READ_DEFECT_DATA               0x37
-#define SCSI_DA_READ_LONG                      0x3e
-#define SCSI_DA_REASSIGN_BLOCKS                        0x07
-#define SCSI_DA_RECEIVE_DIAGNOSTIC_RESULTS     0x1c
-#define SCSI_DA_RELEASE                                0x17
-#define SCSI_DA_REQUEST_SENSE                  0x03
-#define SCSI_DA_RESERVE                                0x16
-#define SCSI_DA_REZERO_UNIT                    0x01
-#define SCSI_DA_SEARCH_DATA_EQUAL              0x31
-#define SCSI_DA_SEARCH_DATA_HIGH               0x30
-#define SCSI_DA_SEARCH_DATA_LOW                        0x32
-#define SCSI_DA_SEEK_6                         0x0b
-#define SCSI_DA_SEEK_10                                0x2b
-#define SCSI_DA_SEND_DIAGNOSTIC                        0x1d
-#define SCSI_DA_SET_LIMITS                     0x33
-#define SCSI_DA_START_STOP_UNIT                        0x1b
-#define SCSI_DA_SYNCHRONIZE_CACHE              0x35
-#define SCSI_DA_TEST_UNIT_READY                        0x00
-#define SCSI_DA_VERIFY                         0x2f
-
-
-/* Sequential access devices */
-
-#define SCSI_SA_CHANGE_DEFINITION              0x40
-#define SCSI_SA_COMPARE                                0x39
-#define SCSI_SA_COPY                           0x18
-#define SCSI_SA_COPY_AND_VERIFY                        0x3a
-#define SCSI_SA_ERASE                          0x19
-#define SCSI_SA_INQUIRY                                0x12
-#define SCSI_SA_LOAD_UNLOAD                    0x1b
-#define SCSI_SA_LOCATE                         0x2b
-#define SCSI_SA_LOG_SELECT                     0x4c
-#define SCSI_SA_LOG_SENSE                      0x4d
-#define SCSI_SA_MODE_SELECT_6                  0x15
-#define SCSI_SA_MODE_SELECT_10                 0x55
-#define SCSI_SA_MODE_SENSE_6                   0x1a
-#define SCSI_SA_MODE_SENSE_10                  0x5a
-#define SCSI_SA_PREVENT_ALLOW_MEDIUM_REMOVAL   0x1e
-#define SCSI_SA_READ                           0x08
-#define SCSI_SA_READ_BLOCK_LIMITS              0x05
-#define SCSI_SA_READ_BUFFER                    0x3c
-#define SCSI_SA_READ_POSITION                  0x34
-#define SCSI_SA_READ_REVERSE                   0x0f
-#define SCSI_SA_RECEIVE_DIAGNOSTIC_RESULTS     0x1c
-#define SCSI_SA_RECOVER_BUFFERED_DATA          0x14
-#define SCSI_SA_RELEASE_UNIT                   0x17
-#define SCSI_SA_REQUEST_SENSE                  0x03
-#define SCSI_SA_RESERVE_UNIT                   0x16
-#define SCSI_SA_REWIND                         0x01
-#define SCSI_SA_SEND_DIAGNOSTIC                        0x1d
-#define SCSI_SA_SPACE                          0x11
-#define SCSI_SA_TEST_UNIT_READY                        0x00
-#define SCSI_SA_VERIFY                         0x13
-#define SCSI_SA_WRITE                          0x0a
-#define SCSI_SA_WRITE_BUFFER                   0x3b
-#define SCSI_SA_WRITE_FILEMARKS                        0x10
-
-
-/* Printer devices */
-
-#define SCSI_PRT_CHANGE_DEFINITION             0x40
-#define SCSI_PRT_COMPARE                       0x39
-#define SCSI_PRT_COPY                          0x18
-#define SCSI_PRT_COPY_AND_VERIFY               0x3a
-#define SCSI_PRT_FORMAT                                0x04
-#define SCSI_PRT_INQUIRY                       0x12
-#define SCSI_PRT_LOG_SELECT                    0x4c
-#define SCSI_PRT_LOG_SENSE                     0x4d
-#define SCSI_PRT_MODE_SELECT_6                 0x15
-#define SCSI_PRT_MODE_SELECT_10                        0x55
-#define SCSI_PRT_MODE_SENSE_6                  0x1a
-#define SCSI_PRT_MODE_SENSE_10                 0x5a
-#define SCSI_PRT_PRINT                         0x0a
-#define SCSI_PRT_READ_BUFFER                   0x3c
-#define SCSI_PRT_RECEIVE_DIAGNOSTIC_RESULTS    0x1c
-#define SCSI_PRT_RECOVER_BUFFERED_DATA         0x14
-#define SCSI_PRT_RELEASE_UNIT                  0x17
-#define SCSI_PRT_REQUEST_SENSE                 0x03
-#define SCSI_PRT_RESERVE_UNIT                  0x16
-#define SCSI_PRT_SEND_DIAGNOSTIC               0x1d
-#define SCSI_PRT_SLEW_AND_PRINT                        0x0b
-#define SCSI_PRT_STOP_PRINT                    0x1b
-#define SCSI_PRT_SYNCHRONIZE_BUFFER            0x10
-#define SCSI_PRT_TEST_UNIT_READY               0x00
-#define SCSI_PRT_WRITE_BUFFER                  0x3b
-
-
-/* Processor devices */
-
-#define SCSI_CPU_CHANGE_DEFINITION             0x40
-#define SCSI_CPU_COMPARE                       0x39
-#define SCSI_CPU_COPY                          0x18
-#define SCSI_CPU_COPY_AND_VERIFY               0x3a
-#define SCSI_CPU_INQUIRY                       0x12
-#define SCSI_CPU_LOG_SELECT                    0x4c
-#define SCSI_CPU_LOG_SENSE                     0x4d
-#define SCSI_CPU_READ_BUFFER                   0x3c
-#define SCSI_CPU_RECEIVE                       0x08
-#define SCSI_CPU_RECEIVE_DIAGNOSTIC_RESULTS    0x1c
-#define SCSI_CPU_REQUEST_SENSE                 0x03
-#define SCSI_CPU_SEND                          0x0a
-#define SCSI_CPU_SEND_DIAGNOSTIC               0x1d
-#define SCSI_CPU_TEST_UNIT_READY               0x00
-#define SCSI_CPU_WRITE_BUFFER                  0x3b
-
-
-/* Write Once devices */
-
-#define SCSI_WO_CHANGE_DEFINITION              0x40
-#define SCSI_WO_COMPARE                                0x39
-#define SCSI_WO_COPY                           0x18
-#define SCSI_WO_COPY_AND_VERIFY                        0x3a
-#define SCSI_WO_INQUIRY                                0x12
-#define SCSI_WO_LOCK_UNLOCK_CACHE              0x36
-#define SCSI_WO_LOG_SELECT                     0x4c
-#define SCSI_WO_LOG_SENSE                      0x4d
-#define SCSI_WO_MEDIUM_SCAN                    0x38
-#define SCSI_WO_MODE_SELECT_6                  0x15
-#define SCSI_WO_MODE_SELECT_10                 0x55
-#define SCSI_WO_MODE_SENSE_6                   0x1a
-#define SCSI_WO_MODE_SENSE_10                  0x5a
-#define SCSI_WO_PRE_FETCH                      0x34
-#define SCSI_WO_PREVENT_ALLOW_MEDIUM_REMOVAL   0x1e
-#define SCSI_WO_READ_6                         0x08
-#define SCSI_WO_READ_10                                0x28
-#define SCSI_WO_READ_12                                0xa8
-#define SCSI_WO_READ_BUFFER                    0x3c
-#define SCSI_WO_READ_CAPACITY                  0x25
-#define SCSI_WO_READ_LONG                      0x3e
-#define SCSI_WO_REASSIGN_BLOCKS                        0x07
-#define SCSI_WO_RECEIVE_DIAGNOSTIC_RESULTS     0x1c
-#define SCSI_WO_RELEASE                                0x17
-#define SCSI_WO_REQUEST_SENSE                  0x03
-#define SCSI_WO_RESERVE                                0x16
-#define SCSI_WO_REZERO_UNIT                    0x01
-#define SCSI_WO_SEARCH_DATA_EQUAL_10           0x31
-#define SCSI_WO_SEARCH_DATA_EQUAL_12           0xb1
-#define SCSI_WO_SEARCH_DATA_HIGH_10            0x30
-#define SCSI_WO_SEARCH_DATA_HIGH_12            0xb0
-#define SCSI_WO_SEARCH_DATA_LOW_10             0x32
-#define SCSI_WO_SEARCH_DATA_LOW_12             0xb2
-#define SCSI_WO_SEEK_6                         0x0b
-#define SCSI_WO_SEEK_10                                0x2b
-#define SCSI_WO_SEND_DIAGNOSTIC                        0x1d
-#define SCSI_WO_SET_LIMITS_10                  0x33
-#define SCSI_WO_SET_LIMITS_12                  0xb3
-#define SCSI_WO_START_STOP_UNIT                        0x1b
-#define SCSI_WO_SYNCHRONIZE_CACHE              0x35
-#define SCSI_WO_TEST_UNIT_READY                        0x00
-#define SCSI_WO_VERIFY_10                      0x2f
-#define SCSI_WO_VERIFY_12                      0xaf
-#define SCSI_WO_WRITE_6                                0x0a
-#define SCSI_WO_WRITE_10                       0x2a
-#define SCSI_WO_WRITE_12                       0xaa
-#define SCSI_WO_WRITE_AND_VERIFY_10            0x2e
-#define SCSI_WO_WRITE_AND_VERIFY_12            0xae
-#define SCSI_WO_WRITE_BUFFER                   0x3b
-#define SCSI_WO_WRITE_LONG                     0x3f
-
-
-/* CD-ROM devices */
-
-#define SCSI_CD_CHANGE_DEFINITION              0x40
-#define SCSI_CD_COMPARE                                0x39
-#define SCSI_CD_COPY                           0x18
-#define SCSI_CD_COPY_AND_VERIFY                        0x3a
-#define SCSI_CD_INQUIRY                                0x12
-#define SCSI_CD_LOCK_UNLOCK_CACHE              0x36
-#define SCSI_CD_LOG_SELECT                     0x4c
-#define SCSI_CD_LOG_SENSE                      0x4d
-#define SCSI_CD_MODE_SELECT_6                  0x15
-#define SCSI_CD_MODE_SELECT_10                 0x55
-#define SCSI_CD_MODE_SENSE_6                   0x1a
-#define SCSI_CD_MODE_SENSE_10                  0x5a
-#define SCSI_CD_PAUSE_RESUME                   0x4b
-#define SCSI_CD_PLAY_AUDIO_10                  0x45
-#define SCSI_CD_PLAY_AUDIO_12                  0xa5
-#define SCSI_CD_PLAY_AUDIO_MSF                 0x47
-#define SCSI_CD_PLAY_AUDIO_TRACK_INDEX         0x48
-#define SCSI_CD_PLAY_TRACK_RELATIVE_10         0x49
-#define SCSI_CD_PLAY_TRACK_RELATIVE_12         0xa9
-#define SCSI_CD_PRE_FETCH                      0x34
-#define SCSI_CD_PREVENT_ALLOW_MEDIUM_REMOVAL   0x1e
-#define SCSI_CD_READ_6                         0x08
-#define SCSI_CD_READ_10                                0x28
-#define SCSI_CD_READ_12                                0xa8
-#define SCSI_CD_READ_BUFFER                    0x3c
-#define SCSI_CD_READ_CD_ROM_CAPACITY           0x25
-#define SCSI_CD_READ_HEADER                    0x44
-#define SCSI_CD_READ_LONG                      0x3e
-#define SCSI_CD_READ_SUB_CHANNEL               0x42
-#define SCSI_CD_READ_TOC                       0x43
-#define SCSI_CD_RECEIVE_DIAGNOSTIC_RESULT      0x1c
-#define SCSI_CD_RELEASE                                0x17
-#define SCSI_CD_REQUEST_SENSE                  0x03
-#define SCSI_CD_RESERVE                                0x16
-#define SCSI_CD_REZERO_UNIT                    0x01
-#define SCSI_CD_SEARCH_DATA_EQUAL_10           0x31
-#define SCSI_CD_SEARCH_DATA_EQUAL_12           0xb1
-#define SCSI_CD_SEARCH_DATA_HIGH_10            0x30
-#define SCSI_CD_SEARCH_DATA_HIGH_12            0xb0
-#define SCSI_CD_SEARCH_DATA_LOW_10             0x32
-#define SCSI_CD_SEARCH_DATA_LOW_12             0xb2
-#define SCSI_CD_SEEK_6                         0x0b
-#define SCSI_CD_SEEK_10                                0x2b
-#define SCSI_CD_SEND_DIAGNOSTIC                        0x1d
-#define SCSI_CD_SET_LIMITS_10                  0x33
-#define SCSI_CD_SET_LIMITS_12                  0xb3
-#define SCSI_CD_START_STOP_UNIT                        0x1b
-#define SCSI_CD_SYNCHRONIZE_CACHE              0x35
-#define SCSI_CD_TEST_UNIT_READY                        0x00
-#define SCSI_CD_VERIFY_10                      0x2f
-#define SCSI_CD_VERIFY_12                      0xaf
-#define SCSI_CD_WRITE_BUFFER                   0x3b
-
-
-/* Scanner devices */
-
-#define SCSI_SC_CHANGE_DEFINITION              0x40
-#define SCSI_SC_COMPARE                                0x39
-#define SCSI_SC_COPY                           0x18
-#define SCSI_SC_COPY_AND_VERIFY                        0x3a
-#define SCSI_SC_GET_DATA_BUFFER_STATUS         0x34
-#define SCSI_SC_GET_WINDOW                     0x25
-#define SCSI_SC_INQUIRY                                0x12
-#define SCSI_SC_LOG_SELECT                     0x4c
-#define SCSI_SC_LOG_SENSE                      0x4d
-#define SCSI_SC_MODE_SELECT_6                  0x15
-#define SCSI_SC_MODE_SELECT_10                 0x55
-#define SCSI_SC_MODE_SENSE_6                   0x1a
-#define SCSI_SC_MODE_SENSE_10                  0x5a
-#define SCSI_SC_OBJECT_POSITION                        0x31
-#define SCSI_SC_READ                           0x28
-#define SCSI_SC_READ_BUFFER                    0x3c
-#define SCSI_SC_RECEIVE_DIAGNOSTIC_RESULTS     0x1c
-#define SCSI_SC_RELEASE_UNIT                   0x17
-#define SCSI_SC_REQUEST_SENSE                  0x03
-#define SCSI_SC_RESERVE_UNIT                   0x16
-#define SCSI_SC_SCAN                           0x1b
-#define SCSI_SC_SET_WINDOW                     0x24
-#define SCSI_SC_SEND                           0x2a
-#define SCSI_SC_SEND_DIAGNOSTIC                        0x1d
-#define SCSI_SC_TEST_UNIT_READY                        0x00
-#define SCSI_SC_WRITE_BUFFER                   0x3b
-
-
-/* Optical memory devices */
-
-#define SCSI_OM_CHANGE_DEFINITION              0x40
-#define SCSI_OM_COMPARE                                0x39
-#define SCSI_OM_COPY                           0x18
-#define SCSI_OM_COPY_AND_VERIFY                        0x3a
-#define SCSI_OM_ERASE_10                       0x2c
-#define SCSI_OM_ERASE_12                       0xac
-#define SCSI_OM_FORMAT_UNIT                    0x04
-#define SCSI_OM_INQUIRY                                0x12
-#define SCSI_OM_LOCK_UNLOCK_CACHE              0x36
-#define SCSI_OM_LOG_SELECT                     0x4c
-#define SCSI_OM_LOG_SENSE                      0x4d
-#define SCSI_OM_MEDIUM_SCAN                    0x38
-#define SCSI_OM_MODE_SELECT_6                  0x15
-#define SCSI_OM_MODE_SELECT_10                 0x55
-#define SCSI_OM_MODE_SENSE_6                   0x1a
-#define SCSI_OM_MODE_SENSE_10                  0x5a
-#define SCSI_OM_PRE_FETCH                      0x34
-#define SCSI_OM_PREVENT_ALLOW_MEDIUM_REMOVAL   0x1e
-#define SCSI_OM_READ_6                         0x08
-#define SCSI_OM_READ_10                                0x28
-#define SCSI_OM_READ_12                                0xa8
-#define SCSI_OM_READ_BUFFER                    0x3c
-#define SCSI_OM_READ_CAPACITY                  0x25
-#define SCSI_OM_READ_DEFECT_DATA_10            0x37
-#define SCSI_OM_READ_DEFECT_DATA_12            0xb7
-#define SCSI_OM_READ_GENERATION                        0x29
-#define SCSI_OM_READ_LONG                      0x3e
-#define SCSI_OM_READ_UPDATED_BLOCK             0x2d
-#define SCSI_OM_REASSIGN_BLOCKS                        0x07
-#define SCSI_OM_RECEIVE_DIAGNOSTIC_RESULTS     0x1c
-#define SCSI_OM_RELEASE                                0x17
-#define SCSI_OM_REQUEST_SENSE                  0x03
-#define SCSI_OM_RESERVE                                0x16
-#define SCSI_OM_REZERO_UNIT                    0x01
-#define SCSI_OM_SEARCH_DATA_EQUAL_10           0x31
-#define SCSI_OM_SEARCH_DATA_EQUAL_12           0xb1
-#define SCSI_OM_SEARCH_DATA_HIGH_10            0x30
-#define SCSI_OM_SEARCH_DATA_HIGH_12            0xb0
-#define SCSI_OM_SEARCH_DATA_LOW_10             0x32
-#define SCSI_OM_SEARCH_DATA_LOW_12             0xb2
-#define SCSI_OM_SEEK_6                         0x0b
-#define SCSI_OM_SEEK_10                                0x2b
-#define SCSI_OM_SEND_DIAGNOSTIC                        0x1d
-#define SCSI_OM_SET_LIMITS_10                  0x33
-#define SCSI_OM_SET_LIMITS_12                  0xb3
-#define SCSI_OM_START_STOP_UNIT                        0x1b
-#define SCSI_OM_SYNCHRONIZE_CACHE              0x35
-#define SCSI_OM_TEST_UNIT_READY                        0x00
-#define SCSI_OM_UPDATE_BLOCK                   0x3d
-#define SCSI_OM_VERIFY_10                      0x2f
-#define SCSI_OM_VERIFY_12                      0xaf
-#define SCSI_OM_WRITE_6                                0x0a
-#define SCSI_OM_WRITE_10                       0x2a
-#define SCSI_OM_WRITE_12                       0xaa
-#define SCSI_OM_WRITE_AND_VERIFY_10            0x2e
-#define SCSI_OM_WRITE_AND_VERIFY_12            0xae
-#define SCSI_OM_WRITE_BUFFER                   0x3b
-#define SCSI_OM_WRITE_LONG                     0x3f
-
-
-/* Medium changer devices */
-
-#define SCSI_MC_CHANGE_DEFINITION              0x40
-#define SCSI_MC_EXCHANGE_MEDIUM                        0xa6
-#define SCSI_MC_INITIALIZE_ELEMENT_STATUS      0x07
-#define SCSI_MC_INQUIRY                                0x12
-#define SCSI_MC_LOG_SELECT                     0x4c
-#define SCSI_MC_LOG_SENSE                      0x4d
-#define SCSI_MC_MODE_SELECT_6                  0x15
-#define SCSI_MC_MODE_SELECT_10                 0x55
-#define SCSI_MC_MODE_SENSE_6                   0x1a
-#define SCSI_MC_MODE_SENSE_10                  0x5a
-#define SCSI_MC_MOVE_MEDIUM                    0xa5
-#define SCSI_MC_POSITION_TO_ELEMENT            0x2b
-#define SCSI_MC_PREVENT_ALLOW_MEDIUM_REMOVAL   0x1e
-#define SCSI_MC_READ_BUFFER                    0x3c
-#define SCSI_MC_READ_ELEMENT_STATUS            0xb8
-#define SCSI_MC_RECEIVE_DIAGNOSTIC_RESULTS     0x1c
-#define SCSI_MC_RELEASE                                0x17
-#define SCSI_MC_REQUEST_VOLUME_ELEMENT_ADDRESS 0xb5
-#define SCSI_MC_REQUEST_SENSE                  0x03
-#define SCSI_MC_RESERVE                                0x16
-#define SCSI_MC_REZERO_UNIT                    0x01
-#define SCSI_MC_SEND_DIAGNOSTIC                        0x1d
-#define SCSI_MC_SEND_VOLUME_TAG                        0xb6
-#define SCSI_MC_TEST_UNIT_READY                        0x00
-#define SCSI_MC_WRITE_BUFFER                   0x3b
-
-
-/* Communications devices */
-
-#define SCSI_COM_CHANGE_DEFINITION             0x40
-#define SCSI_COM_GET_MESSAGE_6                 0x08
-#define SCSI_COM_GET_MESSAGE_10                        0x28
-#define SCSI_COM_GET_MESSAGE_12                        0xa8
-#define SCSI_COM_INQUIRY                       0x12
-#define SCSI_COM_LOG_SELECT                    0x4c
-#define SCSI_COM_LOG_SENSE                     0x4d
-#define SCSI_COM_MODE_SELECT_6                 0x15
-#define SCSI_COM_MODE_SELECT_10                        0x55
-#define SCSI_COM_MODE_SENSE_6                  0x1a
-#define SCSI_COM_MODE_SENSE_10                 0x5a
-#define SCSI_COM_READ_BUFFER                   0x3c
-#define SCSI_COM_RECEIVE_DIAGNOSTIC_RESULTS    0x1c
-#define SCSI_COM_REQUEST_SENSE                 0x03
-#define SCSI_COM_SEND_DIAGNOSTIC               0x1d
-#define SCSI_COM_SEND_MESSAGE_6                        0x0a
-#define SCSI_COM_SEND_MESSAGE_10               0x2a
-#define SCSI_COM_SEND_MESSAGE_12               0xaa
-#define SCSI_COM_TEST_UNIT_READY               0x00
-#define SCSI_COM_WRITE_BUFFER                  0x3b
-
diff --git a/tools/ioemu/iodev/scsidefs.h b/tools/ioemu/iodev/scsidefs.h
deleted file mode 100644 (file)
index 86239e8..0000000
+++ /dev/null
@@ -1,286 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: scsidefs.h,v 1.4 2002/09/16 16:58:36 bdenney Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//
-// iodev/scsidefs.h
-// $Id: scsidefs.h,v 1.4 2002/09/16 16:58:36 bdenney Exp $
-//
-// This file was copied from ... ?
-//
-
-//***************************************************************************
-//
-// Name:            SCSIDEFS.H
-//
-// Description: SCSI definitions ('C' Language)
-//
-//***************************************************************************
-
-//***************************************************************************
-//                          %%% TARGET STATUS VALUES %%%
-//***************************************************************************
-#define STATUS_GOOD     0x00    // Status Good
-#define STATUS_CHKCOND  0x02    // Check Condition
-#define STATUS_CONDMET  0x04    // Condition Met
-#define STATUS_BUSY     0x08    // Busy
-#define STATUS_INTERM   0x10    // Intermediate
-#define STATUS_INTCDMET 0x14    // Intermediate-condition met
-#define STATUS_RESCONF  0x18    // Reservation conflict
-#define STATUS_COMTERM  0x22    // Command Terminated
-#define STATUS_QFULL    0x28    // Queue full
-
-//***************************************************************************
-//                      %%% SCSI MISCELLANEOUS EQUATES %%%
-//***************************************************************************
-#define MAXLUN          7       // Maximum Logical Unit Id
-#define MAXTARG         7       // Maximum Target Id
-#define MAX_SCSI_LUNS   64      // Maximum Number of SCSI LUNs
-#define MAX_NUM_HA      8       // Maximum Number of SCSI HA's
-
-//\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
-//
-//                          %%% SCSI COMMAND OPCODES %%%
-//
-///\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
-
-//***************************************************************************
-//               %%% Commands for all Device Types %%%
-//***************************************************************************
-#define SCSI_CHANGE_DEF 0x40    // Change Definition (Optional)
-#define SCSI_COMPARE    0x39    // Compare (O)
-#define SCSI_COPY       0x18    // Copy (O)
-#define SCSI_COP_VERIFY 0x3A    // Copy and Verify (O)
-#define SCSI_INQUIRY    0x12    // Inquiry (MANDATORY)
-#define SCSI_LOG_SELECT 0x4C    // Log Select (O)
-#define SCSI_LOG_SENSE  0x4D    // Log Sense (O)
-#define SCSI_MODE_SEL6  0x15    // Mode Select 6-byte (Device Specific)
-#define SCSI_MODE_SEL10 0x55    // Mode Select 10-byte (Device Specific)
-#define SCSI_MODE_SEN6  0x1A    // Mode Sense 6-byte (Device Specific)
-#define SCSI_MODE_SEN10 0x5A    // Mode Sense 10-byte (Device Specific)
-#define SCSI_READ_BUFF  0x3C    // Read Buffer (O)
-#define SCSI_REQ_SENSE  0x03    // Request Sense (MANDATORY)
-#define SCSI_SEND_DIAG  0x1D    // Send Diagnostic (O)
-#define SCSI_TST_U_RDY  0x00    // Test Unit Ready (MANDATORY)
-#define SCSI_WRITE_BUFF 0x3B    // Write Buffer (O)
-
-//***************************************************************************
-//            %%% Commands Unique to Direct Access Devices %%%
-//***************************************************************************
-#define SCSI_COMPARE    0x39    // Compare (O)
-#define SCSI_FORMAT     0x04    // Format Unit (MANDATORY)
-#define SCSI_LCK_UN_CAC 0x36    // Lock Unlock Cache (O)
-#define SCSI_PREFETCH   0x34    // Prefetch (O)
-#define SCSI_MED_REMOVL 0x1E    // Prevent/Allow medium Removal (O)
-#define SCSI_READ6      0x08    // Read 6-byte (MANDATORY)
-#define SCSI_READ10     0x28    // Read 10-byte (MANDATORY)
-#define SCSI_RD_CAPAC   0x25    // Read Capacity (MANDATORY)
-#define SCSI_RD_DEFECT  0x37    // Read Defect Data (O)
-#define SCSI_READ_LONG  0x3E    // Read Long (O)
-#define SCSI_REASS_BLK  0x07    // Reassign Blocks (O)
-#define SCSI_RCV_DIAG   0x1C    // Receive Diagnostic Results (O)
-#define SCSI_RELEASE    0x17    // Release Unit (MANDATORY)
-#define SCSI_REZERO     0x01    // Rezero Unit (O)
-#define SCSI_SRCH_DAT_E 0x31    // Search Data Equal (O)
-#define SCSI_SRCH_DAT_H 0x30    // Search Data High (O)
-#define SCSI_SRCH_DAT_L 0x32    // Search Data Low (O)
-#define SCSI_SEEK6      0x0B    // Seek 6-Byte (O)
-#define SCSI_SEEK10     0x2B    // Seek 10-Byte (O)
-#define SCSI_SEND_DIAG  0x1D    // Send Diagnostics (MANDATORY)
-#define SCSI_SET_LIMIT  0x33    // Set Limits (O)
-#define SCSI_START_STP  0x1B    // Start/Stop Unit (O)
-#define SCSI_SYNC_CACHE 0x35    // Synchronize Cache (O)
-#define SCSI_VERIFY     0x2F    // Verify (O)
-#define SCSI_WRITE6     0x0A    // Write 6-Byte (MANDATORY)
-#define SCSI_WRITE10    0x2A    // Write 10-Byte (MANDATORY)
-#define SCSI_WRT_VERIFY 0x2E    // Write and Verify (O)
-#define SCSI_WRITE_LONG 0x3F    // Write Long (O)
-#define SCSI_WRITE_SAME 0x41    // Write Same (O)
-
-//***************************************************************************
-//          %%% Commands Unique to Sequential Access Devices %%%
-//***************************************************************************
-#define SCSI_ERASE      0x19    // Erase (MANDATORY)
-#define SCSI_LOAD_UN    0x1B    // Load/Unload (O)
-#define SCSI_LOCATE     0x2B    // Locate (O)
-#define SCSI_RD_BLK_LIM 0x05    // Read Block Limits (MANDATORY)
-#define SCSI_READ_POS   0x34    // Read Position (O)
-#define SCSI_READ_REV   0x0F    // Read Reverse (O)
-#define SCSI_REC_BF_DAT 0x14    // Recover Buffer Data (O)
-#define SCSI_RESERVE    0x16    // Reserve Unit (MANDATORY)
-#define SCSI_REWIND     0x01    // Rewind (MANDATORY)
-#define SCSI_SPACE      0x11    // Space (MANDATORY)
-#define SCSI_VERIFY_T   0x13    // Verify (Tape) (O)
-#define SCSI_WRT_FILE   0x10    // Write Filemarks (MANDATORY)
-
-//***************************************************************************
-//                %%% Commands Unique to Printer Devices %%%
-//***************************************************************************
-#define SCSI_PRINT      0x0A    // Print (MANDATORY)
-#define SCSI_SLEW_PNT   0x0B    // Slew and Print (O)
-#define SCSI_STOP_PNT   0x1B    // Stop Print (O)
-#define SCSI_SYNC_BUFF  0x10    // Synchronize Buffer (O)
-
-//***************************************************************************
-//               %%% Commands Unique to Processor Devices %%%
-//***************************************************************************
-#define SCSI_RECEIVE    0x08        // Receive (O)
-#define SCSI_SEND       0x0A        // Send (O)
-
-//***************************************************************************
-//              %%% Commands Unique to Write-Once Devices %%%
-//***************************************************************************
-#define SCSI_MEDIUM_SCN 0x38    // Medium Scan (O)
-#define SCSI_SRCHDATE10 0x31    // Search Data Equal 10-Byte (O)
-#define SCSI_SRCHDATE12 0xB1    // Search Data Equal 12-Byte (O)
-#define SCSI_SRCHDATH10 0x30    // Search Data High 10-Byte (O)
-#define SCSI_SRCHDATH12 0xB0    // Search Data High 12-Byte (O)
-#define SCSI_SRCHDATL10 0x32    // Search Data Low 10-Byte (O)
-#define SCSI_SRCHDATL12 0xB2    // Search Data Low 12-Byte (O)
-#define SCSI_SET_LIM_10 0x33    // Set Limits 10-Byte (O)
-#define SCSI_SET_LIM_12 0xB3    // Set Limits 10-Byte (O)
-#define SCSI_VERIFY10   0x2F    // Verify 10-Byte (O)
-#define SCSI_VERIFY12   0xAF    // Verify 12-Byte (O)
-#define SCSI_WRITE12    0xAA    // Write 12-Byte (O)
-#define SCSI_WRT_VER10  0x2E    // Write and Verify 10-Byte (O)
-#define SCSI_WRT_VER12  0xAE    // Write and Verify 12-Byte (O)
-
-//***************************************************************************
-//                %%% Commands Unique to CD-ROM Devices %%%
-//***************************************************************************
-#define SCSI_PLAYAUD_10 0x45    // Play Audio 10-Byte (O)
-#define SCSI_PLAYAUD_12 0xA5    // Play Audio 12-Byte 12-Byte (O)
-#define SCSI_PLAYAUDMSF 0x47    // Play Audio MSF (O)
-#define SCSI_PLAYA_TKIN 0x48    // Play Audio Track/Index (O)
-#define SCSI_PLYTKREL10 0x49    // Play Track Relative 10-Byte (O)
-#define SCSI_PLYTKREL12 0xA9    // Play Track Relative 12-Byte (O)
-#define SCSI_READCDCAP  0x25    // Read CD-ROM Capacity (MANDATORY)
-#define SCSI_READHEADER 0x44    // Read Header (O)
-#define SCSI_SUBCHANNEL 0x42    // Read Subchannel (O)
-#define SCSI_READ_TOC   0x43    // Read TOC (O)
-
-//***************************************************************************
-//                %%% Commands Unique to Scanner Devices %%%
-//***************************************************************************
-#define SCSI_GETDBSTAT  0x34    // Get Data Buffer Status (O)
-#define SCSI_GETWINDOW  0x25    // Get Window (O)
-#define SCSI_OBJECTPOS  0x31    // Object Postion (O)
-#define SCSI_SCAN       0x1B    // Scan (O)
-#define SCSI_SETWINDOW  0x24    // Set Window (MANDATORY)
-
-//***************************************************************************
-//           %%% Commands Unique to Optical Memory Devices %%%
-//***************************************************************************
-#define SCSI_UpdateBlk  0x3D    // Update Block (O)
-
-//***************************************************************************
-//           %%% Commands Unique to Medium Changer Devices %%%
-//***************************************************************************
-#define SCSI_EXCHMEDIUM 0xA6    // Exchange Medium (O)
-#define SCSI_INITELSTAT 0x07    // Initialize Element Status (O)
-#define SCSI_POSTOELEM  0x2B    // Position to Element (O)
-#define SCSI_REQ_VE_ADD 0xB5    // Request Volume Element Address (O)
-#define SCSI_SENDVOLTAG 0xB6    // Send Volume Tag (O)
-
-//***************************************************************************
-//            %%% Commands Unique to Communication Devices %%%
-//***************************************************************************
-#define SCSI_GET_MSG_6  0x08    // Get Message 6-Byte (MANDATORY)
-#define SCSI_GET_MSG_10 0x28    // Get Message 10-Byte (O)
-#define SCSI_GET_MSG_12 0xA8    // Get Message 12-Byte (O)
-#define SCSI_SND_MSG_6  0x0A    // Send Message 6-Byte (MANDATORY)
-#define SCSI_SND_MSG_10 0x2A    // Send Message 10-Byte (O)
-#define SCSI_SND_MSG_12 0xAA    // Send Message 12-Byte (O)
-
-//\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
-//
-//                    %%% END OF SCSI COMMAND OPCODES %%%
-//
-///\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
-
-//***************************************************************************
-//                      %%% Request Sense Data Format %%%
-//***************************************************************************
-typedef struct {
-
-    BYTE    ErrorCode;          // Error Code (70H or 71H)
-    BYTE    SegmentNum;         // Number of current segment descriptor
-    BYTE    SenseKey;           // Sense Key(See bit definitions too)
-    BYTE    InfoByte0;          // Information MSB
-    BYTE    InfoByte1;          // Information MID
-    BYTE    InfoByte2;          // Information MID
-    BYTE    InfoByte3;          // Information LSB
-    BYTE    AddSenLen;          // Additional Sense Length
-    BYTE    ComSpecInf0;        // Command Specific Information MSB
-    BYTE    ComSpecInf1;        // Command Specific Information MID
-    BYTE    ComSpecInf2;        // Command Specific Information MID
-    BYTE    ComSpecInf3;        // Command Specific Information LSB
-    BYTE    AddSenseCode;       // Additional Sense Code
-    BYTE    AddSenQual;         // Additional Sense Code Qualifier
-    BYTE    FieldRepUCode;      // Field Replaceable Unit Code
-    BYTE    SenKeySpec15;       // Sense Key Specific 15th byte
-    BYTE    SenKeySpec16;       // Sense Key Specific 16th byte
-    BYTE    SenKeySpec17;       // Sense Key Specific 17th byte
-    BYTE    AddSenseBytes;      // Additional Sense Bytes
-
-} SENSE_DATA_FMT;
-
-//***************************************************************************
-//                       %%% REQUEST SENSE ERROR CODE %%%
-//***************************************************************************
-#define SERROR_CURRENT  0x70    // Current Errors
-#define SERROR_DEFERED  0x71    // Deferred Errors
-
-//***************************************************************************
-//                   %%% REQUEST SENSE BIT DEFINITIONS %%%
-//***************************************************************************
-#define SENSE_VALID     0x80    // Byte 0 Bit 7
-#define SENSE_FILEMRK   0x80    // Byte 2 Bit 7
-#define SENSE_EOM       0x40    // Byte 2 Bit 6
-#define SENSE_ILI       0x20    // Byte 2 Bit 5
-
-//***************************************************************************
-//               %%% REQUEST SENSE SENSE KEY DEFINITIONS %%%
-//***************************************************************************
-#define KEY_NOSENSE     0x00    // No Sense
-#define KEY_RECERROR    0x01    // Recovered Error
-#define KEY_NOTREADY    0x02    // Not Ready
-#define KEY_MEDIUMERR   0x03    // Medium Error
-#define KEY_HARDERROR   0x04    // Hardware Error
-#define KEY_ILLGLREQ    0x05    // Illegal Request
-#define KEY_UNITATT     0x06    // Unit Attention
-#define KEY_DATAPROT    0x07    // Data Protect
-#define KEY_BLANKCHK    0x08    // Blank Check
-#define KEY_VENDSPEC    0x09    // Vendor Specific
-#define KEY_COPYABORT   0x0A    // Copy Abort
-#define KEY_EQUAL       0x0C    // Equal (Search)
-#define KEY_VOLOVRFLW   0x0D    // Volume Overflow
-#define KEY_MISCOMP     0x0E    // Miscompare (Search)
-#define KEY_RESERVED    0x0F    // Reserved
-
-//***************************************************************************
-//                %%% PERIPHERAL DEVICE TYPE DEFINITIONS %%%
-//***************************************************************************
-#define DTYPE_DASD      0x00    // Disk Device
-#define DTYPE_SEQD      0x01    // Tape Device
-#define DTYPE_PRNT      0x02    // Printer
-#define DTYPE_PROC      0x03    // Processor
-#define DTYPE_WORM      0x04    // Write-once read-multiple
-#define DTYPE_CROM      0x05    // CD-ROM device
-#define DTYPE_CDROM     0x05    // CD-ROM device
-#define DTYPE_SCAN      0x06    // Scanner device
-#define DTYPE_OPTI      0x07    // Optical memory device
-#define DTYPE_JUKE      0x08    // Medium Changer device
-#define DTYPE_COMM      0x09    // Communications device
-#define DTYPE_RESL      0x0A    // Reserved (low)
-#define DTYPE_RESH      0x1E    // Reserved (high)
-#define DTYPE_UNKNOWN   0x1F    // Unknown or no device type
-
-//***************************************************************************
-//                %%% ANSI APPROVED VERSION DEFINITIONS %%%
-//***************************************************************************
-#define ANSI_MAYBE      0x0     // Device may or may not be ANSI approved stand
-#define ANSI_SCSI1      0x1     // Device complies to ANSI X3.131-1986 (SCSI-1)
-#define ANSI_SCSI2      0x2     // Device complies to SCSI-2
-#define ANSI_RESLO      0x3     // Reserved (low)
-#define ANSI_RESHI      0x7     // Reserved (high)
diff --git a/tools/ioemu/iodev/scsipt.h b/tools/ioemu/iodev/scsipt.h
deleted file mode 100644 (file)
index b3c8508..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: scsipt.h,v 1.4 2002/09/16 16:58:36 bdenney Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//
-// iodev/scsipt.h
-// $Id: scsipt.h,v 1.4 2002/09/16 16:58:36 bdenney Exp $
-//
-// This file was copied from ... ?
-//
-// distilled information from various header files from Microsoft's
-// DDK for Windows NT 4.0
-//
-
-#ifndef _SCSIPT_H_INC
-#define _SCSIPT_H_INC
-
-#include <windows.h>
-
-typedef struct {
-  USHORT Length;
-  UCHAR  ScsiStatus;
-  UCHAR  PathId;
-  UCHAR  TargetId;
-  UCHAR  Lun;
-  UCHAR  CdbLength;
-  UCHAR  SenseInfoLength;
-  UCHAR  DataIn;
-  ULONG  DataTransferLength;
-  ULONG  TimeOutValue;
-  ULONG  DataBufferOffset;
-  ULONG  SenseInfoOffset;
-  UCHAR  Cdb[16];
-} SCSI_PASS_THROUGH, *PSCSI_PASS_THROUGH;
-
-
-typedef struct {
-  USHORT Length;
-  UCHAR  ScsiStatus;
-  UCHAR  PathId;
-  UCHAR  TargetId;
-  UCHAR  Lun;
-  UCHAR  CdbLength;
-  UCHAR  SenseInfoLength;
-  UCHAR  DataIn;
-  ULONG  DataTransferLength;
-  ULONG  TimeOutValue;
-  PVOID  DataBuffer;
-  ULONG  SenseInfoOffset;
-  UCHAR  Cdb[16];
-} SCSI_PASS_THROUGH_DIRECT, *PSCSI_PASS_THROUGH_DIRECT;
-
-
-typedef struct {
-  SCSI_PASS_THROUGH spt;
-  ULONG Filler;
-  UCHAR ucSenseBuf[32];
-  UCHAR ucDataBuf[512];
-} SCSI_PASS_THROUGH_WITH_BUFFERS, *PSCSI_PASS_THROUGH_WITH_BUFFERS;
-
-
-typedef struct {
-  SCSI_PASS_THROUGH_DIRECT spt;
-  ULONG Filler;
-  UCHAR ucSenseBuf[32];
-} SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, *PSCSI_PASS_THROUGH_DIRECT_WITH_BUFFER;
-
-
-
-typedef struct {
-  UCHAR NumberOfLogicalUnits;
-  UCHAR InitiatorBusId;
-  ULONG InquiryDataOffset;
-} SCSI_BUS_DATA, *PSCSI_BUS_DATA;
-
-
-typedef struct {
-  UCHAR NumberOfBusses;
-  SCSI_BUS_DATA BusData[1];
-} SCSI_ADAPTER_BUS_INFO, *PSCSI_ADAPTER_BUS_INFO;
-
-
-typedef struct {
-  UCHAR PathId;
-  UCHAR TargetId;
-  UCHAR Lun;
-  BOOLEAN DeviceClaimed;
-  ULONG InquiryDataLength;
-  ULONG NextInquiryDataOffset;
-  UCHAR InquiryData[1];
-} SCSI_INQUIRY_DATA, *PSCSI_INQUIRY_DATA;
-
-
-typedef struct {
-  ULONG Length;
-  UCHAR PortNumber;
-  UCHAR PathId;
-  UCHAR TargetId;
-  UCHAR Lun;
-} SCSI_ADDRESS, *PSCSI_ADDRESS;
-
-
-/*
- * method codes
- */
-#define  METHOD_BUFFERED     0
-#define  METHOD_IN_DIRECT    1
-#define  METHOD_OUT_DIRECT   2
-#define  METHOD_NEITHER      3
-
-/*
- * file access values
- */
-#define  FILE_ANY_ACCESS      0
-#define  FILE_READ_ACCESS     (0x0001)
-#define  FILE_WRITE_ACCESS    (0x0002)
-
-
-#define IOCTL_SCSI_BASE    0x00000004
-
-/*
- * constants for DataIn member of SCSI_PASS_THROUGH* structures
- */
-#define  SCSI_IOCTL_DATA_OUT          0
-#define  SCSI_IOCTL_DATA_IN           1
-#define  SCSI_IOCTL_DATA_UNSPECIFIED  2
-
-/*
- * Standard IOCTL define
- */
-#define CTL_CODE( DevType, Function, Method, Access ) (                 \
-    ((DevType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
-)
-
-#define IOCTL_SCSI_PASS_THROUGH         CTL_CODE( IOCTL_SCSI_BASE, 0x0401, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS )
-#define IOCTL_SCSI_MINIPORT             CTL_CODE( IOCTL_SCSI_BASE, 0x0402, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS )
-#define IOCTL_SCSI_GET_INQUIRY_DATA     CTL_CODE( IOCTL_SCSI_BASE, 0x0403, METHOD_BUFFERED, FILE_ANY_ACCESS)
-#define IOCTL_SCSI_GET_CAPABILITIES     CTL_CODE( IOCTL_SCSI_BASE, 0x0404, METHOD_BUFFERED, FILE_ANY_ACCESS)
-#define IOCTL_SCSI_PASS_THROUGH_DIRECT  CTL_CODE( IOCTL_SCSI_BASE, 0x0405, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS )
-#define IOCTL_SCSI_GET_ADDRESS          CTL_CODE( IOCTL_SCSI_BASE, 0x0406, METHOD_BUFFERED, FILE_ANY_ACCESS )
-
-
-
-#endif
diff --git a/tools/ioemu/iodev/serial.cc b/tools/ioemu/iodev/serial.cc
deleted file mode 100644 (file)
index 02deec3..0000000
+++ /dev/null
@@ -1,1001 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: serial.cc,v 1.41 2003/11/09 00:14:43 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-// Peter Grehan (grehan@iprg.nokia.com) coded the original version of this
-// serial emulation. He implemented a single 8250, and allow terminal
-// input/output to stdout on FreeBSD.
-// The current version emulates a single 16550A with FIFO. Terminal
-// input/output now works on some more platforms.
-
-
-// Define BX_PLUGGABLE in files that can be compiled into plugins.  For
-// platforms that require a special tag on exported symbols, BX_PLUGGABLE 
-// is used to know when we are exporting symbols and when we are importing.
-#define BX_PLUGGABLE
-
-#include "bochs.h"
-
-#define LOG_THIS theSerialDevice->
-
-#if USE_RAW_SERIAL
-#include <signal.h>
-#endif
-
-#ifdef WIN32
-#ifndef __MINGW32__
-// +++
-//#include <winsock2.h>
-#include <winsock.h>
-#endif
-#endif
-
-#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__linux__) || defined(__GNU__) || defined(__APPLE__)
-#define SERIAL_ENABLE
-#endif
-
-#ifdef SERIAL_ENABLE
-extern "C" {
-#include <termios.h>
-};
-#endif
-
-#ifdef SERIAL_ENABLE
-static struct termios term_orig, term_new;
-#endif
-
-static int tty_id;
-
-bx_serial_c *theSerialDevice = NULL;
-
-  int
-libserial_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
-{
-  theSerialDevice = new bx_serial_c ();
-  bx_devices.pluginSerialDevice = theSerialDevice;
-  BX_REGISTER_DEVICE_DEVMODEL(plugin, type, theSerialDevice, BX_PLUGIN_SERIAL);
-  return(0); // Success
-}
-
-  void
-libserial_LTX_plugin_fini(void)
-{
-}
-
-bx_serial_c::bx_serial_c(void)
-{
-  put("SER");
-  settype(SERLOG);
-  tty_id = -1;
-  for (int i=0; i<BX_SERIAL_MAXDEV; i++) {
-    s[i].tx_timer_index = BX_NULL_TIMER_HANDLE;
-    s[i].rx_timer_index = BX_NULL_TIMER_HANDLE;
-    s[i].fifo_timer_index = BX_NULL_TIMER_HANDLE;
-  }
-}
-
-bx_serial_c::~bx_serial_c(void)
-{
-#ifdef SERIAL_ENABLE
-  if ((bx_options.com[0].Oenabled->get ()) && (tty_id >= 0))
-    tcsetattr(tty_id, TCSAFLUSH, &term_orig);
-#endif
-  // nothing for now
-}
-
-
-  void
-bx_serial_c::init(void)
-{
-  Bit16u ports[BX_SERIAL_MAXDEV] = {0x03f8, 0x02f8, 0x03e8, 0x02e8};
-  char name[16];
-
-  if (!bx_options.com[0].Oenabled->get ())
-    return;
-
-#ifdef SERIAL_ENABLE
-  if (strlen(bx_options.com[0].Odev->getptr ()) > 0) {
-    tty_id = open(bx_options.com[0].Odev->getptr (), O_RDWR|O_NONBLOCK,600);
-    if (tty_id < 0)
-      BX_PANIC(("open of %s (%s) failed\n",
-                "com1", bx_options.com[0].Odev->getptr ()));
-    BX_DEBUG(("tty_id: %d",tty_id));
-    tcgetattr(tty_id, &term_orig);
-    bcopy((caddr_t) &term_orig, (caddr_t) &term_new, sizeof(struct termios));
-    cfmakeraw(&term_new);
-    term_new.c_oflag |= OPOST | ONLCR;  // Enable NL to CR-NL translation
-#ifndef TRUE_CTLC
-    // ctl-C will exit Bochs, or trap to the debugger
-    term_new.c_iflag &= ~IGNBRK;
-    term_new.c_iflag |= BRKINT;
-    term_new.c_lflag |= ISIG;
-#else
-    // ctl-C will be delivered to the serial port
-    term_new.c_iflag |= IGNBRK;
-    term_new.c_iflag &= ~BRKINT;
-#endif    /* !def TRUE_CTLC */
-    term_new.c_iflag = 0;
-    term_new.c_oflag = 0;
-    term_new.c_cflag = CS8|CREAD|CLOCAL;
-    term_new.c_lflag = 0;
-    term_new.c_cc[VMIN] = 1;
-    term_new.c_cc[VTIME] = 0;
-    //term_new.c_iflag |= IXOFF;
-    tcsetattr(tty_id, TCSAFLUSH, &term_new);
-  }
-#endif   /* def SERIAL_ENABLE */
-  // nothing for now
-#if USE_RAW_SERIAL
-  this->raw = new serial_raw("/dev/cua0", SIGUSR1);
-#endif // USE_RAW_SERIAL
-
-  /*
-   * Put the UART registers into their RESET state
-   */
-  for (unsigned i=0; i<BX_N_SERIAL_PORTS; i++) {
-    if (bx_options.com[i].Oenabled->get ()) {
-      sprintf(name, "Serial Port %d", i + 1);
-      /* serial interrupt */
-      BX_SER_THIS s[i].IRQ = 4 - (i & 1);
-      if (i < 2) {
-        DEV_register_irq(BX_SER_THIS s[i].IRQ, name);
-      }
-      /* internal state */
-      BX_SER_THIS s[i].ls_ipending = 0;
-      BX_SER_THIS s[i].ms_ipending = 0;
-      BX_SER_THIS s[i].rx_ipending = 0;
-      BX_SER_THIS s[i].fifo_ipending = 0;
-      BX_SER_THIS s[i].ls_interrupt = 0;
-      BX_SER_THIS s[i].ms_interrupt = 0;
-      BX_SER_THIS s[i].rx_interrupt = 0;
-      BX_SER_THIS s[i].tx_interrupt = 0;
-      BX_SER_THIS s[i].fifo_interrupt = 0;
-
-      if (BX_SER_THIS s[i].tx_timer_index == BX_NULL_TIMER_HANDLE) {
-        BX_SER_THIS s[i].tx_timer_index =
-          bx_pc_system.register_timer(this, tx_timer_handler, 0,
-                                      0,0, "serial.tx"); // one-shot, inactive
-      }
-
-      if (BX_SER_THIS s[i].rx_timer_index == BX_NULL_TIMER_HANDLE) {
-        BX_SER_THIS s[i].rx_timer_index =
-          bx_pc_system.register_timer(this, rx_timer_handler, 0,
-                                      0,0, "serial.rx"); // one-shot, inactive
-      }
-      if (BX_SER_THIS s[i].fifo_timer_index == BX_NULL_TIMER_HANDLE) {
-        BX_SER_THIS s[i].fifo_timer_index =
-          bx_pc_system.register_timer(this, fifo_timer_handler, 0,
-                                      0,0, "serial.fifo"); // one-shot, inactive
-      }
-      BX_SER_THIS s[i].rx_pollstate = BX_SER_RXIDLE;
-
-      /* int enable: b0000 0000 */
-      BX_SER_THIS s[i].int_enable.rxdata_enable = 0;
-      BX_SER_THIS s[i].int_enable.txhold_enable = 0;
-      BX_SER_THIS s[i].int_enable.rxlstat_enable = 0;
-      BX_SER_THIS s[i].int_enable.modstat_enable = 0;
-
-      /* int ID: b0000 0001 */
-      BX_SER_THIS s[i].int_ident.ipending = 1;
-      BX_SER_THIS s[i].int_ident.int_ID = 0;
-
-      /* FIFO control: b0000 0000 */
-      BX_SER_THIS s[i].fifo_cntl.enable = 0;
-      BX_SER_THIS s[i].fifo_cntl.rxtrigger = 0;
-      BX_SER_THIS s[i].rx_fifo_end = 0;
-      BX_SER_THIS s[i].tx_fifo_end = 0;
-
-      /* Line Control reg: b0000 0000 */
-      BX_SER_THIS s[i].line_cntl.wordlen_sel = 0;
-      BX_SER_THIS s[i].line_cntl.stopbits = 0;
-      BX_SER_THIS s[i].line_cntl.parity_enable = 0;
-      BX_SER_THIS s[i].line_cntl.evenparity_sel = 0;
-      BX_SER_THIS s[i].line_cntl.stick_parity = 0;
-      BX_SER_THIS s[i].line_cntl.break_cntl = 0;
-      BX_SER_THIS s[i].line_cntl.dlab = 0;
-
-      /* Modem Control reg: b0000 0000 */
-      BX_SER_THIS s[i].modem_cntl.dtr = 0;
-      BX_SER_THIS s[i].modem_cntl.rts = 0;
-      BX_SER_THIS s[i].modem_cntl.out1 = 0;
-      BX_SER_THIS s[i].modem_cntl.out2 = 0;
-      BX_SER_THIS s[i].modem_cntl.local_loopback = 0;
-
-      /* Line Status register: b0110 0000 */
-      BX_SER_THIS s[i].line_status.rxdata_ready = 0;
-      BX_SER_THIS s[i].line_status.overrun_error = 0;
-      BX_SER_THIS s[i].line_status.parity_error = 0;
-      BX_SER_THIS s[i].line_status.framing_error = 0;
-      BX_SER_THIS s[i].line_status.break_int = 0;
-      BX_SER_THIS s[i].line_status.thr_empty = 1;
-      BX_SER_THIS s[i].line_status.tsr_empty = 1;
-      BX_SER_THIS s[i].line_status.fifo_error = 0;
-
-      /* Modem Status register: bXXXX 0000 */
-      BX_SER_THIS s[i].modem_status.delta_cts = 0;
-      BX_SER_THIS s[i].modem_status.delta_dsr = 0;
-      BX_SER_THIS s[i].modem_status.ri_trailedge = 0;
-      BX_SER_THIS s[i].modem_status.delta_dcd = 0;
-      BX_SER_THIS s[i].modem_status.cts = 0;
-      BX_SER_THIS s[i].modem_status.dsr = 0;
-      BX_SER_THIS s[i].modem_status.ri = 0;
-      BX_SER_THIS s[i].modem_status.dcd = 0;
-
-      BX_SER_THIS s[i].scratch = 0;      /* scratch register */
-      BX_SER_THIS s[i].divisor_lsb = 1;  /* divisor-lsb register */
-      BX_SER_THIS s[i].divisor_msb = 0;  /* divisor-msb register */
-
-      BX_SER_THIS s[i].baudrate = 115200;
-
-      for (unsigned addr=ports[i]; addr<(unsigned)(ports[i]+8); addr++) {
-        BX_DEBUG(("register read/write: 0x%04x",addr));
-        DEV_register_ioread_handler(this, read_handler, addr, name, 1);
-        DEV_register_iowrite_handler(this, write_handler, addr, name, 1);
-      }
-      BX_INFO(("com%d at 0x%04x irq %d", i+1, ports[i], BX_SER_THIS s[i].IRQ));
-    }
-  }
-}
-
-  void
-bx_serial_c::reset(unsigned type)
-{
-}
-
-  void
-bx_serial_c::lower_interrupt(Bit8u port)
-{
-  /* If there are no more ints pending, clear the irq */
-  if ((BX_SER_THIS s[port].rx_interrupt == 0) &&
-      (BX_SER_THIS s[port].tx_interrupt == 0) &&
-      (BX_SER_THIS s[port].ls_interrupt == 0) &&
-      (BX_SER_THIS s[port].ms_interrupt == 0) &&
-      (BX_SER_THIS s[port].fifo_interrupt == 0)) {
-    DEV_pic_lower_irq(BX_SER_THIS s[port].IRQ);
-  }
-}
-
-  void
-bx_serial_c::raise_interrupt(Bit8u port, int type)
-{
-  bx_bool gen_int = 0;
-
-  switch (type) {
-    case BX_SER_INT_IER: /* IER has changed */
-      gen_int = 1;
-      break;
-    case BX_SER_INT_RXDATA:
-      if (BX_SER_THIS s[port].int_enable.rxdata_enable) {
-        BX_SER_THIS s[port].rx_interrupt = 1;
-        gen_int = 1;
-      } else {
-        BX_SER_THIS s[port].rx_ipending = 1;
-      }
-      break;
-    case BX_SER_INT_TXHOLD:
-      if (BX_SER_THIS s[port].int_enable.txhold_enable) {
-        BX_SER_THIS s[port].tx_interrupt = 1;
-        gen_int = 1;
-      }
-      break;
-    case BX_SER_INT_RXLSTAT:
-      if (BX_SER_THIS s[port].int_enable.rxlstat_enable) {
-        BX_SER_THIS s[port].ls_interrupt = 1;
-        gen_int = 1;
-      } else {
-        BX_SER_THIS s[port].ls_ipending = 1;
-      }
-      break;
-    case BX_SER_INT_MODSTAT:
-      if ((BX_SER_THIS s[port].ms_ipending == 1) &&
-          (BX_SER_THIS s[port].int_enable.modstat_enable == 1)) {
-        BX_SER_THIS s[port].ms_interrupt = 1;
-        BX_SER_THIS s[port].ms_ipending = 0;
-        gen_int = 1;
-      }
-      break;
-    case BX_SER_INT_FIFO:
-      if (BX_SER_THIS s[port].int_enable.rxdata_enable) {
-        BX_SER_THIS s[port].fifo_interrupt = 1;
-        gen_int = 1;
-      } else {
-        BX_SER_THIS s[port].fifo_ipending = 1;
-      }
-      break;
-  }
-  if (gen_int && BX_SER_THIS s[port].modem_cntl.out2) {
-    DEV_pic_raise_irq(BX_SER_THIS s[port].IRQ);
-  }
-}
-
-  // static IO port read callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-  Bit32u
-bx_serial_c::read_handler(void *this_ptr, Bit32u address, unsigned io_len)
-{
-#if !BX_USE_SER_SMF
-  bx_serial_c *class_ptr = (bx_serial_c *) this_ptr;
-
-  return( class_ptr->read(address, io_len) );
-}
-
-
-  Bit32u
-bx_serial_c::read(Bit32u address, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif  // !BX_USE_SER_SMF
-  //UNUSED(address);
-  Bit8u val;
-
-  /* SERIAL PORT 1 */
-
-  BX_DEBUG(("register read from address 0x%04x - ", (unsigned) address));
-
-  switch (address) {
-    case 0x03F8: /* receive buffer, or divisor latch LSB if DLAB set */
-      if (BX_SER_THIS s[0].line_cntl.dlab) {
-        val = BX_SER_THIS s[0].divisor_lsb;
-      } else {
-        if (BX_SER_THIS s[0].fifo_cntl.enable) {
-          val = BX_SER_THIS s[0].rx_fifo[0];
-          if (BX_SER_THIS s[0].rx_fifo_end > 0) {
-            memcpy(&BX_SER_THIS s[0].rx_fifo[0], &BX_SER_THIS s[0].rx_fifo[1], 15);
-            BX_SER_THIS s[0].rx_fifo_end--;
-          }
-          if (BX_SER_THIS s[0].rx_fifo_end == 0) {
-            BX_SER_THIS s[0].line_status.rxdata_ready = 0;
-            BX_SER_THIS s[0].rx_interrupt = 0;
-            BX_SER_THIS s[0].rx_ipending = 0;
-            BX_SER_THIS s[0].fifo_interrupt = 0;
-            BX_SER_THIS s[0].fifo_ipending = 0;
-            lower_interrupt(0);
-          }
-        } else {
-          val = BX_SER_THIS s[0].rxbuffer;
-          BX_SER_THIS s[0].line_status.rxdata_ready = 0;
-          BX_SER_THIS s[0].rx_interrupt = 0;
-          BX_SER_THIS s[0].rx_ipending = 0;
-          lower_interrupt(0);
-        }
-      }
-      break;
-
-    case 0x03F9: /* interrupt enable register, or div. latch MSB */
-      if (BX_SER_THIS s[0].line_cntl.dlab) {
-        val = BX_SER_THIS s[0].divisor_msb;
-      } else {
-        val = BX_SER_THIS s[0].int_enable.rxdata_enable |
-              (BX_SER_THIS s[0].int_enable.txhold_enable  << 1) |
-              (BX_SER_THIS s[0].int_enable.rxlstat_enable << 2) |
-              (BX_SER_THIS s[0].int_enable.modstat_enable << 3);
-      }
-      break;
-
-    case 0x03FA: /* interrupt ID register */
-      /*
-       * Set the interrupt ID based on interrupt source
-       */
-      if (BX_SER_THIS s[0].ls_interrupt) {
-        BX_SER_THIS s[0].int_ident.int_ID = 0x3;
-        BX_SER_THIS s[0].int_ident.ipending = 0;
-      } else if (BX_SER_THIS s[0].fifo_interrupt) {
-        BX_SER_THIS s[0].int_ident.int_ID = 0x6;
-        BX_SER_THIS s[0].int_ident.ipending = 0;
-      } else if (BX_SER_THIS s[0].rx_interrupt) {
-        BX_SER_THIS s[0].int_ident.int_ID = 0x2;
-        BX_SER_THIS s[0].int_ident.ipending = 0;
-      } else if (BX_SER_THIS s[0].tx_interrupt) {
-        BX_SER_THIS s[0].int_ident.int_ID = 0x1;
-        BX_SER_THIS s[0].int_ident.ipending = 0;
-      } else if (BX_SER_THIS s[0].ms_interrupt) {
-        BX_SER_THIS s[0].int_ident.int_ID = 0x0;
-        BX_SER_THIS s[0].int_ident.ipending = 0;
-      } else {
-        BX_SER_THIS s[0].int_ident.int_ID = 0x0;
-        BX_SER_THIS s[0].int_ident.ipending = 1;
-      }
-      BX_SER_THIS s[0].tx_interrupt = 0;
-      lower_interrupt(0);
-
-      val = BX_SER_THIS s[0].int_ident.ipending  |
-            (BX_SER_THIS s[0].int_ident.int_ID << 1) |
-            (BX_SER_THIS s[0].fifo_cntl.enable ? 0xc0 : 0x00);
-      break;
-
-    case 0x03FB: /* Line control register */
-      val = BX_SER_THIS s[0].line_cntl.wordlen_sel       |
-       (BX_SER_THIS s[0].line_cntl.stopbits       << 2) |
-       (BX_SER_THIS s[0].line_cntl.parity_enable  << 3) |
-       (BX_SER_THIS s[0].line_cntl.evenparity_sel << 4) |
-       (BX_SER_THIS s[0].line_cntl.stick_parity   << 5) |
-       (BX_SER_THIS s[0].line_cntl.break_cntl     << 6) |
-       (BX_SER_THIS s[0].line_cntl.dlab           << 7);
-      break;
-
-    case 0x03FC: /* MODEM control register */
-      val = BX_SER_THIS s[0].modem_cntl.dtr |
-            (BX_SER_THIS s[0].modem_cntl.rts << 1) |
-            (BX_SER_THIS s[0].modem_cntl.out1 << 2) |
-            (BX_SER_THIS s[0].modem_cntl.out2 << 3) |
-            (BX_SER_THIS s[0].modem_cntl.local_loopback << 4);
-      break;
-
-    case 0x03FD: /* Line status register */
-      val = BX_SER_THIS s[0].line_status.rxdata_ready     |
-       (BX_SER_THIS s[0].line_status.overrun_error  << 1) |
-       (BX_SER_THIS s[0].line_status.parity_error   << 2) |
-       (BX_SER_THIS s[0].line_status.framing_error  << 3) |
-       (BX_SER_THIS s[0].line_status.break_int      << 4) |
-       (BX_SER_THIS s[0].line_status.thr_empty      << 5) |
-       (BX_SER_THIS s[0].line_status.tsr_empty      << 6) |
-       (BX_SER_THIS s[0].line_status.fifo_error     << 7);
-      BX_SER_THIS s[0].line_status.overrun_error = 0;
-      BX_SER_THIS s[0].line_status.break_int = 0;
-      BX_SER_THIS s[0].ls_interrupt = 0;
-      BX_SER_THIS s[0].ls_ipending = 0;
-      lower_interrupt(0);
-      break;
-
-    case 0x03FE: /* MODEM status register */
-      val = BX_SER_THIS s[0].modem_status.delta_cts       |
-       (BX_SER_THIS s[0].modem_status.delta_dsr    << 1) |
-       (BX_SER_THIS s[0].modem_status.ri_trailedge << 2) |
-       (BX_SER_THIS s[0].modem_status.delta_dcd    << 3) |
-       (BX_SER_THIS s[0].modem_status.cts          << 4) |
-       (BX_SER_THIS s[0].modem_status.dsr          << 5) |
-       (BX_SER_THIS s[0].modem_status.ri           << 6) |
-       (BX_SER_THIS s[0].modem_status.dcd          << 7);
-      BX_SER_THIS s[0].modem_status.delta_cts = 0;
-      BX_SER_THIS s[0].modem_status.delta_dsr = 0;
-      BX_SER_THIS s[0].modem_status.ri_trailedge = 0;
-      BX_SER_THIS s[0].modem_status.delta_dcd = 0;
-      BX_SER_THIS s[0].ms_interrupt = 0;
-      BX_SER_THIS s[0].ms_ipending = 0;
-      lower_interrupt(0);
-      break;
-
-    case 0x03FF: /* scratch register */
-      val = BX_SER_THIS s[0].scratch;
-      break;
-
-    default:
-      val = 0; // keep compiler happy
-      BX_PANIC(("unsupported io read from address=0x%04x!",
-        (unsigned) address));
-      break;
-  }
-
-  BX_DEBUG(("val =  0x%02x", (unsigned) val));
-
-  return(val);
-}
-
-
-  // static IO port write callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-void
-bx_serial_c::write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len)
-{
-#if !BX_USE_SER_SMF
-  bx_serial_c *class_ptr = (bx_serial_c *) this_ptr;
-
-  class_ptr->write(address, value, io_len);
-}
-
-void
-bx_serial_c::write(Bit32u address, Bit32u value, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif  // !BX_USE_SER_SMF
-  bx_bool prev_cts, prev_dsr, prev_ri, prev_dcd;
-  bx_bool new_rx_ien, new_tx_ien, new_ls_ien, new_ms_ien;
-  bx_bool gen_int = 0;
-
-  /* SERIAL PORT 1 */
-
-  BX_DEBUG(("write to address: 0x%04x = 0x%02x",
-             (unsigned) address, (unsigned) value));
-
-  switch (address) {
-    case 0x03F8: /* transmit buffer, or divisor latch LSB if DLAB set */
-      if (BX_SER_THIS s[0].line_cntl.dlab) {
-       BX_SER_THIS s[0].divisor_lsb = value;
-
-        if ((value != 0) || (BX_SER_THIS s[0].divisor_msb != 0)) {
-         BX_SER_THIS s[0].baudrate = (int) (BX_PC_CLOCK_XTL /
-                         (16 * ((BX_SER_THIS s[0].divisor_msb << 8) |
-                                BX_SER_THIS s[0].divisor_lsb)));
-#if USE_RAW_SERIAL
-         BX_SER_THIS raw->set_baudrate(BX_SER_THIS s[0].baudrate);
-#endif // USE_RAW_SERIAL
-       }
-      } else {
-        Bit8u bitmask = 0xff >> (3 - BX_SER_THIS s[0].line_cntl.wordlen_sel);
-        if (BX_SER_THIS s[0].line_status.thr_empty) {
-          if (BX_SER_THIS s[0].fifo_cntl.enable) {
-            BX_SER_THIS s[0].tx_fifo[BX_SER_THIS s[0].tx_fifo_end++] = value & bitmask;
-          } else {
-            BX_SER_THIS s[0].thrbuffer = value & bitmask;
-          }
-          BX_SER_THIS s[0].line_status.thr_empty = 0;
-          if (BX_SER_THIS s[0].line_status.tsr_empty) {
-            if (BX_SER_THIS s[0].fifo_cntl.enable) {
-              BX_SER_THIS s[0].tsrbuffer = BX_SER_THIS s[0].tx_fifo[0];
-              memcpy(&BX_SER_THIS s[0].tx_fifo[0], &BX_SER_THIS s[0].tx_fifo[1], 15);
-              BX_SER_THIS s[0].line_status.thr_empty = (--BX_SER_THIS s[0].tx_fifo_end == 0);
-            } else {
-              BX_SER_THIS s[0].tsrbuffer = BX_SER_THIS s[0].thrbuffer;
-              BX_SER_THIS s[0].line_status.thr_empty = 1;
-            }
-            BX_SER_THIS s[0].line_status.tsr_empty = 0;
-            raise_interrupt(0, BX_SER_INT_TXHOLD);
-            bx_pc_system.activate_timer(BX_SER_THIS s[0].tx_timer_index,
-                                        (int) (1000000.0 / BX_SER_THIS s[0].baudrate *
-                                        (BX_SER_THIS s[0].line_cntl.wordlen_sel + 5)),
-                                        0); /* not continuous */
-          } else {
-            BX_SER_THIS s[0].tx_interrupt = 0;
-            lower_interrupt(0);
-          }
-        } else {
-          if (BX_SER_THIS s[0].fifo_cntl.enable) {
-            if (BX_SER_THIS s[0].tx_fifo_end < 16) {
-              BX_SER_THIS s[0].tx_fifo[BX_SER_THIS s[0].tx_fifo_end++] = value & bitmask;
-            } else {
-              BX_ERROR(("com1: transmit FIFO overflow"));
-            }
-          } else {
-            BX_ERROR(("write to tx hold register when not empty"));
-          }
-        }
-      }
-      break;
-
-    case 0x03F9: /* interrupt enable register, or div. latch MSB */
-      if (BX_SER_THIS s[0].line_cntl.dlab) {
-       BX_SER_THIS s[0].divisor_msb = value;
-
-        if ((value != 0) || (BX_SER_THIS s[0].divisor_lsb != 0)) {
-         BX_SER_THIS s[0].baudrate = (int) (BX_PC_CLOCK_XTL /
-                      (16 * ((BX_SER_THIS s[0].divisor_msb << 8) |
-                             BX_SER_THIS s[0].divisor_lsb)));
-#if USE_RAW_SERIAL
-         BX_SER_THIS raw->set_baudrate(BX_SER_THIS s[0].baudrate);
-#endif // USE_RAW_SERIAL
-       }
-      } else {
-       new_rx_ien = value & 0x01;
-       new_tx_ien = (value & 0x02) >> 1;
-       new_ls_ien = (value & 0x04) >> 2;
-       new_ms_ien = (value & 0x08) >> 3;
-        if (new_ms_ien != BX_SER_THIS s[0].int_enable.modstat_enable) {
-          BX_SER_THIS s[0].int_enable.modstat_enable  = new_ms_ien;
-          if (BX_SER_THIS s[0].int_enable.modstat_enable == 1) {
-            if (BX_SER_THIS s[0].ms_ipending == 1) {
-              BX_SER_THIS s[0].ms_interrupt = 1;
-              BX_SER_THIS s[0].ms_ipending = 0;
-              gen_int = 1;
-            }
-          } else {
-            if (BX_SER_THIS s[0].ms_interrupt == 1) {
-              BX_SER_THIS s[0].ms_interrupt = 0;
-              BX_SER_THIS s[0].ms_ipending = 1;
-              lower_interrupt(0);
-            }
-          }
-        }
-        if (new_tx_ien != BX_SER_THIS s[0].int_enable.txhold_enable) {
-          BX_SER_THIS s[0].int_enable.txhold_enable  = new_tx_ien;
-          if (BX_SER_THIS s[0].int_enable.txhold_enable == 1) {
-            BX_SER_THIS s[0].tx_interrupt = BX_SER_THIS s[0].line_status.thr_empty;
-            if (BX_SER_THIS s[0].tx_interrupt) gen_int = 1;
-          } else {
-            BX_SER_THIS s[0].tx_interrupt = 0;
-            lower_interrupt(0);
-          }
-        }
-        if (new_rx_ien != BX_SER_THIS s[0].int_enable.rxdata_enable) {
-          BX_SER_THIS s[0].int_enable.rxdata_enable  = new_rx_ien;
-          if (BX_SER_THIS s[0].int_enable.rxdata_enable == 1) {
-            if (BX_SER_THIS s[0].fifo_ipending == 1) {
-              BX_SER_THIS s[0].fifo_interrupt = 1;
-              BX_SER_THIS s[0].fifo_ipending = 0;
-              gen_int = 1;
-            }
-            if (BX_SER_THIS s[0].rx_ipending == 1) {
-              BX_SER_THIS s[0].rx_interrupt = 1;
-              BX_SER_THIS s[0].rx_ipending = 0;
-              gen_int = 1;
-            }
-          } else {
-            if (BX_SER_THIS s[0].rx_interrupt == 1) {
-              BX_SER_THIS s[0].rx_interrupt = 0;
-              BX_SER_THIS s[0].rx_ipending = 1;
-              lower_interrupt(0);
-            }
-            if (BX_SER_THIS s[0].fifo_interrupt == 1) {
-              BX_SER_THIS s[0].fifo_interrupt = 0;
-              BX_SER_THIS s[0].fifo_ipending = 1;
-              lower_interrupt(0);
-            }
-          }
-        }
-        if (new_ls_ien != BX_SER_THIS s[0].int_enable.rxlstat_enable) {
-          BX_SER_THIS s[0].int_enable.rxlstat_enable  = new_ls_ien;
-          if (BX_SER_THIS s[0].int_enable.rxlstat_enable == 1) {
-            if (BX_SER_THIS s[0].ls_ipending == 1) {
-              BX_SER_THIS s[0].ls_interrupt = 1;
-              BX_SER_THIS s[0].ls_ipending = 0;
-              gen_int = 1;
-            }
-          } else {
-            if (BX_SER_THIS s[0].ls_interrupt == 1) {
-              BX_SER_THIS s[0].ls_interrupt = 0;
-              BX_SER_THIS s[0].ls_ipending = 1;
-              lower_interrupt(0);
-            }
-          }
-        }
-        if (gen_int) raise_interrupt(0, BX_SER_INT_IER);
-      }
-      break;
-
-    case 0x03FA: /* FIFO control register */
-      if (!BX_SER_THIS s[0].fifo_cntl.enable && (value & 0x01)) {
-        BX_INFO(("FIFO enabled"));
-        BX_SER_THIS s[0].rx_fifo_end = 0;
-        BX_SER_THIS s[0].tx_fifo_end = 0;
-      }
-      BX_SER_THIS s[0].fifo_cntl.enable = value & 0x01;
-      if (value & 0x02) {
-        BX_SER_THIS s[0].rx_fifo_end = 0;
-      }
-      if (value & 0x04) {
-        BX_SER_THIS s[0].tx_fifo_end = 0;
-      }
-      BX_SER_THIS s[0].fifo_cntl.rxtrigger = (value & 0xc0) >> 6;
-      break;
-
-    case 0x03FB: /* Line control register */
-#if !USE_RAW_SERIAL
-      if ((value & 0x3) != 0x3) {
-       /* ignore this: this is set by FreeBSD when the console
-          code wants to set DLAB */
-      }
-#endif // !USE_RAW_SERIAL
-#if USE_RAW_SERIAL
-      if (BX_SER_THIS s[0].line_cntl.wordlen_sel != (value & 0x3)) {
-           BX_SER_THIS raw->set_data_bits((value & 0x3) + 5);
-      }
-      if (BX_SER_THIS s[0].line_cntl.stopbits != (value & 0x4) >> 2) {
-           BX_SER_THIS raw->set_stop_bits((value & 0x4 >> 2) ? 2 : 1);
-      }
-      if (BX_SER_THIS s[0].line_cntl.parity_enable != (value & 0x8) >> 3 ||
-         BX_SER_THIS s[0].line_cntl.evenparity_sel != (value & 0x10) >> 4 ||
-         BX_SER_THIS s[0].line_cntl.stick_parity != (value & 0x20) >> 5) {
-           if (((value & 0x20) >> 5) &&
-               ((value & 0x8) >> 3))
-                 BX_PANIC(("sticky parity set and parity enabled"));
-           BX_SER_THIS raw->set_parity_mode(((value & 0x8) >> 3),
-                                            ((value & 0x10) >> 4) ? P_EVEN : P_ODD);
-      }
-      if (BX_SER_THIS s[0].line_cntl.break_cntl && !((value & 0x40) >> 6)) {
-           BX_SER_THIS raw->transmit(C_BREAK);
-      }
-#endif // USE_RAW_SERIAL
-
-      BX_SER_THIS s[0].line_cntl.wordlen_sel = value & 0x3;
-      /* These are ignored, but set them up so they can be read back */
-      BX_SER_THIS s[0].line_cntl.stopbits = (value & 0x4) >> 2;
-      BX_SER_THIS s[0].line_cntl.parity_enable = (value & 0x8) >> 3;
-      BX_SER_THIS s[0].line_cntl.evenparity_sel = (value & 0x10) >> 4;
-      BX_SER_THIS s[0].line_cntl.stick_parity = (value & 0x20) >> 5;
-      BX_SER_THIS s[0].line_cntl.break_cntl = (value & 0x40) >> 6;
-      /* used when doing future writes */
-      if (BX_SER_THIS s[0].line_cntl.dlab &&
-         !((value & 0x80) >> 7)) {
-       // Start the receive polling process if not already started
-       // and there is a valid baudrate.
-       if (BX_SER_THIS s[0].rx_pollstate == BX_SER_RXIDLE &&
-           BX_SER_THIS s[0].baudrate != 0) {
-         BX_SER_THIS s[0].rx_pollstate = BX_SER_RXPOLL;
-         bx_pc_system.activate_timer(BX_SER_THIS s[0].rx_timer_index,
-                     (int) (1000000.0 / BX_SER_THIS s[0].baudrate *
-                      (BX_SER_THIS s[0].line_cntl.wordlen_sel + 5)),
-                      0); /* not continuous */
-       }
-       BX_DEBUG(("baud rate set - %d", BX_SER_THIS s[0].baudrate));
-      }
-      BX_SER_THIS s[0].line_cntl.dlab = (value & 0x80) >> 7;
-      break;
-
-    case 0x03FC: /* MODEM control register */
-      if ((value & 0x01) == 0) {
-#if USE_RAW_SERIAL
-       BX_SER_THIS raw->send_hangup();
-#endif
-      }
-
-      BX_SER_THIS s[0].modem_cntl.dtr  = value & 0x01;
-      BX_SER_THIS s[0].modem_cntl.rts  = (value & 0x02) >> 1;
-      BX_SER_THIS s[0].modem_cntl.out1 = (value & 0x04) >> 2;
-      BX_SER_THIS s[0].modem_cntl.out2 = (value & 0x08) >> 3;
-      BX_SER_THIS s[0].modem_cntl.local_loopback = (value & 0x10) >> 4;
-
-      if (BX_SER_THIS s[0].modem_cntl.local_loopback) {
-        prev_cts = BX_SER_THIS s[0].modem_status.cts;
-        prev_dsr = BX_SER_THIS s[0].modem_status.dsr;
-        prev_ri  = BX_SER_THIS s[0].modem_status.ri;
-        prev_dcd = BX_SER_THIS s[0].modem_status.dcd;
-        BX_SER_THIS s[0].modem_status.cts = BX_SER_THIS s[0].modem_cntl.rts;
-        BX_SER_THIS s[0].modem_status.dsr = BX_SER_THIS s[0].modem_cntl.dtr;
-        BX_SER_THIS s[0].modem_status.ri  = BX_SER_THIS s[0].modem_cntl.out1;
-        BX_SER_THIS s[0].modem_status.dcd = BX_SER_THIS s[0].modem_cntl.out2;
-        if (BX_SER_THIS s[0].modem_status.cts != prev_cts) {
-          BX_SER_THIS s[0].modem_status.delta_cts = 1;
-          BX_SER_THIS s[0].ms_ipending = 1;
-        }
-        if (BX_SER_THIS s[0].modem_status.dsr != prev_dsr) {
-          BX_SER_THIS s[0].modem_status.delta_dsr = 1;
-          BX_SER_THIS s[0].ms_ipending = 1;
-        }
-        if (BX_SER_THIS s[0].modem_status.ri != prev_ri)
-          BX_SER_THIS s[0].ms_ipending = 1;
-        if ((BX_SER_THIS s[0].modem_status.ri == 0) && (prev_ri == 1))
-          BX_SER_THIS s[0].modem_status.ri_trailedge = 1;
-        if (BX_SER_THIS s[0].modem_status.dcd != prev_dcd) {
-          BX_SER_THIS s[0].modem_status.delta_dcd = 1;
-          BX_SER_THIS s[0].ms_ipending = 1;
-        }
-        raise_interrupt(0, BX_SER_INT_MODSTAT);
-      } else {
-        /* set these to 0 for the time being */
-        BX_SER_THIS s[0].modem_status.cts = 0;
-        BX_SER_THIS s[0].modem_status.dsr = 0;
-        BX_SER_THIS s[0].modem_status.ri  = 0;
-        BX_SER_THIS s[0].modem_status.dcd = 0;
-      }
-      break;
-
-    case 0x03FD: /* Line status register */
-      BX_ERROR(("write to line status register ignored"));
-      break;
-
-    case 0x03FE: /* MODEM status register */
-      BX_ERROR(("write to MODEM status register ignored"));
-      break;
-
-    case 0x03FF: /* scratch register */
-      BX_SER_THIS s[0].scratch = value;
-      break;
-
-    default:
-      BX_PANIC(("unsupported io write to address=0x%04x, value = 0x%02x!",
-        (unsigned) address, (unsigned) value));
-      break;
-  }
-}
-
-
-void
-bx_serial_c::rx_fifo_enq(Bit8u port, Bit8u data)
-{
-  bx_bool gen_int = 0;
-
-  if (BX_SER_THIS s[port].fifo_cntl.enable) {
-    if (BX_SER_THIS s[port].rx_fifo_end == 16) {
-      BX_ERROR(("com%d: receive FIFO overflow", port + 1));
-      BX_SER_THIS s[port].line_status.overrun_error = 1;
-      raise_interrupt(port, BX_SER_INT_RXLSTAT);
-    } else {
-      BX_SER_THIS s[port].rx_fifo[BX_SER_THIS s[0].rx_fifo_end++] = data;
-      switch (BX_SER_THIS s[port].fifo_cntl.rxtrigger) {
-        case 1:
-          if (BX_SER_THIS s[0].rx_fifo_end == 4) gen_int = 1;
-          break;
-        case 2:
-          if (BX_SER_THIS s[0].rx_fifo_end == 8) gen_int = 1;
-          break;
-        case 3:
-          if (BX_SER_THIS s[0].rx_fifo_end == 14) gen_int = 1;
-          break;
-        default:
-          gen_int = 1;
-      }
-      if (gen_int) {
-        bx_pc_system.deactivate_timer(BX_SER_THIS s[0].fifo_timer_index);
-        BX_SER_THIS s[port].line_status.rxdata_ready = 1;
-        raise_interrupt(port, BX_SER_INT_RXDATA);
-      } else {
-        bx_pc_system.activate_timer(BX_SER_THIS s[0].fifo_timer_index,
-                                    (int) (1000000.0 / BX_SER_THIS s[0].baudrate *
-                                    (BX_SER_THIS s[0].line_cntl.wordlen_sel + 5) * 16),
-                                    0); /* not continuous */
-      }
-    }
-  } else {
-    if (BX_SER_THIS s[port].line_status.rxdata_ready == 1) {
-      BX_ERROR(("com%d: overrun error", port + 1));
-      BX_SER_THIS s[port].line_status.overrun_error = 1;
-      raise_interrupt(port, BX_SER_INT_RXLSTAT);
-    }
-    BX_SER_THIS s[port].rxbuffer = data;
-    BX_SER_THIS s[port].line_status.rxdata_ready = 1;
-    raise_interrupt(port, BX_SER_INT_RXDATA);
-  }
-}
-
-
-void
-bx_serial_c::tx_timer_handler(void *this_ptr)
-{
-  bx_serial_c *class_ptr = (bx_serial_c *) this_ptr;
-
-  class_ptr->tx_timer();
-}
-
-
-void
-bx_serial_c::tx_timer(void)
-{
-  bx_bool gen_int = 0;
-
-  if (BX_SER_THIS s[0].modem_cntl.local_loopback) {
-    rx_fifo_enq(0, BX_SER_THIS s[0].tsrbuffer);
-  } else {
-#if USE_RAW_SERIAL
-    if (!BX_SER_THIS raw->ready_transmit())
-         BX_PANIC(("Not ready to transmit"));
-    BX_SER_THIS raw->transmit(BX_SER_THIS s[0].tsrbuffer);
-#endif
-#if defined(SERIAL_ENABLE)
-    BX_DEBUG(("write: '%c'", BX_SER_THIS s[0].tsrbuffer));
-    if (tty_id >= 0) write(tty_id, (bx_ptr_t) & BX_SER_THIS s[0].tsrbuffer, 1);
-#endif
-  }
-
-  BX_SER_THIS s[0].line_status.tsr_empty = 1;
-  if (BX_SER_THIS s[0].fifo_cntl.enable && (BX_SER_THIS s[0].tx_fifo_end > 0)) {
-    BX_SER_THIS s[0].tsrbuffer = BX_SER_THIS s[0].tx_fifo[0];
-    BX_SER_THIS s[0].line_status.tsr_empty = 0;
-    memcpy(&BX_SER_THIS s[0].tx_fifo[0], &BX_SER_THIS s[0].tx_fifo[1], 15);
-    gen_int = (--BX_SER_THIS s[0].tx_fifo_end == 0);
-  } else if (!BX_SER_THIS s[0].line_status.thr_empty) {
-    BX_SER_THIS s[0].tsrbuffer = BX_SER_THIS s[0].thrbuffer;
-    BX_SER_THIS s[0].line_status.tsr_empty = 0;
-    gen_int = 1;
-  }
-  if (!BX_SER_THIS s[0].line_status.tsr_empty) {
-    if (gen_int) {
-      BX_SER_THIS s[0].line_status.thr_empty = 1;
-      raise_interrupt(0, BX_SER_INT_TXHOLD);
-    }
-    bx_pc_system.activate_timer(BX_SER_THIS s[0].tx_timer_index,
-                                (int) (1000000.0 / BX_SER_THIS s[0].baudrate *
-                                (BX_SER_THIS s[0].line_cntl.wordlen_sel + 5)),
-                                0); /* not continuous */
-  }
-}
-
-
-void
-bx_serial_c::rx_timer_handler(void *this_ptr)
-{
-  bx_serial_c *class_ptr = (bx_serial_c *) this_ptr;
-
-  class_ptr->rx_timer();
-}
-
-
-void
-bx_serial_c::rx_timer(void)
-{
-#if BX_HAVE_SELECT
-#ifndef __BEOS__
-  struct timeval tval;
-  fd_set fds;
-#endif
-#endif
-  int bdrate = BX_SER_THIS s[0].baudrate / (BX_SER_THIS s[0].line_cntl.wordlen_sel + 5);
-  unsigned char chbuf = 0;
-
-#if BX_HAVE_SELECT
-#ifndef __BEOS__
-  tval.tv_sec  = 0;
-  tval.tv_usec = 0;
-
-// MacOS: I'm not sure what to do with this, since I don't know
-// what an fd_set is or what FD_SET() or select() do. They aren't
-// declared in the CodeWarrior standard library headers. I'm just
-// leaving it commented out for the moment.
-
-  FD_ZERO(&fds);
-  if (tty_id >= 0) FD_SET(tty_id, &fds);
-
-  if ((BX_SER_THIS s[0].line_status.rxdata_ready == 0) ||
-      (BX_SER_THIS s[0].fifo_cntl.enable)) {
-#if USE_RAW_SERIAL
-    bx_bool rdy;
-    uint16 data;
-    if ((rdy = BX_SER_THIS raw->ready_receive())) {
-      data = BX_SER_THIS raw->receive();
-      if (data == C_BREAK) {
-           BX_DEBUG(("got BREAK"));
-           BX_SER_THIS s[0].line_status.break_int = 1;
-           rdy = 0;
-      }
-    }
-    if (rdy) {
-      chbuf = data;
-#elif defined(SERIAL_ENABLE)
-    if ((tty_id >= 0) && (select(tty_id + 1, &fds, NULL, NULL, &tval) == 1)) {
-      (void) read(tty_id, &chbuf, 1);
-      BX_DEBUG(("read: '%c'",chbuf));
-#else
-    if (0) {
-#endif
-      if (!BX_SER_THIS s[0].modem_cntl.local_loopback) {
-        rx_fifo_enq(0, chbuf);
-      }
-    } else {
-      if (!BX_SER_THIS s[0].fifo_cntl.enable) {
-        bdrate = (int) (1000000.0 / 100000); // Poll frequency is 100ms
-      }
-    }
-  } else {
-    // Poll at 4x baud rate to see if the next-char can
-    // be read
-    bdrate *= 4;
-  }
-#endif
-#endif
-
-  bx_pc_system.activate_timer(BX_SER_THIS s[0].rx_timer_index,
-                             (int) (1000000.0 / bdrate),
-                             0); /* not continuous */
-}
-
-
-void
-bx_serial_c::fifo_timer_handler(void *this_ptr)
-{
-  bx_serial_c *class_ptr = (bx_serial_c *) this_ptr;
-
-  class_ptr->fifo_timer();
-}
-
-
-void
-bx_serial_c::fifo_timer(void)
-{
-  BX_SER_THIS s[0].line_status.rxdata_ready = 1;
-  raise_interrupt(0, BX_SER_INT_FIFO);
-}
diff --git a/tools/ioemu/iodev/serial.h b/tools/ioemu/iodev/serial.h
deleted file mode 100644 (file)
index 00f01c9..0000000
+++ /dev/null
@@ -1,193 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: serial.h,v 1.15 2003/11/16 08:21:10 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-// Peter Grehan (grehan@iprg.nokia.com) coded most of this
-// serial emulation.
-
-#if USE_RAW_SERIAL
-#include "serial_raw.h"
-#endif // USE_RAW_SERIAL
-
-#if BX_USE_SER_SMF
-#  define BX_SER_SMF  static
-#  define BX_SER_THIS theSerialDevice->
-#else
-#  define BX_SER_SMF
-#  define BX_SER_THIS this->
-#endif
-
-#define BX_SERIAL_MAXDEV   4
-
-#define  BX_PC_CLOCK_XTL   1843200.0
-
-#define  BX_SER_RXIDLE  0
-#define  BX_SER_RXPOLL  1
-#define  BX_SER_RXWAIT  2
-
-enum {
-  BX_SER_INT_IER,
-  BX_SER_INT_RXDATA,
-  BX_SER_INT_TXHOLD,
-  BX_SER_INT_RXLSTAT,
-  BX_SER_INT_MODSTAT,
-  BX_SER_INT_FIFO
-};
-
-typedef struct {
-  /*
-   * UART internal state
-   */
-  bx_bool  ls_interrupt;
-  bx_bool  ms_interrupt;
-  bx_bool  rx_interrupt;
-  bx_bool  tx_interrupt;
-  bx_bool  fifo_interrupt;
-  bx_bool  ls_ipending;
-  bx_bool  ms_ipending;
-  bx_bool  rx_ipending;
-  bx_bool  fifo_ipending;
-
-  Bit8u IRQ;
-
-  Bit8u rx_fifo_end;
-  Bit8u tx_fifo_end;
-
-  int  baudrate;
-  int  tx_timer_index;
-
-  int  rx_pollstate;
-  int  rx_timer_index;
-  int  fifo_timer_index;
-
-  /*
-   * Register definitions
-   */
-  Bit8u     rxbuffer;     /* receiver buffer register (r/o) */
-  Bit8u     thrbuffer;    /* transmit holding register (w/o) */
-  /* Interrupt Enable Register */
-  struct {
-    bx_bool    rxdata_enable;      /* 1=enable receive data interrupts */
-    bx_bool    txhold_enable;      /* 1=enable tx. holding reg. empty ints */
-    bx_bool    rxlstat_enable;     /* 1=enable rx line status interrupts */
-    bx_bool    modstat_enable;     /* 1=enable modem status interrupts */
-  } int_enable;
-  /* Interrupt Identification Register (r/o) */
-  struct {
-    bx_bool    ipending;           /* 0=interrupt pending */
-    Bit8u      int_ID;             /* 3-bit interrupt ID */
-  } int_ident;
-  /* FIFO Control Register (w/o) */
-  struct {
-    bx_bool    enable;             /* 1=enable tx and rx FIFOs */
-    Bit8u      rxtrigger;          /* 2-bit code for rx fifo trigger level */
-  } fifo_cntl;
-  /* Line Control Register (r/w) */
-  struct {
-    Bit8u      wordlen_sel;        /* 2-bit code for char length */
-    bx_bool    stopbits;           /* select stop bit len */
-    bx_bool    parity_enable;      /* ... */
-    bx_bool    evenparity_sel;     /* ... */
-    bx_bool    stick_parity;       /* ... */
-    bx_bool    break_cntl;         /* 1=send break signal */
-    bx_bool    dlab;               /* divisor latch access bit */
-  } line_cntl;
-  /* MODEM Control Register (r/w) */
-  struct {
-    bx_bool    dtr;                /* DTR output value */
-    bx_bool    rts;                /* RTS output value */
-    bx_bool    out1;               /* OUTPUT1 value */
-    bx_bool    out2;               /* OUTPUT2 value */
-    bx_bool    local_loopback;     /* 1=loopback mode */
-  } modem_cntl;
-  /* Line Status Register (r/w) */
-  struct {
-    bx_bool    rxdata_ready;       /* 1=receiver data ready */
-    bx_bool    overrun_error;      /* 1=receive overrun detected */
-    bx_bool    parity_error;       /* 1=rx char has a bad parity bit */
-    bx_bool    framing_error;      /* 1=no stop bit detected for rx char */
-    bx_bool    break_int;          /* 1=break signal detected */
-    bx_bool    thr_empty;          /* 1=tx hold register (or fifo) is empty */
-    bx_bool    tsr_empty;          /* 1=shift reg and hold reg empty */
-    bx_bool    fifo_error;         /* 1=at least 1 err condition in fifo */
-  } line_status;
-  /* Modem Status Register (r/w) */
-  struct {
-    bx_bool    delta_cts;          /* 1=CTS changed since last read */
-    bx_bool    delta_dsr;          /* 1=DSR changed since last read */
-    bx_bool    ri_trailedge;       /* 1=RI moved from low->high */
-    bx_bool    delta_dcd;          /* 1=CD changed since last read */
-    bx_bool    cts;                /* CTS input value */
-    bx_bool    dsr;                /* DSR input value */
-    bx_bool    ri;                 /* RI input value */
-    bx_bool    dcd;                /* DCD input value */
-  } modem_status;
-
-  Bit8u  scratch;       /* Scratch Register (r/w) */
-  Bit8u  tsrbuffer;     /* transmit shift register (internal) */
-  Bit8u  rx_fifo[16];   /* receive FIFO (internal) */
-  Bit8u  tx_fifo[16];   /* transmit FIFO (internal) */
-  Bit8u  divisor_lsb;   /* Divisor latch, least-sig. byte */
-  Bit8u  divisor_msb;   /* Divisor latch, most-sig. byte */
-} bx_serial_t;
-
-
-
-class bx_serial_c : public bx_devmodel_c {
-public:
-  bx_serial_c(void);
-  ~bx_serial_c(void);
-  virtual void   init(void);
-  virtual void   reset(unsigned type);
-#if USE_RAW_SERIAL
-  serial_raw* raw;
-#endif // USE_RAW_SERIAL
-
-private:
-    bx_serial_t s[BX_SERIAL_MAXDEV];
-
-  static void lower_interrupt(Bit8u port);
-  static void raise_interrupt(Bit8u port, int type);
-
-  static void rx_fifo_enq(Bit8u port, Bit8u data);
-
-  static void tx_timer_handler(void *);
-  BX_SER_SMF void tx_timer(void);
-
-  static void rx_timer_handler(void *);
-  BX_SER_SMF void rx_timer(void);
-
-  static void fifo_timer_handler(void *);
-  BX_SER_SMF void fifo_timer(void);
-
-  static Bit32u read_handler(void *this_ptr, Bit32u address, unsigned io_len);
-  static void   write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);
-#if !BX_USE_SER_SMF
-  Bit32u read(Bit32u address, unsigned io_len);
-  void   write(Bit32u address, Bit32u value, unsigned io_len);
-#endif
-  };
-
diff --git a/tools/ioemu/iodev/serial_raw.h b/tools/ioemu/iodev/serial_raw.h
deleted file mode 100644 (file)
index 978c28d..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: serial_raw.h,v 1.2 2001/10/03 13:10:38 bdenney Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-#include <linux/serial.h>
-
-#define P_EVEN 0
-#define P_ODD 1
-#define C_BREAK 201
-
-class serial_raw : public logfunctions {
-  public:
-    serial_raw (char *ttypath, int signal);
-    void set_baudrate (int rate);
-    void set_data_bits (int );
-    void set_stop_bits (int);
-    void set_parity_mode (int, int);
-    void transmit (int byte);
-    void send_hangup ();
-    int ready_transmit ();
-    int ready_receive ();
-    int receive ();
-};
diff --git a/tools/ioemu/iodev/slowdown_timer.cc b/tools/ioemu/iodev/slowdown_timer.cc
deleted file mode 100644 (file)
index 76d8613..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: slowdown_timer.cc,v 1.17.2.1 2004/02/06 22:14:36 danielg4 Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-//
-
-#include "bochs.h"
-#include <errno.h>
-
-//These need to stay printfs because they are useless in the log file.
-#define BX_SLOWDOWN_PRINTF_FEEDBACK 0
-
-#define SECINUSEC 1000000
-#define usectosec(a) ((a)/SECINUSEC)
-#define sectousec(a) ((a)*SECINUSEC)
-#define nsectousec(a) ((a)/1000)
-
-#define MSECINUSEC 1000
-#define usectomsec(a) ((a)/MSECINUSEC)
-
-#if BX_HAVE_USLEEP
-#  define Qval 1000
-#else
-#  define Qval SECINUSEC
-#endif
-
-#define MAXMULT 1.5
-#define REALTIME_Q SECINUSEC
-
-#define LOG_THIS bx_slowdown_timer.
-
-bx_slowdown_timer_c bx_slowdown_timer;
-
-bx_slowdown_timer_c::bx_slowdown_timer_c() {
-  put("STIMER");
-  settype(STIMERLOG);
-
-
-  s.start_time=0;
-  s.start_emulated_time=0;
-  s.timer_handle=BX_NULL_TIMER_HANDLE;
-}
-
-void
-bx_slowdown_timer_c::init(void) {
-
-  // Return early if slowdown timer not selected
-  if ( (bx_options.clock.Osync->get () != BX_CLOCK_SYNC_SLOWDOWN)
-    && (bx_options.clock.Osync->get () != BX_CLOCK_SYNC_BOTH) )
-    return;
-
-  BX_INFO(("using 'slowdown' timer synchronization method"));
-  s.MAXmultiplier=MAXMULT;
-  s.Q=Qval;
-
-  if(s.MAXmultiplier<1)
-    s.MAXmultiplier=1;
-
-  s.start_time=sectousec(time(NULL));
-  s.start_emulated_time = bx_pc_system.time_usec();
-  s.lasttime=0;
-  if (s.timer_handle == BX_NULL_TIMER_HANDLE) {
-    s.timer_handle=bx_pc_system.register_timer(this, timer_handler, 100 , 1, 1,
-       "slowdown_timer");
-  }
-  bx_pc_system.deactivate_timer(s.timer_handle);
-  bx_pc_system.activate_timer(s.timer_handle,(Bit32u)s.Q,0);
-}
-
-void
-bx_slowdown_timer_c::reset(unsigned type)
-{
-}
-
-void
-bx_slowdown_timer_c::timer_handler(void * this_ptr) {
-  bx_slowdown_timer_c * class_ptr = (bx_slowdown_timer_c *) this_ptr;
-
-  class_ptr->handle_timer();
-}
-
-void
-bx_slowdown_timer_c::handle_timer() {
-  Bit64u total_emu_time = (bx_pc_system.time_usec()) - s.start_emulated_time;
-  Bit64u wanttime = s.lasttime+s.Q;
-  Bit64u totaltime = sectousec(time(NULL)) - s.start_time;
-  Bit64u thistime=(wanttime>totaltime)?wanttime:totaltime;
-
-#if BX_SLOWDOWN_PRINTF_FEEDBACK
-  printf("Entering slowdown timer handler.\n");
-#endif
-
-  /* Decide if we're behind.
-   * Set interrupt interval accordingly. */
-  if(totaltime > total_emu_time) {
-    bx_pc_system.deactivate_timer(s.timer_handle);
-    bx_pc_system.activate_timer(s.timer_handle,
-                               (Bit32u)(s.MAXmultiplier * (float)((Bit64s)s.Q)),
-                               0);
-#if BX_SLOWDOWN_PRINTF_FEEDBACK
-    printf("running at MAX speed\n");
-#endif
-  } else {
-    bx_pc_system.deactivate_timer(s.timer_handle);
-    bx_pc_system.activate_timer(s.timer_handle,s.Q,0);
-#if BX_SLOWDOWN_PRINTF_FEEDBACK
-    printf("running at NORMAL speed\n");
-#endif
-  }
-
-  /* Make sure we took at least one time quantum. */
-  /* This is a little strange.  I'll try to explain.
-   * We're running bochs one second ahead of real time.
-   *  this gives us a very precise division on whether
-   *  we're ahead or behind the second line.
-   * Basically, here's how it works:
-   * *****|******************|***********...
-   *      Time               Time+1sec
-   *                        <^Bochs doesn't delay.
-   *                          ^>Bochs delays.
-   *    <^Bochs runs at MAX speed.
-   *      ^>Bochs runs at normal
-   */
-  if(wanttime > (totaltime+REALTIME_Q)) {
-#if BX_HAVE_USLEEP
-    usleep(s.Q);
-#elif BX_HAVE_MSLEEP
-    msleep(usectomsec(s.Q));
-#elif BX_HAVE_SLEEP
-    sleep(usectosec(s.Q));
-#else
-#error do not know have to sleep
-#endif    //delay(wanttime-totaltime);
-    /*alternatively: delay(Q);
-     * This works okay because we share the delay between
-     * two time quantums.
-     */
-#if BX_SLOWDOWN_PRINTF_FEEDBACK
-    printf("DELAYING for a quantum\n");
-#endif
-  }
-  s.lasttime=thistime;
-
-  //Diagnostic info:
-#if 0
-  if(wanttime > (totaltime+REALTIME_Q)) {
-    if(totaltime > total_emu_time) {
-      printf("Solving OpenBSD problem.\n");
-    } else {
-      printf("too fast.\n");
-    }
-  } else {
-    if(totaltime > total_emu_time) {
-      printf("too slow.\n");
-    } else {
-      printf("sometimes invalid state, normally okay.\n");
-    }
-  }
-#endif // Diagnostic info
-}
-
diff --git a/tools/ioemu/iodev/slowdown_timer.h b/tools/ioemu/iodev/slowdown_timer.h
deleted file mode 100644 (file)
index 3b6b153..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: slowdown_timer.h,v 1.8 2003/08/19 00:10:38 cbothamy Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-
-class bx_slowdown_timer_c : public logfunctions {
-
-private:
-  struct {
-    Bit64u start_time;
-    Bit64u start_emulated_time;
-    Bit64u lasttime;
-
-    int timer_handle;
-
-    float MAXmultiplier;
-    Bit64u Q; // (Q (in seconds))
-  } s;
-
-public:
-  bx_slowdown_timer_c();
-
-  void init(void);
-  void reset(unsigned type);
-
-  static void timer_handler(void * this_ptr);
-
-  void handle_timer();
-
-};
-
-extern bx_slowdown_timer_c bx_slowdown_timer;
-
diff --git a/tools/ioemu/iodev/soundlnx.cc b/tools/ioemu/iodev/soundlnx.cc
deleted file mode 100644 (file)
index 773addc..0000000
+++ /dev/null
@@ -1,227 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: soundlnx.cc,v 1.6 2002/12/24 10:12:26 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2001  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-// This file (SOUNDLNX.CC) written and donated by Josef Drexler
-
-
-#include "bochs.h"
-#if (defined(linux) || defined(__FreeBSD__)) && BX_SUPPORT_SB16
-#define LOG_THIS bx_sb16.
-
-#include <errno.h>
-#include <sys/ioctl.h>
-#include <sys/soundcard.h>
-
-bx_sound_linux_c::bx_sound_linux_c(bx_sb16_c *sb16)
-  :bx_sound_output_c(sb16)
-{
-  this->sb16 = sb16;
-  midi = NULL;
-  wavedevice = NULL;
-  wave = -1;
-}
-
-bx_sound_linux_c::~bx_sound_linux_c()
-{
-  // nothing for now
-}
-
-
-int bx_sound_linux_c::waveready()
-{
-  return BX_SOUND_OUTPUT_OK;
-}
-
-int bx_sound_linux_c::midiready()
-{
-  return BX_SOUND_OUTPUT_OK;
-}
-
-int bx_sound_linux_c::openmidioutput(char *device)
-{
-  if ( (device == NULL) || (strlen(device) < 1) )
-    return BX_SOUND_OUTPUT_ERR;
-
-  midi = fopen(device,"w");
-
-  if (midi == NULL)
-    {
-      WRITELOG( MIDILOG(2), "Couldn't open midi output device %s: %s.",
-               device, strerror(errno));
-      return BX_SOUND_OUTPUT_ERR;
-    }
-
-  return BX_SOUND_OUTPUT_OK;
-}
-
-
-int bx_sound_linux_c::sendmidicommand(int delta, int command, int length, Bit8u data[])
-{
-  UNUSED(delta);
-  //  BX_PANIC(("Sendmidicommand!!");
-
-  fputc(command, midi);
-  fwrite(data, 1, length, midi);
-  fflush(midi);       // to start playing immediately
-
-  return BX_SOUND_OUTPUT_OK;
-}
-
-
-int bx_sound_linux_c::closemidioutput()
-{
-  fclose(midi);
-
-  return BX_SOUND_OUTPUT_OK;
-}
-
-
-int bx_sound_linux_c::openwaveoutput(char *device)
-{
-  int length = strlen(device) + 1;
-
-  if (wavedevice != NULL)
-    delete(wavedevice);
-
-  wavedevice = new char[length];
-
-  if (wavedevice == NULL)
-    return BX_SOUND_OUTPUT_ERR;
-
-  strncpy(wavedevice, device, length);
-
-  return BX_SOUND_OUTPUT_OK;
-}
-
-int bx_sound_linux_c::startwaveplayback(int frequency, int bits, int stereo, int format)
-{
-  int fmt, ret;
-  int signeddata = format & 1;
-
-  if ( (wavedevice == NULL) || (strlen(wavedevice) < 1) )
-    return BX_SOUND_OUTPUT_ERR;
-
-  if (wave == -1)
-    wave = open(wavedevice, O_WRONLY);
-  else
-    if ( (frequency == oldfreq) &&
-        (bits == oldbits) &&
-        (stereo == oldstereo) &&
-        (format == oldformat) )
-      return BX_SOUND_OUTPUT_OK;    // nothing to do
-
-  oldfreq = frequency;
-  oldbits = bits;
-  oldstereo = stereo;
-  oldformat = format;
-
-  if (wave == -1)
-    return BX_SOUND_OUTPUT_ERR;
-
-  if (bits == 16)
-    if (signeddata == 1)
-      fmt = AFMT_S16_LE;
-    else
-      fmt = AFMT_U16_LE;
-  else if (bits == 8)
-    if (signeddata == 1)
-      fmt = AFMT_S8;
-    else
-      fmt = AFMT_U8;
-  else
-    return BX_SOUND_OUTPUT_ERR;
-      // set frequency etc.
-  ret = ioctl(wave, SNDCTL_DSP_RESET);
-  if (ret != 0)
-    WRITELOG( WAVELOG(4), "ioctl(SNDCTL_DSP_RESET): %s", strerror(errno));
-
-  /*
-  ret = ioctl(wave, SNDCTL_DSP_SETFRAGMENT, &fragment);
-  if (ret != 0)
-    WRITELOG( WAVELOG(4), "ioctl(SNDCTL_DSP_SETFRAGMENT, %d): %s",
-             fragment, strerror(errno));
-  */
-
-  ret = ioctl(wave, SNDCTL_DSP_SETFMT, &fmt);
-  if (ret != 0)   // abort if the format is unknown, to avoid playing noise
-    {
-      WRITELOG( WAVELOG(4), "ioctl(SNDCTL_DSP_SETFMT, %d): %s",
-               fmt, strerror(errno));
-      return BX_SOUND_OUTPUT_ERR;
-    }
-
-  ret = ioctl(wave, SNDCTL_DSP_STEREO, &stereo);
-  if (ret != 0)
-    WRITELOG( WAVELOG(4), "ioctl(SNDCTL_DSP_STEREO, %d): %s", 
-             stereo, strerror(errno));
-
-  ret = ioctl(wave, SNDCTL_DSP_SPEED, &frequency);
-  if (ret != 0)
-    WRITELOG( WAVELOG(4), "ioctl(SNDCTL_DSP_SPEED, %d): %s", 
-             frequency, strerror(errno));
-
-  //  ioctl(wave, SNDCTL_DSP_GETBLKSIZE, &fragment);
-  //  WRITELOG( WAVELOG(4), "current output block size is %d", fragment);
-
-  return BX_SOUND_OUTPUT_OK;
-}
-                        
-int bx_sound_linux_c::sendwavepacket(int length, Bit8u data[])
-{
-  int ret;
-
-  ret = write(wave, data, length);
-
-  return BX_SOUND_OUTPUT_OK;
-}
-
-int bx_sound_linux_c::stopwaveplayback()
-{
-  //  ioctl(wave, SNDCTL_DSP_SYNC);
-  //  close(wave);
-  //  wave = -1;
-
-  return BX_SOUND_OUTPUT_OK;
-}
-
-int bx_sound_linux_c::closewaveoutput()
-{
-  if (wavedevice != NULL)
-    delete(wavedevice);
-
-  if (wave != -1)
-    {
-      close(wave);
-      wave = -1;
-    }
-
-  wavedevice = NULL;
-
-  return BX_SOUND_OUTPUT_OK;
-}
-
-#endif  // defined(linux)
diff --git a/tools/ioemu/iodev/soundlnx.h b/tools/ioemu/iodev/soundlnx.h
deleted file mode 100644 (file)
index 8f718b5..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: soundlnx.h,v 1.5 2002/12/24 10:12:26 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2001  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-// This file (SOUNDLNX.H) written and donated by Josef Drexler
-
-
-#if (defined(linux) || defined(__FreeBSD__))
-
-#include "bochs.h"
-
-#define BX_SOUND_LINUX_BUFSIZE   BX_SOUND_OUTPUT_WAVEPACKETSIZE
-
-class bx_sound_linux_c : public bx_sound_output_c {
-public:
-  bx_sound_linux_c(bx_sb16_c *sb16);
-  BX_SOUND_VIRTUAL ~bx_sound_linux_c();
-
-  // if virtual functions are used, we have to override them
-  // and define our own. Otherwise this file will just implement
-  // the original functions
-#ifdef BX_USE_SOUND_VIRTUAL
-  BX_SOUND_VIRTUAL int    waveready();
-  BX_SOUND_VIRTUAL int    midiready();
-
-  BX_SOUND_VIRTUAL int    openmidioutput(char *device);
-  BX_SOUND_VIRTUAL int    sendmidicommand(int delta, int command, int length, Bit8u data[]);
-  BX_SOUND_VIRTUAL int    closemidioutput();
-
-  BX_SOUND_VIRTUAL int    openwaveoutput(char *device);
-  BX_SOUND_VIRTUAL int    startwaveplayback(int frequency, int bits, int stereo, int format);
-  BX_SOUND_VIRTUAL int    sendwavepacket(int length, Bit8u data[]);
-  BX_SOUND_VIRTUAL int    stopwaveplayback();
-  BX_SOUND_VIRTUAL int    closewaveoutput();
-#endif
-
-private:
-  bx_sb16_c *sb16;
-  FILE *midi;
-  char *wavedevice;
-  int wave;
-  int bufferpos;
-  Bit8u audio_buffer[BX_SOUND_LINUX_BUFSIZE];
-  int oldfreq,oldbits,oldstereo,oldformat;
-};
-
-#endif  // defined(linux)
diff --git a/tools/ioemu/iodev/soundwin.cc b/tools/ioemu/iodev/soundwin.cc
deleted file mode 100644 (file)
index b8b386c..0000000
+++ /dev/null
@@ -1,521 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: soundwin.cc,v 1.13 2003/04/05 08:26:49 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2001  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-// This file (SOUNDWIN.CC) written and donated by Josef Drexler
-
-// Define BX_PLUGGABLE in files that can be compiled into plugins.  For
-// platforms that require a special tag on exported symbols, BX_PLUGGABLE 
-// is used to know when we are exporting symbols and when we are importing.
-#define BX_PLUGGABLE
-
-#include "bochs.h"
-#if defined(WIN32) && BX_SUPPORT_SB16
-
-#define LOG_THIS bx_devices.pluginSB16Device->
-
-bx_sound_windows_c::bx_sound_windows_c(bx_sb16_c *sb16)
-  :bx_sound_output_c(sb16)
-{
-  this->sb16 = sb16;
-
-  MidiOpen = 0;
-  WaveOpen = 0;
-
-  ismidiready = 1;
-  iswaveready = 1;
-
-  // size is the total size of the midi header and buffer and the
-  // BX_SOUND_WINDOWS_NBUF wave header and buffers, all aligned
-  // on a 16-byte boundary
-
-#define ALIGN(size) ( (size + 15) & ~15 )
-
-#define size   ALIGN(sizeof(MIDIHDR)) \
-            + ALIGN(sizeof(WAVEHDR)) \
-            + ALIGN(BX_SOUND_WINDOWS_MAXSYSEXLEN) * BX_SOUND_WINDOWS_NBUF \
-            + ALIGN(BX_SOUND_OUTPUT_WAVEPACKETSIZE) * BX_SOUND_WINDOWS_NBUF
-
-  DataHandle = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, size);
-  DataPointer = (Bit8u*) GlobalLock(DataHandle);
-
-  if (DataPointer == NULL)
-    BX_PANIC(("GlobalLock returned NULL-pointer"));
-
-#define NEWBUFFER(size) &(DataPointer[offset]); offset += ALIGN(size)
-
-  int offset = 0;
-  MidiHeader = (LPMIDIHDR) NEWBUFFER(sizeof(MIDIHDR));
-  MidiData = (LPSTR) NEWBUFFER(BX_SOUND_WINDOWS_MAXSYSEXLEN);
-
-  for (int bufnum=0; bufnum<BX_SOUND_WINDOWS_NBUF; bufnum++)
-    {
-      WaveHeader[bufnum] = (LPWAVEHDR) NEWBUFFER(sizeof(WAVEHDR));
-      WaveData[bufnum] = (LPSTR) NEWBUFFER(BX_SOUND_OUTPUT_WAVEPACKETSIZE);
-    }
-
-  if (offset > size)
-    BX_PANIC(("Allocated memory was too small!"));
-
-#undef size
-#undef ALIGN
-#undef NEWBUFFER
-}
-
-bx_sound_windows_c::~bx_sound_windows_c()
-{
-  GlobalUnlock(DataHandle);
-  GlobalFree(DataHandle);
-}
-
-int bx_sound_windows_c::waveready()
-{
-  if (iswaveready == 0)
-    checkwaveready();
-
-  if (iswaveready == 1)
-    return BX_SOUND_OUTPUT_OK;
-  else
-    return BX_SOUND_OUTPUT_ERR;
-}
-int bx_sound_windows_c::midiready()
-{
-  if (ismidiready == 0)
-    checkmidiready();
-
-  if (ismidiready == 1)
-    return BX_SOUND_OUTPUT_OK;
-  else
-    return BX_SOUND_OUTPUT_ERR;
-}
-
-int bx_sound_windows_c::openmidioutput(char *device)
-{
-  // could make the output device selectable,
-  // but currently only the midi mapper is supported
-  UNUSED(device);
-
-  UINT deviceid = (UINT) MIDIMAPPER;
-
-  MidiOpen = 0;
-
-  UINT ret = midiOutOpen( &MidiOut, deviceid, 0, 0, CALLBACK_NULL);
-  if (ret == 0)
-    MidiOpen = 1;
-
-  WRITELOG( MIDILOG(4), "midiOutOpen() = %d, MidiOpen: %d", ret, MidiOpen);
-
-  return (MidiOpen == 1) ? BX_SOUND_OUTPUT_OK : BX_SOUND_OUTPUT_ERR;
-}
-
-int bx_sound_windows_c::sendmidicommand(int delta, int command, int length, Bit8u data[])
-{
-  UINT ret;
-
-  if (MidiOpen != 1)
-    return BX_SOUND_OUTPUT_ERR;
-
-  if ( (command == 0xf0) || (command == 0xf7) || (length > 3) )
-    {
-      WRITELOG( WAVELOG(5), "SYSEX started, length %d", length);
-      ismidiready = 0;   // until the buffer is done
-      memcpy(MidiData, data, length);
-      MidiHeader->lpData = MidiData;
-      MidiHeader->dwBufferLength = BX_SOUND_WINDOWS_MAXSYSEXLEN;
-      MidiHeader->dwBytesRecorded = 0;
-      MidiHeader->dwUser = 0;
-      MidiHeader->dwFlags = 0;
-      ret = midiOutPrepareHeader(MidiOut, MidiHeader, sizeof(*MidiHeader));
-      if (ret != 0)
-       WRITELOG( MIDILOG(2), "midiOutPrepareHeader() = %d", ret);
-      ret = midiOutLongMsg(MidiOut, MidiHeader, sizeof(*MidiHeader));
-      if (ret != 0)
-       WRITELOG( MIDILOG(2), "midiOutLongMsg() = %d", ret);
-    }
-  else
-    {
-      DWORD msg = command;
-
-      for (int i = 0; i<length; i++)
-       msg |= (data[i] << (8 * (i + 1) ) );
-
-      ret = midiOutShortMsg(MidiOut, msg);
-      WRITELOG( MIDILOG(4), "midiOutShortMsg(%x) = %d", msg, ret);
-    }
-
-  return (ret == 0) ? BX_SOUND_OUTPUT_OK : BX_SOUND_OUTPUT_ERR;
-}
-
-int bx_sound_windows_c::closemidioutput()
-{
-  UINT ret;
-
-  if (MidiOpen != 1)
-    return BX_SOUND_OUTPUT_ERR;
-
-  ret = midiOutReset(MidiOut);
-  if (ismidiready == 0)
-    checkmidiready();   // to clear any pending SYSEX
-
-  ret = midiOutClose(MidiOut);
-  WRITELOG( MIDILOG(4), "midiOutClose() = %d", ret);
-  MidiOpen = 0;
-
-  return (ret == 0) ? BX_SOUND_OUTPUT_OK : BX_SOUND_OUTPUT_ERR;
-}
-
-int bx_sound_windows_c::openwaveoutput(char *device)
-{
-  // could make the output device selectable,
-  // but currently only the midi mapper is supported
-  UNUSED(device);
-
-  WRITELOG( WAVELOG(4), "openwaveoutput(%s)", device);
-
-#ifdef usewaveOut
-  WaveDevice = (UINT) WAVEMAPPER;
-
-  for (int i=0; i<BX_SOUND_WINDOWS_NBUF; i++)
-    WaveHeader[i]->dwFlags = WHDR_DONE;
-
-  head = 0;
-  tailfull = 0;
-  tailplay = 0;
-  needreopen = 0;
-#endif
-
-  return BX_SOUND_OUTPUT_OK;
-}
-
-int bx_sound_windows_c::playnextbuffer()
-{
-  UINT ret;
-  PCMWAVEFORMAT waveformat;
-  int bufnum;
-
-  // if the format is different, we have to reopen the device,
-  // so reset it first
-  if (needreopen != 0)
-    if (WaveOpen != 0)
-      ret = waveOutReset( WaveOut );
-
-  // clean up the buffers and mark if output is ready
-  checkwaveready();
-
-  // do we have to play anything?
-  if (tailplay == head)
-    return BX_SOUND_OUTPUT_OK;
-
-  // if the format is different, we have to close and reopen the device
-  // or, just open the device if it's not open yet
-  if ( (needreopen != 0) || (WaveOpen == 0) )
-    {
-      if (WaveOpen != 0)
-       {
-         ret = waveOutClose( WaveOut );
-         WaveOpen = 0;
-       }
-
-      // try three times to find a suitable format
-      for (int tries = 0; tries < 3; tries++)
-       {
-         int frequency = WaveInfo.frequency;
-         int stereo = WaveInfo.stereo;
-         int bits = WaveInfo.bits;
-         int format = WaveInfo.format;
-         int bps = (bits / 8) * (stereo + 1);
-
-         waveformat.wf.wFormatTag = WAVE_FORMAT_PCM;
-         waveformat.wf.nChannels = stereo + 1;
-         waveformat.wf.nSamplesPerSec = frequency;
-         waveformat.wf.nAvgBytesPerSec = frequency * bps;
-         waveformat.wf.nBlockAlign = bps;
-         waveformat.wBitsPerSample = bits;
-
-         ret = waveOutOpen( &(WaveOut), WaveDevice, (LPWAVEFORMATEX)&(waveformat.wf), 0, 0, CALLBACK_NULL);
-         if (ret != 0)
-           {
-             char errormsg[4*MAXERRORLENGTH+1];
-             waveOutGetErrorTextA(ret, errormsg, 4*MAXERRORLENGTH+1);
-             WRITELOG( WAVELOG(5), "waveOutOpen: %s", errormsg);
-             switch (tries)
-               {
-               case 0: // maybe try a different frequency
-                 if (frequency < 15600)
-                   frequency = 11025;
-                 else if (frequency < 31200)
-                   frequency = 22050;
-                 else
-                   frequency = 44100;
-
-                 WRITELOG( WAVELOG(4), "Couldn't open wave device (error %d), trying frequency %d", ret, frequency);
-
-                 break;
-               case 1: // or something else
-                 frequency = 11025;
-                 stereo = 0;
-                 bits = 8;
-                 bps = 1;
-
-                 WRITELOG( WAVELOG(4), "Couldn't open wave device again (error %d), trying 11KHz, mono, 8bit", ret);
-
-                 break;
-               case 2: // nope, doesn't work
-
-                 WRITELOG( WAVELOG(2), "Couldn't open wave device (error %d)!", ret);
-
-                 return BX_SOUND_OUTPUT_ERR;
-               }
-             WRITELOG( WAVELOG(5), "The format was: wFormatTag=%d, nChannels=%d, nSamplesPerSec=%d,",
-                       waveformat.wf.wFormatTag, waveformat.wf.nChannels, waveformat.wf.nSamplesPerSec);
-             WRITELOG( WAVELOG(5), "                nAvgBytesPerSec=%d, nBlockAlign=%d, wBitsPerSample=%d",
-                       waveformat.wf.nAvgBytesPerSec, waveformat.wf.nBlockAlign, waveformat.wBitsPerSample);
-
-           }
-         else
-           {
-             WaveOpen = 1;
-             needreopen = 0;
-             break;
-           }
-       }
-    }
-
-  for (bufnum=tailplay; bufnum != head;
-       bufnum++, bufnum &= BX_SOUND_WINDOWS_NMASK, tailplay=bufnum)
-    {
-      WRITELOG( WAVELOG(5), "Playing buffer %d", bufnum);
-
-      // prepare the wave header
-      WaveHeader[bufnum]->lpData = WaveData[bufnum];
-      WaveHeader[bufnum]->dwBufferLength = length[bufnum];
-      WaveHeader[bufnum]->dwBytesRecorded = length[bufnum];
-      WaveHeader[bufnum]->dwUser = 0;
-      WaveHeader[bufnum]->dwFlags = 0;
-      WaveHeader[bufnum]->dwLoops = 1;
-
-      ret = waveOutPrepareHeader(WaveOut, WaveHeader[bufnum], sizeof(*WaveHeader[bufnum]));
-      if (ret != 0)
-       {
-         WRITELOG( WAVELOG(2), "waveOutPrepareHeader = %d", ret);
-         return BX_SOUND_OUTPUT_ERR;
-       }
-
-      ret = waveOutWrite(WaveOut, WaveHeader[bufnum], sizeof(*WaveHeader[bufnum]));
-      if (ret != 0)
-       {
-         char errormsg[4*MAXERRORLENGTH+1];
-         waveOutGetErrorTextA(ret, errormsg, 4*MAXERRORLENGTH+1);
-         WRITELOG( WAVELOG(5), "waveOutWrite: %s", errormsg);
-       }
-    }
-    return BX_SOUND_OUTPUT_OK;
-}
-
-int bx_sound_windows_c::startwaveplayback(int frequency, int bits, int stereo, int format)
-{
-  // UINT ret;
-
-  WRITELOG( WAVELOG(4), "startwaveplayback(%d, %d, %d, %x)", frequency, bits, stereo, format);
-
-#ifdef usewaveOut
-  // check if any of the properties have changed
-  if ( (WaveInfo.frequency != frequency) ||
-       (WaveInfo.bits != bits) ||
-       (WaveInfo.stereo != stereo) ||
-       (WaveInfo.format != format) )
-    {
-      needreopen = 1;
-
-      // store the current settings to be used by sendwavepacket()
-      WaveInfo.frequency = frequency;
-      WaveInfo.bits = bits;
-      WaveInfo.stereo = stereo;
-      WaveInfo.format = format;
-    }
-#endif
-
-#ifdef usesndPlaySnd
-  int bps = (bits / 8) * (stereo + 1);
-  LPWAVEFILEHEADER header = (LPWAVEFILEHEADER) WaveData;
-
-  memcpy(header->RIFF, "RIFF", 4);
-  memcpy(header->TYPE, "WAVE", 4);
-  memcpy(header->chnk, "fmt ", 4);
-  header->chnklen = 16;
-  header->waveformat.wf.wFormatTag = WAVE_FORMAT_PCM;
-  header->waveformat.wf.nChannels = stereo + 1;
-  header->waveformat.wf.nSamplesPerSec = frequency;
-  header->waveformat.wf.nAvgBytesPerSec = frequency * bps;
-  header->waveformat.wf.nBlockAlign = bps;
-  header->waveformat.wBitsPerSample = bits;
-  memcpy(header->chnk2, "data", 4);
-#endif
-
-  return BX_SOUND_OUTPUT_OK;
-}
-
-int bx_sound_windows_c::sendwavepacket(int length, Bit8u data[])
-{
-//  UINT ret;
-  int bufnum;
-
-  WRITELOG( WAVELOG(4), "sendwavepacket(%d, %p)", length, data);
-
-#ifdef usewaveOut
-  bufnum = head;
-
-  memcpy(WaveData[bufnum], data, length);
-  this->length[bufnum] = length;
-
-  // select next buffer to write to
-  bufnum++;
-  bufnum &= BX_SOUND_WINDOWS_NMASK;
-
-  if ( ( (bufnum + 1) & BX_SOUND_WINDOWS_NMASK) == tailfull )
-    {   // this should not actually happen!
-      WRITELOG( WAVELOG(2), "Output buffer overflow! Not played. Iswaveready was %d", iswaveready);
-      iswaveready = 0;          // stop the output for a while
-      return BX_SOUND_OUTPUT_ERR;
-    }
-
-  head = bufnum;
-
-  // check if more buffers are available, otherwise stall the emulator
-  if ( ( (bufnum + 2) & BX_SOUND_WINDOWS_NMASK) == tailfull )
-    {
-      WRITELOG( WAVELOG(5), "Buffer status: Head %d, TailFull %d, TailPlay %d. Stall.",
-               head, tailfull, tailplay);
-      iswaveready = 0;
-    }
-
-  playnextbuffer();
-
-#endif
-
-#ifdef usesndPlaySnd
-  LPWAVEFILEHEADER header = (LPWAVEFILEHEADER) WaveData;
-
-  header->length = length + 36;
-  header->chnk2len = length;
-
-  memcpy( &(header->data), data, length);
-
-  FILE *test = fopen("test", "a");
-  fwrite(WaveData, 1, length + 44, test);
-  fclose(test);
-
-  ret = sndPlaySoundA( (LPCSTR) header, SND_SYNC | SND_MEMORY );
-  if (ret != 0)
-    {
-      WRITELOG( WAVELOG(3), "sndPlaySoundA: %d", ret);
-    }
-#endif
-
-  return BX_SOUND_OUTPUT_OK;
-}
-
-int bx_sound_windows_c::stopwaveplayback()
-{
-  WRITELOG( WAVELOG(4), "stopwaveplayback()");
-
-#ifdef usewaveOut
-  // this is handled by checkwaveready() when closing
-#endif
-
-#ifdef usesndPlaySnd
-  sndPlaySoundA( NULL, SND_ASYNC | SND_MEMORY );
-
-  WaveOpen = 0;
-#endif
-
-  return BX_SOUND_OUTPUT_OK;
-}
-
-int bx_sound_windows_c::closewaveoutput()
-{
-//  int bufnum;
-
-  WRITELOG( WAVELOG(4), "closewaveoutput");
-
-#ifdef usewaveOut
-  if (WaveOpen == 1)
-    {
-      waveOutReset(WaveOut);
-
-      // let checkwaveready() clean up the buffers
-      checkwaveready();
-
-      waveOutClose(WaveOut);
-
-      head = 0;
-      tailfull = 0;
-      tailplay = 0;
-      needreopen = 0;
-    }
-#endif
-
-  return BX_SOUND_OUTPUT_OK;
-}
-
-void bx_sound_windows_c::checkmidiready()
-{
-  UINT ret;
-
-  if ( (MidiHeader->dwFlags & WHDR_DONE) != 0)
-    {
-      WRITELOG( MIDILOG(5), "SYSEX message done, midi ready again.");
-      ret = midiOutUnprepareHeader( MidiOut, MidiHeader, sizeof(*MidiHeader));
-      ismidiready = 1;
-    }
-}
-void bx_sound_windows_c::checkwaveready()
-{
-  int bufnum;
-  UINT ret;
-
-  // clean up all finished buffers and mark them as available
-  for (bufnum=tailfull;
-       (bufnum != tailplay) &&
-         ( (WaveHeader[bufnum]->dwFlags & WHDR_DONE) != 0);
-       bufnum++, bufnum &= BX_SOUND_WINDOWS_NMASK)
-    {
-      WRITELOG( WAVELOG(5), "Buffer %d done.", bufnum);
-
-      ret = waveOutUnprepareHeader(WaveOut, WaveHeader[bufnum], sizeof(*WaveHeader[bufnum]));
-    }
-
-  tailfull = bufnum;
-
-  // enable gathering data if a buffer is available
-  if ( ( (head + 2) & BX_SOUND_WINDOWS_NMASK) != tailfull )
-    {
-      WRITELOG( WAVELOG(5), "Buffer status: Head %d, TailFull %d, TailPlay %d. Ready.",
-               head, tailfull, tailplay);
-      iswaveready = 1;
-    }
-}
-
-#endif // defined(WIN32)
diff --git a/tools/ioemu/iodev/soundwin.h b/tools/ioemu/iodev/soundwin.h
deleted file mode 100644 (file)
index 122fa55..0000000
+++ /dev/null
@@ -1,229 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: soundwin.h,v 1.3 2001/10/03 13:10:38 bdenney Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2001  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-// This file (SOUNDWIN.H) written and donated by Josef Drexler
-
-
-#if defined(WIN32)
-
-#include "bochs.h"
-#include <windows.h>
-
-// uncomment one of the following two #defines
-//#define usesndPlaySnd
-#define usewaveOut
-
-#define BX_SOUND_WINDOWS_MAXSYSEXLEN  256    // maximum supported length of a sysex message
-
-#define BX_SOUND_WINDOWS_NBUF  4   // number of buffers for the output, must be power of 2 and >= 4
-#define BX_SOUND_WINDOWS_NMASK (BX_SOUND_WINDOWS_NBUF - 1)
-
-#ifndef WAVEMAPPER
-#define WAVEMAPPER             -1
-#endif
-
-// Definitions for WINMM.DLL, if not defined already
-#ifndef MMSYSERR_NOERROR
-
-#pragma pack(1)
-
-typedef UINT HMIDIOUT;
-typedef        HMIDIOUT *LPHMIDIOUT;
-typedef struct midihdr_tag {
-    LPSTR lpData;
-    DWORD dwBufferLength;
-    DWORD dwBytesRecorded;
-    DWORD dwUser;
-    DWORD dwFlags;
-    struct midihdr_tag *lpNext;
-    DWORD reserved;
-} MIDIHDR, *LPMIDIHDR;
-
-typedef UINT HWAVEOUT;
-typedef HWAVEOUT *LPHWAVEOUT;
-
-typedef struct wavehdr_tag {
-    LPSTR lpData;
-    DWORD dwBufferLength;
-    DWORD dwBytesRecorded;
-    DWORD dwUser;
-    DWORD dwFlags;
-    DWORD dwLoops;
-    struct wavehdr_tag *lpNext;
-    DWORD reserved;
-} WAVEHDR, *LPWAVEHDR;
-
-#define WHDR_DONE         0x00000001
-#define WHDR_PREPARED     0x00000002
-#define WHDR_BEGINLOOP    0x00000004
-#define WHDR_ENDLOOP      0x00000008
-#define WHDR_INQUEUE      0x00000010
-
-
-typedef struct waveformat_tag {
-    WORD wFormatTag;
-    WORD nChannels;
-    DWORD nSamplesPerSec;
-    DWORD nAvgBytesPerSec;
-    WORD nBlockAlign;
-} WAVEFORMAT, *LPWAVEFORMAT;
-
-#define WAVE_FORMAT_PCM        1
-
-typedef struct pcmwaveformat_tag {
-    WAVEFORMAT wf;
-    WORD wBitsPerSample;
-} PCMWAVEFORMAT, *LPPCMWAVEFORMAT;
-
-#define MIDIMAPPER             -1
-
-#define CALLBACK_NULL          0x00000000
-#define CALLBACK_WINDOW                0x00010000
-#define CALLBACK_TASK          0x00020000
-#define CALLBACK_FUNCTION      0x00030000
-
-#define MMSYSERR_NOERROR       0
-#define MMSYSERR_ERROR         1
-#define MMSYSERR_BADDEVICEID   2
-#define MMSYSERR_NOTENABLED    3
-#define MMSYSERR_ALLOCATED      4
-#define MMSYSERR_INVALHANDLE   5
-#define MMSYSERR_NODRIVER      6
-#define MMSYSERR_NOMEM         7
-#define MMSYSERR_NOTSUPPORTED  8
-#define MMSYSERR_NOMAP         7
-
-#define MIDIERR_UNPREPARED      64
-#define MIDIERR_STILLPLAYING    65
-#define MIDIERR_NOTREADY       66
-#define MIDIERR_NODEVICE        67
-
-#define WAVERR_BADFORMAT        32
-#define WAVERR_STILLPLAYING     33
-#define WAVERR_UNPREPARED       34
-#define WAVERR_SYNC             35
-
-#define MAXERRORLENGTH         128
-
-extern "C" {
-UINT STDCALL midiOutOpen(LPHMIDIOUT, UINT, DWORD, DWORD, DWORD);
-UINT STDCALL midiOutShortMsg(HMIDIOUT, DWORD);
-UINT STDCALL midiOutLongMsg(HMIDIOUT, LPMIDIHDR, UINT);
-UINT STDCALL midiOutPrepareHeader(HMIDIOUT, LPMIDIHDR, UINT);
-UINT STDCALL midiOutUnprepareHeader(HMIDIOUT, LPMIDIHDR, UINT);
-UINT STDCALL midiOutReset(HMIDIOUT);
-UINT STDCALL midiOutClose(HMIDIOUT);
-
-UINT STDCALL waveOutOpen(LPHWAVEOUT, UINT, LPWAVEFORMAT, DWORD, DWORD, DWORD);
-UINT STDCALL waveOutWrite(HWAVEOUT, LPWAVEHDR, UINT);
-UINT STDCALL waveOutPrepareHeader(HWAVEOUT, LPWAVEHDR, UINT);
-UINT STDCALL waveOutUnprepareHeader(HWAVEOUT, LPWAVEHDR, UINT);
-UINT STDCALL waveOutReset(HWAVEOUT);
-UINT STDCALL waveOutClose(HWAVEOUT);
-
-UINT STDCALL waveOutGetErrorTextA(UINT, LPSTR, UINT);
-
-BOOL STDCALL sndPlaySoundA(LPCSTR, UINT);
-}
-
-typedef struct {
-  char RIFF[4];
-  Bit32u length;
-  char TYPE[4];
-  char chnk[4];
-  Bit32u chnklen;
-  PCMWAVEFORMAT waveformat;
-  char chnk2[4];
-  Bit32u chnk2len;
-  char data[1];
-} WAVEFILEHEADER, *LPWAVEFILEHEADER;
-#pragma pack(0)
-
-#endif  // MMSYSERR_NOERROR defined
-
-class bx_sound_windows_c : public bx_sound_output_c {
-public:
-  bx_sound_windows_c(bx_sb16_c *sb16);
-  BX_SOUND_VIRTUAL ~bx_sound_windows_c();
-
-  // if virtual functions are used, we have to override them
-  // and define our own. Otherwise this file will just implement
-  // the original functions
-#ifdef BX_USE_SOUND_VIRTUAL
-  BX_SOUND_VIRTUAL int    waveready();
-  BX_SOUND_VIRTUAL int    midiready();
-
-  BX_SOUND_VIRTUAL int    openmidioutput(char *device);
-  BX_SOUND_VIRTUAL int    sendmidicommand(int delta, int command, int length, Bit8u data[]);
-  BX_SOUND_VIRTUAL int    closemidioutput();
-
-  BX_SOUND_VIRTUAL int    openwaveoutput(char *device);
-  BX_SOUND_VIRTUAL int    startwaveplayback(int frequency, int bits, int stereo, int format);
-  BX_SOUND_VIRTUAL int    sendwavepacket(int length, Bit8u data[]);
-  BX_SOUND_VIRTUAL int    stopwaveplayback();
-  BX_SOUND_VIRTUAL int    closewaveoutput();
-#endif
-
-private:
-  bx_sb16_c *sb16;
-
-  struct bx_sb16_waveinfo_struct {
-    int frequency;
-    int bits;
-    int stereo;
-    int format;
-  };
-
-  HMIDIOUT MidiOut;       // Midi output device
-  int MidiOpen;           // is it open?
-  HWAVEOUT WaveOut;       // Wave output device
-  int WaveOpen;           // is it open?
-
-  UINT WaveDevice;        // Wave device ID, for waveOutOpen
-
-       // some data for the wave buffers
-  HANDLE DataHandle;          // returned by GlobalAlloc()
-  Bit8u *DataPointer;         // returned by GlobalLock()
-
-  LPWAVEHDR WaveHeader[BX_SOUND_WINDOWS_NBUF];
-  LPSTR WaveData[BX_SOUND_WINDOWS_NBUF];
-  int length[BX_SOUND_WINDOWS_NBUF];                // length of the data in the buffer
-  int needreopen;                                   // if the format has changed
-  int head,tailfull,tailplay;       // These are for three states of the buffers: empty, full, played
-  bx_sb16_waveinfo_struct WaveInfo;                 // format for the next buffer to be played
-  int iswaveready;
-
-       // and the midi buffer for the SYSEX messages
-  LPMIDIHDR MidiHeader;
-  LPSTR MidiData;
-  int ismidiready;
-
-  int playnextbuffer();
-  void checkmidiready();
-  void checkwaveready();
-};
-
-#endif  // defined(WIN32)
diff --git a/tools/ioemu/iodev/state_file.cc b/tools/ioemu/iodev/state_file.cc
deleted file mode 100644 (file)
index f7d0d0f..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: state_file.cc,v 1.9 2001/12/21 19:33:18 bdenney Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2001  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-
-// Classes for helping to make checkpoints of the emulator state.
-
-
-
-#include "bochs.h"
-#define LOG_THIS log->
-
-
-
-FILE *state_file::get_handle()
-{
-  BX_INFO(("state_file::get_handle()"));
-  return NULL;
-}
-       
-void state_file::write(Bit8u)
-{
-  BX_PANIC(("state_file::write(Bit8u)"));
-}
-
-void state_file::write(Bit16u)
-{
-  BX_PANIC(("state_file::write(Bit16u)"));
-}
-
-void state_file::write(Bit32u)
-{
-  BX_PANIC(("state_file::write(Bit32u)"));
-}
-
-void state_file::write(Bit64u)
-{
-  BX_PANIC(("state_file::write(Bit64u)"));
-}
-
-void state_file::write(const void *, size_t)
-{
-  BX_PANIC(("state_file::write(const void *, size_t)"));
-}
-
-void state_file::read(Bit8u &)
-{
-  BX_PANIC(("state_file::read(uint8 &)"));
-}
-
-void state_file::read(Bit16u &)
-{
-  BX_PANIC(("state_file::read(uint16 &)"));
-}
-
-void state_file::read(Bit32u &)
-{
-  BX_PANIC(("state_file::read(uint32 &)"));
-}
-
-void state_file::read(Bit64u &)
-{
-  BX_PANIC(("state_file::read(uint64 &)"));
-}
-
-void state_file::read(void *, size_t)
-{
-  BX_PANIC(("state_file::read(void *, size_t)"));
-}
-
-void state_file::write_check(const char *)
-{
-  BX_PANIC(("state_file::write_check()"));
-}
-
-void state_file::read_check (const char *)
-{
-  BX_PANIC(("state_file::read_check()"));
-}
-
-void
-state_file::init(void)
-{
-       log = new class logfunctions();
-       log->put("STAT");
-       log->settype(GENLOG);
-}
-
-
-state_file::state_file (const char *name, const char *options)
-{
-  UNUSED(name);
-  UNUSED(options);
-  init();
-  BX_DEBUG(( "Init(const char *, const char *)." ));
-}
-
-state_file::state_file (FILE *f)
-{
-  UNUSED(f);
-  init();
-  BX_INFO(("Init(FILE *)."));
-}
-
-state_file::~state_file()
-{
-  BX_DEBUG(("Exit."));
-  if ( log != NULL )
-  {
-        delete log;
-        log = NULL;
-  }
-}
diff --git a/tools/ioemu/iodev/unmapped.cc b/tools/ioemu/iodev/unmapped.cc
deleted file mode 100644 (file)
index 5c7aafe..0000000
+++ /dev/null
@@ -1,305 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: unmapped.cc,v 1.22 2003/08/10 17:19:49 akrisak Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2001  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-
-// Define BX_PLUGGABLE in files that can be compiled into plugins.  For
-// platforms that require a special tag on exported symbols, BX_PLUGGABLE 
-// is used to know when we are exporting symbols and when we are importing.
-#define BX_PLUGGABLE
-
-#include "bochs.h"
-
-#define LOG_THIS theUnmappedDevice->
-
-
-bx_unmapped_c *theUnmappedDevice = NULL;
-
-  int
-libunmapped_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
-{
-  theUnmappedDevice = new bx_unmapped_c ();
-  bx_devices.pluginUnmapped = theUnmappedDevice;
-  BX_REGISTER_DEVICE_DEVMODEL(plugin, type, theUnmappedDevice, BX_PLUGIN_UNMAPPED);
-  return(0); // Success
-}
-
-  void
-libunmapped_LTX_plugin_fini(void)
-{
-}
-
-bx_unmapped_c::bx_unmapped_c(void)
-{
-  put("UNMP");
-  settype(UNMAPLOG);
-  s.port80 = 0x00;
-  s.port8e = 0x00;
-  s.shutdown = 0;
-}
-
-bx_unmapped_c::~bx_unmapped_c(void)
-{
-  // Nothing yet
-}
-
-  void
-bx_unmapped_c::init(void)
-{
-  DEV_register_default_ioread_handler(this, read_handler, "Unmapped", 7);
-  DEV_register_default_iowrite_handler(this, write_handler, "Unmapped", 7);
-}
-
-  void
-bx_unmapped_c::reset(unsigned type)
-{
-}
-
-  // static IO port read callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-  Bit32u
-bx_unmapped_c::read_handler(void *this_ptr, Bit32u address, unsigned io_len)
-{
-#if !BX_USE_UM_SMF
-  bx_unmapped_c *class_ptr = (bx_unmapped_c *) this_ptr;
-
-  return( class_ptr->read(address, io_len) );
-}
-
-  Bit32u
-bx_unmapped_c::read(Bit32u address, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif  // !BX_USE_UM_SMF
-  UNUSED(io_len);
-
-  Bit32u retval;
-
-  // This function gets called for access to any IO ports which
-  // are not mapped to any device handler.  Reads return 0
-
-  if (address >= 0x02e0 && address <= 0x02ef) {
-       retval = 0;
-       goto return_from_read;
-  }
-
-  switch (address) {
-    case 0x80:
-         retval = BX_UM_THIS s.port80;
-         break;
-    case 0x8e:
-         retval = BX_UM_THIS s.port8e;
-         break;
-#if BX_PORT_E9_HACK
-    // Unused port on ISA - this can be used by the emulated code
-    // to detect it is running inside Bochs and that the debugging
-    // features are available (write 0xFF or something on unused
-    // port 0x80, then read from 0xe9, if value is 0xe9, debug
-    // output is available) (see write() for that) -- Andreas and Emmanuel
-    case 0xe9:
-         retval = 0xe9;
-         break;
-#endif
-    case 0x03df:
-         retval = 0xffffffff;
-      BX_DEBUG(("unsupported IO read from port %04x (CGA)", address));
-      break;
-    case 0x023a:
-    case 0x02f8: /* UART */
-    case 0x02f9: /* UART */
-    case 0x02fb: /* UART */
-    case 0x02fc: /* UART */
-    case 0x02fd: /* UART */
-    case 0x02ea:
-    case 0x02eb:
-    case 0x03e8:
-    case 0x03e9:
-    case 0x03ea:
-    case 0x03eb:
-    case 0x03ec:
-    case 0x03ed:
-    case 0x03f8: /* UART */
-    case 0x03f9: /* UART */
-    case 0x03fb: /* UART */
-    case 0x03fc: /* UART */
-    case 0x03fd: /* UART */
-    case 0x17c6:
-         retval = 0xffffffff;
-      BX_DEBUG(("unsupported IO read from port %04x", address));
-      break;
-    default:
-         retval = 0xffffffff;
-    }
-
-  return_from_read:
-  if (bx_dbg.unsupported_io)
-         switch (io_len) {
-         case 1:
-                 retval = (Bit8u)retval;
-                 BX_DEBUG(("unmapped: 8-bit read from %04x = %02x", address, retval));
-                 break;
-         case 2:
-                 retval = (Bit16u)retval;
-                 BX_DEBUG(("unmapped: 16-bit read from %04x = %04x", address, retval));
-                 break;
-         case 4:
-                 BX_DEBUG(("unmapped: 32-bit read from %04x = %08x", address, retval));
-                 break;
-         default:
-                 BX_DEBUG(("unmapped: %d-bit read from %04x = %x", io_len * 8, address, retval));
-         }
-  return retval;
-}
-
-
-  // static IO port write callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-  void
-bx_unmapped_c::write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len)
-{
-#if !BX_USE_UM_SMF
-  bx_unmapped_c *class_ptr = (bx_unmapped_c *) this_ptr;
-
-  class_ptr->write(address, value, io_len);
-}
-
-  void
-bx_unmapped_c::write(Bit32u address, Bit32u value, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif  // !BX_USE_UM_SMF
-  UNUSED(io_len);
-
-
-  // This function gets called for access to any IO ports which
-  // are not mapped to any device handler.  Writes to an unmapped
-  // IO port are ignored.
-
-// ???
-
-  if (address >= 0x02e0 && address <= 0x02ef)
-       goto return_from_write;
-
-  switch (address) {
-    case 0x80: // diagnostic test port to display progress of POST
-      //BX_DEBUG(("Diagnostic port 80h: write = %02xh", (unsigned) value));
-      BX_UM_THIS s.port80 = value;
-      break;
-
-    case 0x8e: // ???
-      BX_UM_THIS s.port8e = value;
-      break;
-
-#if BX_PORT_E9_HACK
-    // This port doesn't exist on normal ISA architecture. However,
-    // we define a convention here, to display on the console of the
-    // system running Bochs, anything that is written to it. The
-    // idea is to provide debug output very early when writing
-    // BIOS or OS code for example, without having to bother with
-    // properly setting up a serial port or anything.
-    //
-    // Idea by Andreas Beck (andreas.beck@ggi-project.org)
-
-    case 0xe9:
-      putchar(value);
-      fflush(stdout);
-      break;
-#endif
-
-    case 0xed: // Dummy port used as I/O delay
-         break;
-    case 0xee: // ???
-         break;
-
-    case 0x2f2:
-    case 0x2f3:
-    case 0x2f4:
-    case 0x2f5:
-    case 0x2f6:
-    case 0x2f7:
-    case 0x3e8:
-    case 0x3e9:
-    case 0x3eb:
-    case 0x3ec:
-    case 0x3ed:
-           // BX_DEBUG(("unsupported IO write to port %04x of %02x",
-           // address, value));
-      break;
-    
-    case 0x8900: // Shutdown port, could be moved in a PM device
-                 // or a host <-> guest communication device 
-      switch (value) {
-        case 'S': if (BX_UM_THIS s.shutdown == 0) BX_UM_THIS s.shutdown = 1; break;
-        case 'h': if (BX_UM_THIS s.shutdown == 1) BX_UM_THIS s.shutdown = 2; break;
-        case 'u': if (BX_UM_THIS s.shutdown == 2) BX_UM_THIS s.shutdown = 3; break;
-        case 't': if (BX_UM_THIS s.shutdown == 3) BX_UM_THIS s.shutdown = 4; break;
-        case 'd': if (BX_UM_THIS s.shutdown == 4) BX_UM_THIS s.shutdown = 5; break;
-        case 'o': if (BX_UM_THIS s.shutdown == 5) BX_UM_THIS s.shutdown = 6; break;
-        case 'w': if (BX_UM_THIS s.shutdown == 6) BX_UM_THIS s.shutdown = 7; break;
-        case 'n': if (BX_UM_THIS s.shutdown == 7) BX_UM_THIS s.shutdown = 8; break;
-#if BX_DEBUGGER 
-        // Very handy for debugging:
-       // output 'D' to port 8900, and bochs quits to debugger
-        case 'D': bx_debug_break (); break;
-#endif
-       default :  BX_UM_THIS s.shutdown = 0; break;
-        }
-      if (BX_UM_THIS s.shutdown == 8) {
-        bx_user_quit = 1;
-        LOG_THIS setonoff(LOGLEV_PANIC, ACT_FATAL);
-        BX_PANIC(("Shutdown port: shutdown requested"));
-        }
-      break;
-
-    case 0xfedc:
-      bx_dbg.debugger = (value > 0);
-               BX_DEBUG(( "DEBUGGER = %u", (unsigned) bx_dbg.debugger));
-      break;
-
-    default:
-           break;
-    }
-  return_from_write:
-  if (bx_dbg.unsupported_io)
-         switch (io_len) {
-         case 1:
-                 BX_INFO(("unmapped: 8-bit write to %04x = %02x", address, value));
-                 break;
-         case 2:
-                 BX_INFO(("unmapped: 16-bit write to %04x = %04x", address, value));
-                 break;
-         case 4:
-                 BX_INFO(("unmapped: 32-bit write to %04x = %08x", address, value));
-                 break;
-         default:
-                 BX_INFO(("unmapped: %d-bit write to %04x = %x", io_len * 8, address, value));
-                 break;
-         }
-}
diff --git a/tools/ioemu/iodev/unmapped.h b/tools/ioemu/iodev/unmapped.h
deleted file mode 100644 (file)
index c9ef1dc..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: unmapped.h,v 1.10 2002/10/24 21:07:52 bdenney Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2001  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-
-
-#if BX_USE_UM_SMF
-#  define BX_UM_SMF  static
-#  define BX_UM_THIS theUnmappedDevice->
-#else
-#  define BX_UM_SMF
-#  define BX_UM_THIS this->
-#endif
-
-
-
-class bx_unmapped_c : public bx_devmodel_c {
-public:
-  bx_unmapped_c(void);
-  ~bx_unmapped_c(void);
-
-  virtual void init(void);
-  virtual void reset (unsigned type);
-
-private:
-
-  static Bit32u read_handler(void *this_ptr, Bit32u address, unsigned io_len);
-  static void   write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);
-#if !BX_USE_UM_SMF
-  Bit32u read(Bit32u address, unsigned io_len);
-  void   write(Bit32u address, Bit32u value, unsigned io_len);
-#endif
-
-
-  struct {
-    Bit8u port80;
-    Bit8u port8e;
-    Bit8u shutdown;
-    } s;  // state information
-
-  };
diff --git a/tools/ioemu/iodev/vga.cc b/tools/ioemu/iodev/vga.cc
deleted file mode 100644 (file)
index 894f80b..0000000
+++ /dev/null
@@ -1,3116 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: vga.cc,v 1.94.2.1 2004/02/02 22:37:48 cbothamy Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-// Define BX_PLUGGABLE in files that can be compiled into plugins.  For
-// platforms that require a special tag on exported symbols, BX_PLUGGABLE 
-// is used to know when we are exporting symbols and when we are importing.
-#define BX_PLUGGABLE
-
-#include "bochs.h"
-
-#define LOG_THIS theVga->
-
-/* NOTES:
- * I take it data rotate is a true rotate with carry of bit 0 to bit 7.
- * support map mask (3c5 reg 02)
- */
-
-/* Notes from cb
- *
- * It seems that the vga card should support multi bytes IO reads and write
- * From my tests, inw(port) return port+1 * 256 + port, except for port 0x3c9
- * (PEL data register, data cycling). More reverse engineering is needed.
- * This would fix the gentoo bug.
- */
-
-// (mch)
-#define VGA_TRACE_FEATURE
-
-// Only reference the array if the tile numbers are within the bounds
-// of the array.  If out of bounds, do nothing.
-#define SET_TILE_UPDATED(xtile,ytile,value)                              \
-  do {                                                                   \
-    if (((xtile) < BX_NUM_X_TILES) && ((ytile) < BX_NUM_Y_TILES))        \
-      BX_VGA_THIS s.vga_tile_updated[(xtile)][(ytile)] = value;          \
-  } while (0)
-
-// Only reference the array if the tile numbers are within the bounds
-// of the array.  If out of bounds, return 0.
-#define GET_TILE_UPDATED(xtile,ytile)                                    \
-  ((((xtile) < BX_NUM_X_TILES) && ((ytile) < BX_NUM_Y_TILES))?           \
-     BX_VGA_THIS s.vga_tile_updated[(xtile)][(ytile)]                    \
-     : 0)
-
-static const Bit8u ccdat[16][4] = {
-  { 0x00, 0x00, 0x00, 0x00 },
-  { 0xff, 0x00, 0x00, 0x00 },
-  { 0x00, 0xff, 0x00, 0x00 },
-  { 0xff, 0xff, 0x00, 0x00 },
-  { 0x00, 0x00, 0xff, 0x00 },
-  { 0xff, 0x00, 0xff, 0x00 },
-  { 0x00, 0xff, 0xff, 0x00 },
-  { 0xff, 0xff, 0xff, 0x00 },
-  { 0x00, 0x00, 0x00, 0xff },
-  { 0xff, 0x00, 0x00, 0xff },
-  { 0x00, 0xff, 0x00, 0xff },
-  { 0xff, 0xff, 0x00, 0xff },
-  { 0x00, 0x00, 0xff, 0xff },
-  { 0xff, 0x00, 0xff, 0xff },
-  { 0x00, 0xff, 0xff, 0xff },
-  { 0xff, 0xff, 0xff, 0xff },
-};
-
-bx_vga_c *theVga = NULL;
-
-unsigned old_iHeight = 0, old_iWidth = 0, old_MSL = 0, old_BPP = 0;
-
-  int
-libvga_LTX_plugin_init(plugin_t *plugin, plugintype_t type, int argc, char *argv[])
-{
-  theVga = new bx_vga_c ();
-  bx_devices.pluginVgaDevice = theVga;
-  BX_REGISTER_DEVICE_DEVMODEL(plugin, type, theVga, BX_PLUGIN_VGA);
-  return(0); // Success
-}
-
-  void
-libvga_LTX_plugin_fini(void)
-{
-}
-
-bx_vga_c::bx_vga_c(void)
-{
-  put("VGA");
-  s.vga_mem_updated = 0;
-  s.x_tilesize = X_TILESIZE;
-  s.y_tilesize = Y_TILESIZE;
-  timer_id = BX_NULL_TIMER_HANDLE;
-}
-
-
-bx_vga_c::~bx_vga_c(void)
-{
-  // nothing for now
-}
-
-
-  void
-bx_vga_c::init(void)
-{
-  unsigned i;
-  unsigned x,y;
-
-  unsigned addr;
-  for (addr=0x03B4; addr<=0x03B5; addr++) {
-    DEV_register_ioread_handler(this, read_handler, addr, "vga video", 1);
-    DEV_register_iowrite_handler(this, write_handler, addr, "vga video", 3);
-    }
-
-  for (addr=0x03BA; addr<=0x03BA; addr++) {
-    DEV_register_ioread_handler(this, read_handler, addr, "vga video", 1);
-    DEV_register_iowrite_handler(this, write_handler, addr, "vga video", 3);
-    }
-
-  for (addr=0x03C0; addr<=0x03CF; addr++) {
-    DEV_register_ioread_handler(this, read_handler, addr, "vga video", 1);
-    DEV_register_iowrite_handler(this, write_handler, addr, "vga video", 3);
-    }
-
-  for (addr=0x03D4; addr<=0x03D5; addr++) {
-    DEV_register_ioread_handler(this, read_handler, addr, "vga video", 1);
-    DEV_register_iowrite_handler(this, write_handler, addr, "vga video", 3);
-    }
-
-  for (addr=0x03DA; addr<=0x03DA; addr++) {
-    DEV_register_ioread_handler(this, read_handler, addr, "vga video", 1);
-    DEV_register_iowrite_handler(this, write_handler, addr, "vga video", 3);
-    }
-
-
-  BX_VGA_THIS s.misc_output.color_emulation  = 1;
-  BX_VGA_THIS s.misc_output.enable_ram  = 1;
-  BX_VGA_THIS s.misc_output.clock_select     = 0;
-  BX_VGA_THIS s.misc_output.select_high_bank = 0;
-  BX_VGA_THIS s.misc_output.horiz_sync_pol   = 1;
-  BX_VGA_THIS s.misc_output.vert_sync_pol    = 1;
-
-  BX_VGA_THIS s.attribute_ctrl.mode_ctrl.graphics_alpha = 0;
-  BX_VGA_THIS s.attribute_ctrl.mode_ctrl.display_type = 0;
-  BX_VGA_THIS s.attribute_ctrl.mode_ctrl.enable_line_graphics = 1;
-  BX_VGA_THIS s.attribute_ctrl.mode_ctrl.blink_intensity = 0;
-  BX_VGA_THIS s.attribute_ctrl.mode_ctrl.pixel_panning_compat = 0;
-  BX_VGA_THIS s.attribute_ctrl.mode_ctrl.pixel_clock_select = 0;
-  BX_VGA_THIS s.attribute_ctrl.mode_ctrl.internal_palette_size = 0;
-
-  BX_VGA_THIS s.line_offset=80;
-  BX_VGA_THIS s.line_compare=1023;
-  BX_VGA_THIS s.vertical_display_end=399;
-
-  for (i=0; i<=0x18; i++)
-    BX_VGA_THIS s.CRTC.reg[i] = 0;
-  BX_VGA_THIS s.CRTC.address = 0;
-
-  BX_VGA_THIS s.attribute_ctrl.flip_flop = 0;
-  BX_VGA_THIS s.attribute_ctrl.address = 0;
-  BX_VGA_THIS s.attribute_ctrl.video_enabled = 1;
-  for (i=0; i<16; i++)
-    BX_VGA_THIS s.attribute_ctrl.palette_reg[i] = 0;
-  BX_VGA_THIS s.attribute_ctrl.overscan_color = 0;
-  BX_VGA_THIS s.attribute_ctrl.color_plane_enable = 0x0f;
-  BX_VGA_THIS s.attribute_ctrl.horiz_pel_panning = 0;
-  BX_VGA_THIS s.attribute_ctrl.color_select = 0;
-
-  for (i=0; i<256; i++) {
-    BX_VGA_THIS s.pel.data[i].red = 0;
-    BX_VGA_THIS s.pel.data[i].green = 0;
-    BX_VGA_THIS s.pel.data[i].blue = 0;
-    }
-  BX_VGA_THIS s.pel.write_data_register = 0;
-  BX_VGA_THIS s.pel.write_data_cycle = 0;
-  BX_VGA_THIS s.pel.read_data_register = 0;
-  BX_VGA_THIS s.pel.read_data_cycle = 0;
-  BX_VGA_THIS s.pel.dac_state = 0x01;
-  BX_VGA_THIS s.pel.mask = 0xff;
-
-  BX_VGA_THIS s.graphics_ctrl.index = 0;
-  BX_VGA_THIS s.graphics_ctrl.set_reset = 0;
-  BX_VGA_THIS s.graphics_ctrl.enable_set_reset = 0;
-  BX_VGA_THIS s.graphics_ctrl.color_compare = 0;
-  BX_VGA_THIS s.graphics_ctrl.data_rotate = 0;
-  BX_VGA_THIS s.graphics_ctrl.raster_op    = 0;
-  BX_VGA_THIS s.graphics_ctrl.read_map_select = 0;
-  BX_VGA_THIS s.graphics_ctrl.write_mode = 0;
-  BX_VGA_THIS s.graphics_ctrl.read_mode  = 0;
-  BX_VGA_THIS s.graphics_ctrl.odd_even = 0;
-  BX_VGA_THIS s.graphics_ctrl.chain_odd_even = 0;
-  BX_VGA_THIS s.graphics_ctrl.shift_reg = 0;
-  BX_VGA_THIS s.graphics_ctrl.graphics_alpha = 0;
-  BX_VGA_THIS s.graphics_ctrl.memory_mapping = 2; // monochrome text mode
-  BX_VGA_THIS s.graphics_ctrl.color_dont_care = 0;
-  BX_VGA_THIS s.graphics_ctrl.bitmask = 0;
-  for (i=0; i<4; i++) {
-    BX_VGA_THIS s.graphics_ctrl.latch[i] = 0;
-    }
-
-  BX_VGA_THIS s.sequencer.index = 0;
-  BX_VGA_THIS s.sequencer.map_mask = 0;
-  for (i=0; i<4; i++) {
-    BX_VGA_THIS s.sequencer.map_mask_bit[i] = 0;
-    }
-  BX_VGA_THIS s.sequencer.reset1 = 1;
-  BX_VGA_THIS s.sequencer.reset2 = 1;
-  BX_VGA_THIS s.sequencer.reg1 = 0;
-  BX_VGA_THIS s.sequencer.char_map_select = 0;
-  BX_VGA_THIS s.sequencer.extended_mem = 1; // display mem greater than 64K
-  BX_VGA_THIS s.sequencer.odd_even = 1; // use sequential addressing mode
-  BX_VGA_THIS s.sequencer.chain_four = 0; // use map mask & read map select
-
-  memset(BX_VGA_THIS s.vga_memory, 0, sizeof(BX_VGA_THIS s.vga_memory));
-
-  BX_VGA_THIS s.vga_mem_updated = 0;
-  for (y=0; y<480/Y_TILESIZE; y++)
-    for (x=0; x<640/X_TILESIZE; x++)
-      SET_TILE_UPDATED (x, y, 0);
-
-  {
-  /* ??? should redo this to pass X args */
-  char *argv[1] = { "bochs" };
-  bx_gui->init(1, &argv[0], BX_VGA_THIS s.x_tilesize, BX_VGA_THIS s.y_tilesize);
-  }
-
-  BX_INFO(("interval=%u", bx_options.Ovga_update_interval->get ()));
-  if (BX_VGA_THIS timer_id == BX_NULL_TIMER_HANDLE) {
-    BX_VGA_THIS timer_id = bx_pc_system.register_timer(this, timer_handler,
-       bx_options.Ovga_update_interval->get (), 1, 1, "vga");
-  }
-
-  /* video card with BIOS ROM */
-  DEV_cmos_set_reg(0x14, (DEV_cmos_get_reg(0x14) & 0xcf) | 0x00); 
-
-  BX_VGA_THIS s.charmap_address = 0;
-  BX_VGA_THIS s.x_dotclockdiv2 = 0;
-  BX_VGA_THIS s.y_doublescan = 0;
-
-#if BX_SUPPORT_VBE  
-  // The following is for the vbe display extension
-  
-  for (addr=VBE_DISPI_IOPORT_INDEX; addr<=VBE_DISPI_IOPORT_DATA; addr++) {
-    DEV_register_ioread_handler(this, vbe_read_handler, addr, "vga video", 7);
-    DEV_register_iowrite_handler(this, vbe_write_handler, addr, "vga video", 7);
-  }    
-#if !BX_PCI_USB_SUPPORT
-  for (addr=VBE_DISPI_IOPORT_INDEX_OLD; addr<=VBE_DISPI_IOPORT_DATA_OLD; addr++) {
-    DEV_register_ioread_handler(this, vbe_read_handler, addr, "vga video", 7);
-    DEV_register_iowrite_handler(this, vbe_write_handler, addr, "vga video", 7);
-  }    
-#endif
-  BX_VGA_THIS s.vbe_cur_dispi=VBE_DISPI_ID0;
-  BX_VGA_THIS s.vbe_xres=640;
-  BX_VGA_THIS s.vbe_yres=480;
-  BX_VGA_THIS s.vbe_bpp=8;
-  BX_VGA_THIS s.vbe_bank=0;
-  BX_VGA_THIS s.vbe_enabled=0;
-  BX_VGA_THIS s.vbe_curindex=0;
-  BX_VGA_THIS s.vbe_offset_x=0;
-  BX_VGA_THIS s.vbe_offset_y=0;
-  BX_VGA_THIS s.vbe_virtual_xres=640;
-  BX_VGA_THIS s.vbe_virtual_yres=480;
-  BX_VGA_THIS s.vbe_bpp_multiplier=1;
-  BX_VGA_THIS s.vbe_virtual_start=0;
-  BX_VGA_THIS s.vbe_line_byte_width=640;
-  BX_VGA_THIS s.vbe_lfb_enabled=0;
-
-  
-  BX_INFO(("VBE Bochs Display Extension Enabled"));
-#endif  
-  bios_init();
-}
-
-  void
-bx_vga_c::bios_init()
-{
-  int i;
-  
-  BX_VGA_THIS s.misc_output.color_emulation = 1;
-  BX_VGA_THIS s.misc_output.enable_ram = 1;
-  BX_VGA_THIS s.misc_output.clock_select = 1;
-  BX_VGA_THIS s.misc_output.select_high_bank = 1;
-  BX_VGA_THIS s.misc_output.horiz_sync_pol = 1;
-  BX_VGA_THIS s.misc_output.vert_sync_pol = 0;
-  BX_VGA_THIS s.CRTC.address = 15;
-  BX_VGA_THIS s.CRTC.reg[0] = 95;
-  BX_VGA_THIS s.CRTC.reg[1] = 79;
-  BX_VGA_THIS s.CRTC.reg[2] = 80;
-  BX_VGA_THIS s.CRTC.reg[3] = 130;
-  BX_VGA_THIS s.CRTC.reg[4] = 85;
-  BX_VGA_THIS s.CRTC.reg[5] = 129;
-  BX_VGA_THIS s.CRTC.reg[6] = 191;
-  BX_VGA_THIS s.CRTC.reg[7] = 31;
-  BX_VGA_THIS s.CRTC.reg[8] = 0;
-  BX_VGA_THIS s.CRTC.reg[9] = 79;
-  BX_VGA_THIS s.CRTC.reg[10] = 14;
-  BX_VGA_THIS s.CRTC.reg[11] = 15;
-  BX_VGA_THIS s.CRTC.reg[12] = 0;
-  BX_VGA_THIS s.CRTC.reg[13] = 0;
-  BX_VGA_THIS s.CRTC.reg[14] = 5;
-  BX_VGA_THIS s.CRTC.reg[15] = 160;
-  BX_VGA_THIS s.CRTC.reg[16] = 156;
-  BX_VGA_THIS s.CRTC.reg[17] = 142;
-  BX_VGA_THIS s.CRTC.reg[18] = 143;
-  BX_VGA_THIS s.CRTC.reg[19] = 40;
-  BX_VGA_THIS s.CRTC.reg[20] = 31;
-  BX_VGA_THIS s.CRTC.reg[21] = 150;
-  BX_VGA_THIS s.CRTC.reg[22] = 185;
-  BX_VGA_THIS s.CRTC.reg[23] = 163;
-  BX_VGA_THIS s.CRTC.reg[24] = 255;
-  BX_VGA_THIS s.attribute_ctrl.flip_flop = 1;
-  BX_VGA_THIS s.attribute_ctrl.address = 0;
-  BX_VGA_THIS s.attribute_ctrl.video_enabled = 1;
-  BX_VGA_THIS s.attribute_ctrl.palette_reg[0] = 0;
-  BX_VGA_THIS s.attribute_ctrl.palette_reg[1] = 1;
-  BX_VGA_THIS s.attribute_ctrl.palette_reg[2] = 2;
-  BX_VGA_THIS s.attribute_ctrl.palette_reg[3] = 3;
-  BX_VGA_THIS s.attribute_ctrl.palette_reg[4] = 4;
-  BX_VGA_THIS s.attribute_ctrl.palette_reg[5] = 5;
-  BX_VGA_THIS s.attribute_ctrl.palette_reg[6] = 6;
-  BX_VGA_THIS s.attribute_ctrl.palette_reg[7] = 7;
-  BX_VGA_THIS s.attribute_ctrl.palette_reg[8] = 8;
-  BX_VGA_THIS s.attribute_ctrl.palette_reg[9] = 9;
-  BX_VGA_THIS s.attribute_ctrl.palette_reg[10] = 10;
-  BX_VGA_THIS s.attribute_ctrl.palette_reg[11] = 11;
-  BX_VGA_THIS s.attribute_ctrl.palette_reg[12] = 12;
-  BX_VGA_THIS s.attribute_ctrl.palette_reg[13] = 13;
-  BX_VGA_THIS s.attribute_ctrl.palette_reg[14] = 14;
-  BX_VGA_THIS s.attribute_ctrl.palette_reg[15] = 15;
-  BX_VGA_THIS s.attribute_ctrl.overscan_color = 0;
-  BX_VGA_THIS s.attribute_ctrl.color_plane_enable = 15;
-  BX_VGA_THIS s.attribute_ctrl.horiz_pel_panning = 8;
-  BX_VGA_THIS s.attribute_ctrl.color_select = 0;
-  BX_VGA_THIS s.attribute_ctrl.mode_ctrl.graphics_alpha = 0;
-  BX_VGA_THIS s.attribute_ctrl.mode_ctrl.display_type = 0;
-  BX_VGA_THIS s.attribute_ctrl.mode_ctrl.enable_line_graphics = 1;
-  BX_VGA_THIS s.attribute_ctrl.mode_ctrl.blink_intensity = 1;
-  BX_VGA_THIS s.attribute_ctrl.mode_ctrl.pixel_panning_compat = 0;
-  BX_VGA_THIS s.attribute_ctrl.mode_ctrl.pixel_clock_select = 0;
-  BX_VGA_THIS s.attribute_ctrl.mode_ctrl.internal_palette_size = 0;
-  BX_VGA_THIS s.pel.write_data_register = 16;
-  BX_VGA_THIS s.pel.write_data_cycle = 0;
-  BX_VGA_THIS s.pel.read_data_register = 0;
-  BX_VGA_THIS s.pel.read_data_cycle = 0;
-  BX_VGA_THIS s.pel.dac_state = 0;
-  memset((BX_VGA_THIS s.pel.data), 0, 256);
-  BX_VGA_THIS s.pel.data[0].red = 0;
-  BX_VGA_THIS s.pel.data[0].green = 0;
-  BX_VGA_THIS s.pel.data[0].blue = 0;
-  BX_VGA_THIS s.pel.mask = 255;
-  BX_VGA_THIS s.graphics_ctrl.index = 6;
-  BX_VGA_THIS s.graphics_ctrl.set_reset = 0;
-  BX_VGA_THIS s.graphics_ctrl.enable_set_reset = 0;
-  BX_VGA_THIS s.graphics_ctrl.color_compare = 0;
-  BX_VGA_THIS s.graphics_ctrl.data_rotate = 0;
-  BX_VGA_THIS s.graphics_ctrl.raster_op = 0;
-  BX_VGA_THIS s.graphics_ctrl.read_map_select = 0;
-  BX_VGA_THIS s.graphics_ctrl.write_mode = 0;
-  BX_VGA_THIS s.graphics_ctrl.read_mode = 0;
-  BX_VGA_THIS s.graphics_ctrl.odd_even = 1;
-  BX_VGA_THIS s.graphics_ctrl.chain_odd_even = 1;
-  BX_VGA_THIS s.graphics_ctrl.shift_reg = 0;
-  BX_VGA_THIS s.graphics_ctrl.graphics_alpha = 0;
-  BX_VGA_THIS s.graphics_ctrl.memory_mapping = 3;
-  BX_VGA_THIS s.graphics_ctrl.color_dont_care = 15;
-  BX_VGA_THIS s.graphics_ctrl.bitmask = 255;
-  BX_VGA_THIS s.graphics_ctrl.latch[0] = 0;
-  BX_VGA_THIS s.graphics_ctrl.latch[1] = 0;
-  BX_VGA_THIS s.graphics_ctrl.latch[2] = 0;
-  BX_VGA_THIS s.graphics_ctrl.latch[3] = 0;
-  BX_VGA_THIS s.sequencer.index = 3;
-  BX_VGA_THIS s.sequencer.map_mask = 3;
-  BX_VGA_THIS s.sequencer.map_mask_bit[0] = 1;
-  BX_VGA_THIS s.sequencer.map_mask_bit[1] = 1;
-  BX_VGA_THIS s.sequencer.map_mask_bit[2] = 0;
-  BX_VGA_THIS s.sequencer.map_mask_bit[3] = 0;
-  BX_VGA_THIS s.sequencer.reset1 = 1;
-  BX_VGA_THIS s.sequencer.reset2 = 1;
-  BX_VGA_THIS s.sequencer.reg1 = 0;
-  BX_VGA_THIS s.sequencer.char_map_select = 0;
-  BX_VGA_THIS s.sequencer.extended_mem = 1;
-  BX_VGA_THIS s.sequencer.odd_even = 0;
-  BX_VGA_THIS s.sequencer.chain_four = 0;
-  BX_VGA_THIS s.vga_mem_updated = 1;
-  BX_VGA_THIS s.x_tilesize = 16;
-  BX_VGA_THIS s.y_tilesize = 24;
-  BX_VGA_THIS s.line_offset = 160;
-  BX_VGA_THIS s.line_compare = 1023;
-  BX_VGA_THIS s.vertical_display_end = 399;
-  memset((BX_VGA_THIS s.vga_tile_updated), 0, BX_NUM_X_TILES * BX_NUM_Y_TILES);
-  
-  memset((BX_VGA_THIS s.vga_memory), ' ', 256 * 1024);
-  for(i = 0; i < 256 * 1024;i+=2) {
-       BX_VGA_THIS s.vga_memory[i] = ' ';
-       BX_VGA_THIS s.vga_memory[i+1] = 0x07;
-  
-  }
-  memset((BX_VGA_THIS s.text_snapshot), 0, 32 * 1024);
-  memset((BX_VGA_THIS s.rgb), 0, 3 * 256);
-  memset((BX_VGA_THIS s.tile), 0, X_TILESIZE * Y_TILESIZE * 4);
-  BX_VGA_THIS s.charmap_address = 0;
-  BX_VGA_THIS s.x_dotclockdiv2 = 0;
-  BX_VGA_THIS s.y_doublescan = 1;
-}
-
-  void
-bx_vga_c::reset(unsigned type)
-{
-}
-
-
-  void
-bx_vga_c::determine_screen_dimensions(unsigned *piHeight, unsigned *piWidth)
-{
-  int ai[0x20];
-  int i,h,v;
-  for ( i = 0 ; i < 0x20 ; i++ )
-   ai[i] = BX_VGA_THIS s.CRTC.reg[i];
-
-  h = (ai[1] + 1) * 8;
-  v = (ai[18] | ((ai[7] & 0x02) << 7) | ((ai[7] & 0x40) << 3)) + 1;
-
-  if ( BX_VGA_THIS s.graphics_ctrl.shift_reg == 0 )
-    {
-    *piWidth = 640;
-    *piHeight = 480;
-
-    if ( BX_VGA_THIS s.CRTC.reg[6] == 0xBF )
-      {
-      if (BX_VGA_THIS s.CRTC.reg[23] == 0xA3 &&
-         BX_VGA_THIS s.CRTC.reg[20] == 0x40 &&
-         BX_VGA_THIS s.CRTC.reg[9] == 0x41)
-        {
-        *piWidth = 320;
-        *piHeight = 240;
-        }
-      else {
-        if (BX_VGA_THIS s.x_dotclockdiv2) h <<= 1;
-        *piWidth = h;
-        *piHeight = v;
-        }
-      }
-    else if ((h >= 640) && (v >= 480)) {
-      *piWidth = h;
-      *piHeight = v;
-      }
-    }
-  else if ( BX_VGA_THIS s.graphics_ctrl.shift_reg == 2 )
-    {
-
-    if ( BX_VGA_THIS s.sequencer.chain_four )
-      {
-      *piWidth = h;
-      *piHeight = v;
-      }
-    else
-      {
-      *piWidth = h;
-      *piHeight = v;
-      }
-    }
-  else
-    {
-    if (BX_VGA_THIS s.x_dotclockdiv2) h <<= 1;
-    *piWidth = h;
-    *piHeight = v;
-    }
-}
-
-
-  // static IO port read callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-  Bit32u
-bx_vga_c::read_handler(void *this_ptr, Bit32u address, unsigned io_len)
-{
-#if !BX_USE_VGA_SMF
-  bx_vga_c *class_ptr = (bx_vga_c *) this_ptr;
-
-  return( class_ptr->read(address, io_len) );
-}
-
-
-  Bit32u
-bx_vga_c::read(Bit32u address, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif  // !BX_USE_VGA_SMF
-  bx_bool  horiz_retrace = 0, vert_retrace = 0;
-  Bit64u usec;
-  Bit16u vertres;
-  Bit8u retval;
-
-#if defined(VGA_TRACE_FEATURE)
-  Bit32u ret = 0;
-#define RETURN(x) do { ret = (x); goto read_return; } while (0)
-#else
-#define RETURN return
-#endif
-
-#ifdef __OS2__
-  if ( bx_options.videomode == BX_VIDEO_DIRECT )
-     {
-     return _inp(address);
-     }
-#endif
-
-#if !defined(VGA_TRACE_FEATURE)
-    BX_DEBUG(("io read from 0x%04x", (unsigned) address));
-#endif
-
-  if ( (address >= 0x03b0) && (address <= 0x03bf) &&
-       (BX_VGA_THIS s.misc_output.color_emulation) ) {
-       RETURN(0xff);
-  }
-  if ( (address >= 0x03d0) && (address <= 0x03df) &&
-       (BX_VGA_THIS s.misc_output.color_emulation==0) ) {
-       RETURN(0xff);
-  }
-
-  switch (address) {
-    case 0x03ba: /* Input Status 1 (monochrome emulation modes) */
-    case 0x03ca: /* Feature Control ??? */
-    case 0x03da: /* Input Status 1 (color emulation modes) */
-      // bit3: Vertical Retrace
-      //       0 = display is in the display mode
-      //       1 = display is in the vertical retrace mode
-      // bit0: Display Enable
-      //       0 = display is in the display mode
-      //       1 = display is not in the display mode; either the
-      //           horizontal or vertical retrace period is active
-
-      // using 72 Hz vertical frequency
-      usec = bx_pc_system.time_usec();
-      switch ( ( BX_VGA_THIS s.misc_output.vert_sync_pol << 1) | BX_VGA_THIS s.misc_output.horiz_sync_pol )
-      {
-        case 0: vertres = 200; break;
-        case 1: vertres = 400; break;
-        case 2: vertres = 350; break;
-        default: vertres = 480; break;
-      }
-      if ((usec % 13888) < 70) {
-        vert_retrace = 1;
-      }
-      if ((usec % (13888 / vertres)) == 0) {
-        horiz_retrace = 1;
-      }
-
-      retval = 0;
-      if (horiz_retrace || vert_retrace)
-        retval = 0x01;
-      if (vert_retrace)
-        retval |= 0x08;
-
-      /* reading this port resets the flip-flop to address mode */
-      BX_VGA_THIS s.attribute_ctrl.flip_flop = 0;
-      RETURN(retval);
-      break;
-
-
-    case 0x03c0: /* */
-      if (BX_VGA_THIS s.attribute_ctrl.flip_flop == 0) {
-        //BX_INFO(("io read: 0x3c0: flip_flop = 0"));
-        retval =
-          (BX_VGA_THIS s.attribute_ctrl.video_enabled << 5) |
-          BX_VGA_THIS s.attribute_ctrl.address;
-        RETURN(retval);
-        }
-      else {
-        BX_ERROR(("io read: 0x3c0: flip_flop != 0"));
-        return(0);
-        }
-      break;
-
-    case 0x03c1: /* */
-      switch (BX_VGA_THIS s.attribute_ctrl.address) {
-        case 0x00: case 0x01: case 0x02: case 0x03:
-        case 0x04: case 0x05: case 0x06: case 0x07:
-        case 0x08: case 0x09: case 0x0a: case 0x0b:
-        case 0x0c: case 0x0d: case 0x0e: case 0x0f:
-          retval = BX_VGA_THIS s.attribute_ctrl.palette_reg[BX_VGA_THIS s.attribute_ctrl.address];
-         RETURN(retval);
-          break;
-        case 0x10: /* mode control register */
-          retval =
-            (BX_VGA_THIS s.attribute_ctrl.mode_ctrl.graphics_alpha << 0) |
-            (BX_VGA_THIS s.attribute_ctrl.mode_ctrl.display_type << 1) |
-            (BX_VGA_THIS s.attribute_ctrl.mode_ctrl.enable_line_graphics << 2) |
-            (BX_VGA_THIS s.attribute_ctrl.mode_ctrl.blink_intensity << 3) |
-            (BX_VGA_THIS s.attribute_ctrl.mode_ctrl.pixel_panning_compat << 5) |
-            (BX_VGA_THIS s.attribute_ctrl.mode_ctrl.pixel_clock_select << 6) |
-            (BX_VGA_THIS s.attribute_ctrl.mode_ctrl.internal_palette_size << 7);
-         RETURN(retval);
-          break;
-       case 0x11: /* overscan color register */
-         RETURN(BX_VGA_THIS s.attribute_ctrl.overscan_color);
-          break;
-       case 0x12: /* color plane enable */
-         RETURN(BX_VGA_THIS s.attribute_ctrl.color_plane_enable);
-          break;
-        case 0x13: /* horizontal PEL panning register */
-          RETURN(BX_VGA_THIS s.attribute_ctrl.horiz_pel_panning);
-          break;
-        case 0x14: /* color select register */
-          RETURN(BX_VGA_THIS s.attribute_ctrl.color_select);
-          break;
-        default:
-          BX_INFO(("io read: 0x3c1: unknown register 0x%02x",
-            (unsigned) BX_VGA_THIS s.attribute_ctrl.address));
-          RETURN(0);
-        }
-      break;
-
-    case 0x03c2: /* Input Status 0 */
-      BX_DEBUG(("io read 0x3c2: input status #0: ignoring"));
-      RETURN(0);
-      break;
-
-    case 0x03c3: /* VGA Enable Register */
-      RETURN(1);
-      break;
-
-    case 0x03c4: /* Sequencer Index Register */
-      RETURN(BX_VGA_THIS s.sequencer.index);
-      break;
-
-    case 0x03c5: /* Sequencer Registers 00..04 */
-      switch (BX_VGA_THIS s.sequencer.index) {
-        case 0: /* sequencer: reset */
-          BX_DEBUG(("io read 0x3c5: sequencer reset"));
-          RETURN(BX_VGA_THIS s.sequencer.reset1 | (BX_VGA_THIS s.sequencer.reset2<<1));
-          break;
-        case 1: /* sequencer: clocking mode */
-          BX_DEBUG(("io read 0x3c5: sequencer clocking mode"));
-          RETURN(BX_VGA_THIS s.sequencer.reg1);
-          break;
-        case 2: /* sequencer: map mask register */
-          RETURN(BX_VGA_THIS s.sequencer.map_mask);
-          break;
-        case 3: /* sequencer: character map select register */
-          RETURN(BX_VGA_THIS s.sequencer.char_map_select);
-          break;
-        case 4: /* sequencer: memory mode register */
-          retval =
-            (BX_VGA_THIS s.sequencer.extended_mem   << 1) |
-            (BX_VGA_THIS s.sequencer.odd_even       << 2) |
-            (BX_VGA_THIS s.sequencer.chain_four     << 3);
-          RETURN(retval);
-          break;
-
-        default:
-          BX_DEBUG(("io read 0x3c5: index %u unhandled",
-            (unsigned) BX_VGA_THIS s.sequencer.index));
-          RETURN(0);
-        }
-      break;
-
-    case 0x03c6: /* PEL mask ??? */
-      RETURN(BX_VGA_THIS s.pel.mask);
-      break;
-
-    case 0x03c7: /* DAC state, read = 11b, write = 00b */
-      RETURN(BX_VGA_THIS s.pel.dac_state);
-      break;
-
-    case 0x03c8: /* PEL address write mode */
-      RETURN(BX_VGA_THIS s.pel.write_data_register);
-      break;
-
-    case 0x03c9: /* PEL Data Register, colors 00..FF */
-      if (BX_VGA_THIS s.pel.dac_state == 0x03) {
-        switch (BX_VGA_THIS s.pel.read_data_cycle) {
-          case 0:
-            retval = BX_VGA_THIS s.pel.data[BX_VGA_THIS s.pel.read_data_register].red;
-            break;
-          case 1:
-            retval = BX_VGA_THIS s.pel.data[BX_VGA_THIS s.pel.read_data_register].green;
-            break;
-          case 2:
-            retval = BX_VGA_THIS s.pel.data[BX_VGA_THIS s.pel.read_data_register].blue;
-            break;
-          default:
-            retval = 0; // keep compiler happy
-          }
-        BX_VGA_THIS s.pel.read_data_cycle++;
-        if (BX_VGA_THIS s.pel.read_data_cycle >= 3) {
-          BX_VGA_THIS s.pel.read_data_cycle = 0;
-          BX_VGA_THIS s.pel.read_data_register++;
-          }
-       }
-      else {
-        retval = 0x3f;
-        }
-      RETURN(retval);
-      break;
-
-    case 0x03cc: /* Miscellaneous Output / Graphics 1 Position ??? */
-      retval =
-        ((BX_VGA_THIS s.misc_output.color_emulation  & 0x01) << 0) |
-        ((BX_VGA_THIS s.misc_output.enable_ram       & 0x01) << 1) |
-        ((BX_VGA_THIS s.misc_output.clock_select     & 0x03) << 2) |
-        ((BX_VGA_THIS s.misc_output.select_high_bank & 0x01) << 5) |
-        ((BX_VGA_THIS s.misc_output.horiz_sync_pol   & 0x01) << 6) |
-        ((BX_VGA_THIS s.misc_output.vert_sync_pol    & 0x01) << 7);
-      RETURN(retval);
-      break;
-
-    case 0x03ce: /* Graphics Controller Index Register */
-      RETURN(BX_VGA_THIS s.graphics_ctrl.index);
-      break;
-
-    case 0x03cd: /* ??? */
-      BX_DEBUG(("io read from 03cd"));
-      RETURN(0x00);
-      break;
-
-    case 0x03cf: /* Graphics Controller Registers 00..08 */
-      switch (BX_VGA_THIS s.graphics_ctrl.index) {
-        case 0: /* Set/Reset */
-          RETURN(BX_VGA_THIS s.graphics_ctrl.set_reset);
-          break;
-        case 1: /* Enable Set/Reset */
-          RETURN(BX_VGA_THIS s.graphics_ctrl.enable_set_reset);
-          break;
-        case 2: /* Color Compare */
-          RETURN(BX_VGA_THIS s.graphics_ctrl.color_compare);
-          break;
-        case 3: /* Data Rotate */
-          retval =
-            ((BX_VGA_THIS s.graphics_ctrl.raster_op & 0x03) << 3) |
-            ((BX_VGA_THIS s.graphics_ctrl.data_rotate & 0x07) << 0);
-          RETURN(retval);
-          break;
-        case 4: /* Read Map Select */
-          RETURN(BX_VGA_THIS s.graphics_ctrl.read_map_select);
-          break;
-        case 5: /* Mode */
-          retval =
-            ((BX_VGA_THIS s.graphics_ctrl.shift_reg & 0x03) << 5) |
-            ((BX_VGA_THIS s.graphics_ctrl.odd_even & 0x01 ) << 4) |
-            ((BX_VGA_THIS s.graphics_ctrl.read_mode & 0x01) << 3) |
-            ((BX_VGA_THIS s.graphics_ctrl.write_mode & 0x03) << 0);
-
-          if (BX_VGA_THIS s.graphics_ctrl.odd_even ||
-              BX_VGA_THIS s.graphics_ctrl.shift_reg)
-            BX_DEBUG(("io read 0x3cf: reg 05 = 0x%02x", (unsigned) retval));
-          RETURN(retval);
-          break;
-        case 6: /* Miscellaneous */
-          retval =
-            ((BX_VGA_THIS s.graphics_ctrl.memory_mapping & 0x03 ) << 2) |
-            ((BX_VGA_THIS s.graphics_ctrl.odd_even & 0x01) << 1) |
-            ((BX_VGA_THIS s.graphics_ctrl.graphics_alpha & 0x01) << 0);
-          RETURN(retval);
-          break;
-        case 7: /* Color Don't Care */
-          RETURN(BX_VGA_THIS s.graphics_ctrl.color_dont_care);
-          break;
-        case 8: /* Bit Mask */
-          RETURN(BX_VGA_THIS s.graphics_ctrl.bitmask);
-          break;
-        default:
-          /* ??? */
-          BX_DEBUG(("io read: 0x3cf: index %u unhandled",
-            (unsigned) BX_VGA_THIS s.graphics_ctrl.index));
-          RETURN(0);
-        }
-      break;
-
-    case 0x03d4: /* CRTC Index Register (color emulation modes) */
-      RETURN(BX_VGA_THIS s.CRTC.address);
-      break;
-
-    case 0x03b5: /* CRTC Registers (monochrome emulation modes) */
-    case 0x03d5: /* CRTC Registers (color emulation modes) */
-      if (BX_VGA_THIS s.CRTC.address > 0x18) {
-        BX_DEBUG(("io read: invalid CRTC register 0x%02x",
-          (unsigned) BX_VGA_THIS s.CRTC.address));
-        RETURN(0);
-      }
-      RETURN(BX_VGA_THIS s.CRTC.reg[BX_VGA_THIS s.CRTC.address]);
-      break;
-
-    case 0x03b4: /* CRTC Index Register (monochrome emulation modes) */
-    case 0x03cb: /* not sure but OpenBSD reads it a lot */
-    default:
-      BX_INFO(("io read from vga port 0x%02x", (unsigned) address));
-      RETURN(0); /* keep compiler happy */
-    }
-
-#if defined(VGA_TRACE_FEATURE)
-  read_return:
-       BX_DEBUG(("8-bit read from %04x = %02x", (unsigned) address, ret));
-  return ret;
-#endif
-}
-#if defined(VGA_TRACE_FEATURE)
-#undef RETURN
-#endif
-
-  // static IO port write callback handler
-  // redirects to non-static class handler to avoid virtual functions
-
-  void
-bx_vga_c::write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len)
-{
-#if !BX_USE_VGA_SMF
-  bx_vga_c *class_ptr = (bx_vga_c *) this_ptr;
-
-  class_ptr->write(address, value, io_len, 0);
-#else
-  UNUSED(this_ptr);
-  theVga->write(address, value, io_len, 0);
-#endif
-}
-
-  void
-bx_vga_c::write_handler_no_log(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len)
-{
-#if !BX_USE_VGA_SMF
-  bx_vga_c *class_ptr = (bx_vga_c *) this_ptr;
-
-  class_ptr->write(address, value, io_len, 1);
-#else
-  UNUSED(this_ptr);
-  theVga->write(address, value, io_len, 1);
-#endif
-}
-
-  void
-bx_vga_c::write(Bit32u address, Bit32u value, unsigned io_len, bx_bool no_log)
-{
-  unsigned i;
-  Bit8u charmap1, charmap2, prev_memory_mapping;
-  bx_bool prev_video_enabled, prev_line_graphics, prev_int_pal_size;
-  bx_bool prev_graphics_alpha, prev_chain_odd_even;
-  bx_bool needs_update = 0;
-
-#if defined(VGA_TRACE_FEATURE)
-  if (!no_log)
-       switch (io_len) {
-             case 1:
-                   BX_DEBUG(("8-bit write to %04x = %02x", (unsigned)address, (unsigned)value));
-                   break;
-             case 2:
-                   BX_DEBUG(("16-bit write to %04x = %04x", (unsigned)address, (unsigned)value));
-                   break;
-             default:
-                   BX_PANIC(("Weird VGA write size"));
-       }
-#else
-  if (io_len == 1) {
-    BX_DEBUG(("io write to 0x%04x = 0x%02x", (unsigned) address,
-      (unsigned) value));
-  }
-#endif
-
-  if (io_len == 2) {
-#if BX_USE_VGA_SMF
-    bx_vga_c::write_handler_no_log(0, address, value & 0xff, 1);
-    bx_vga_c::write_handler_no_log(0, address+1, (value >> 8) & 0xff, 1);
-#else
-    bx_vga_c::write(address, value & 0xff, 1, 1);
-    bx_vga_c::write(address+1, (value >> 8) & 0xff, 1, 1);
-#endif
-    return;
-    }
-
-#ifdef __OS2__
-  if ( bx_options.videomode == BX_VIDEO_DIRECT )
-     {
-     _outp(address,value);
-     return;
-     }
-#endif
-
-  if ( (address >= 0x03b0) && (address <= 0x03bf) &&
-       (BX_VGA_THIS s.misc_output.color_emulation) )
-    return;
-  if ( (address >= 0x03d0) && (address <= 0x03df) &&
-       (BX_VGA_THIS s.misc_output.color_emulation==0) )
-    return;
-
-  switch (address) {
-    case 0x03ba: /* Feature Control (monochrome emulation modes) */
-#if !defined(VGA_TRACE_FEATURE)
-      BX_DEBUG(("io write 3ba: feature control: ignoring"));
-#endif
-      break;
-
-    case 0x03c0: /* Attribute Controller */
-      if (BX_VGA_THIS s.attribute_ctrl.flip_flop == 0) { /* address mode */
-        prev_video_enabled = BX_VGA_THIS s.attribute_ctrl.video_enabled;
-        BX_VGA_THIS s.attribute_ctrl.video_enabled = (value >> 5) & 0x01;
-#if !defined(VGA_TRACE_FEATURE)
-        BX_DEBUG(("io write 3c0: video_enabled = %u",
-                  (unsigned) BX_VGA_THIS s.attribute_ctrl.video_enabled));
-#endif
-        if (BX_VGA_THIS s.attribute_ctrl.video_enabled == 0)
-          bx_gui->clear_screen();
-        else if (!prev_video_enabled) {
-#if !defined(VGA_TRACE_FEATURE)
-          BX_DEBUG(("found enable transition"));
-#endif
-          needs_update = 1;
-        }
-        value &= 0x1f; /* address = bits 0..4 */
-        BX_VGA_THIS s.attribute_ctrl.address = value;
-        switch (value) {
-          case 0x00: case 0x01: case 0x02: case 0x03:
-          case 0x04: case 0x05: case 0x06: case 0x07:
-          case 0x08: case 0x09: case 0x0a: case 0x0b:
-          case 0x0c: case 0x0d: case 0x0e: case 0x0f:
-            break;
-
-          default:
-            BX_DEBUG(("io write 3c0: address mode reg=%u",
-              (unsigned) value));
-          }
-        }
-      else { /* data-write mode */
-        switch (BX_VGA_THIS s.attribute_ctrl.address) {
-          case 0x00: case 0x01: case 0x02: case 0x03:
-          case 0x04: case 0x05: case 0x06: case 0x07:
-          case 0x08: case 0x09: case 0x0a: case 0x0b:
-          case 0x0c: case 0x0d: case 0x0e: case 0x0f:
-            if (value != BX_VGA_THIS s.attribute_ctrl.palette_reg[BX_VGA_THIS s.attribute_ctrl.address]) {
-              BX_VGA_THIS s.attribute_ctrl.palette_reg[BX_VGA_THIS s.attribute_ctrl.address] =
-                value;
-              needs_update = 1;
-            }
-            break;
-          case 0x10: // mode control register
-            prev_line_graphics = BX_VGA_THIS s.attribute_ctrl.mode_ctrl.enable_line_graphics;
-            prev_int_pal_size = BX_VGA_THIS s.attribute_ctrl.mode_ctrl.internal_palette_size;
-            BX_VGA_THIS s.attribute_ctrl.mode_ctrl.graphics_alpha =
-              (value >> 0) & 0x01;
-            BX_VGA_THIS s.attribute_ctrl.mode_ctrl.display_type =
-              (value >> 1) & 0x01;
-            BX_VGA_THIS s.attribute_ctrl.mode_ctrl.enable_line_graphics =
-              (value >> 2) & 0x01;
-            BX_VGA_THIS s.attribute_ctrl.mode_ctrl.blink_intensity =
-              (value >> 3) & 0x01;
-            BX_VGA_THIS s.attribute_ctrl.mode_ctrl.pixel_panning_compat =
-              (value >> 5) & 0x01;
-            BX_VGA_THIS s.attribute_ctrl.mode_ctrl.pixel_clock_select =
-              (value >> 6) & 0x01;
-            BX_VGA_THIS s.attribute_ctrl.mode_ctrl.internal_palette_size =
-              (value >> 7) & 0x01;
-            if (((value >> 2) & 0x01) != prev_line_graphics) {
-              bx_gui->set_text_charmap(
-                & BX_VGA_THIS s.vga_memory[0x20000 + BX_VGA_THIS s.charmap_address]);
-              BX_VGA_THIS s.vga_mem_updated = 1;
-            }
-            if (((value >> 7) & 0x01) != prev_int_pal_size) {
-              needs_update = 1;
-            }
-#if !defined(VGA_TRACE_FEATURE)
-            BX_DEBUG(("io write 3c0: mode control: %02x h",
-                (unsigned) value));
-#endif
-            break;
-          case 0x11: // Overscan Color Register
-            BX_VGA_THIS s.attribute_ctrl.overscan_color = (value & 0x3f);
-#if !defined(VGA_TRACE_FEATURE)
-            BX_DEBUG(("io write 3c0: overscan color = %02x",
-                        (unsigned) value));
-#endif
-            break;
-          case 0x12: // Color Plane Enable Register
-            BX_VGA_THIS s.attribute_ctrl.color_plane_enable = (value & 0x0f);
-            needs_update = 1;
-#if !defined(VGA_TRACE_FEATURE)
-            BX_DEBUG(("io write 3c0: color plane enable = %02x",
-                        (unsigned) value));
-#endif
-            break;
-          case 0x13: // Horizontal Pixel Panning Register
-            BX_VGA_THIS s.attribute_ctrl.horiz_pel_panning = (value & 0x0f);
-            needs_update = 1;
-#if !defined(VGA_TRACE_FEATURE)
-            BX_DEBUG(("io write 3c0: horiz pel panning = %02x",
-                        (unsigned) value));
-#endif
-            break;
-          case 0x14: // Color Select Register
-            BX_VGA_THIS s.attribute_ctrl.color_select = (value & 0x0f);
-            needs_update = 1;
-#if !defined(VGA_TRACE_FEATURE)
-            BX_DEBUG(("io write 3c0: color select = %02x",
-                        (unsigned) BX_VGA_THIS s.attribute_ctrl.color_select));
-#endif
-            break;
-          default:
-            BX_DEBUG(("io write 3c0: data-write mode %02x h",
-              (unsigned) BX_VGA_THIS s.attribute_ctrl.address));
-          }
-        }
-      BX_VGA_THIS s.attribute_ctrl.flip_flop = !BX_VGA_THIS s.attribute_ctrl.flip_flop;
-      break;
-
-    case 0x03c2: // Miscellaneous Output Register
-      BX_VGA_THIS s.misc_output.color_emulation  = (value >> 0) & 0x01;
-      BX_VGA_THIS s.misc_output.enable_ram       = (value >> 1) & 0x01;
-      BX_VGA_THIS s.misc_output.clock_select     = (value >> 2) & 0x03;
-      BX_VGA_THIS s.misc_output.select_high_bank = (value >> 5) & 0x01;
-      BX_VGA_THIS s.misc_output.horiz_sync_pol   = (value >> 6) & 0x01;
-      BX_VGA_THIS s.misc_output.vert_sync_pol    = (value >> 7) & 0x01;
-#if !defined(VGA_TRACE_FEATURE)
-        BX_DEBUG(("io write 3c2:"));
-        BX_DEBUG(("  color_emulation (attempted) = %u",
-                  (value >> 0) & 0x01));
-        BX_DEBUG(("  enable_ram = %u",
-                  (unsigned) BX_VGA_THIS s.misc_output.enable_ram));
-        BX_DEBUG(("  clock_select = %u",
-                  (unsigned) BX_VGA_THIS s.misc_output.clock_select));
-        BX_DEBUG(("  select_high_bank = %u",
-                  (unsigned) BX_VGA_THIS s.misc_output.select_high_bank));
-        BX_DEBUG(("  horiz_sync_pol = %u",
-                  (unsigned) BX_VGA_THIS s.misc_output.horiz_sync_pol));
-        BX_DEBUG(("  vert_sync_pol = %u",
-                  (unsigned) BX_VGA_THIS s.misc_output.vert_sync_pol));
-#endif
-      break;
-
-    case 0x03c3: // VGA enable
-      // bit0: enables VGA display if set
-#if !defined(VGA_TRACE_FEATURE)
-      BX_DEBUG(("io write 3c3: (ignoring) VGA enable = %u",
-                  (unsigned) (value & 0x01) ));
-#endif
-      break;
-
-    case 0x03c4: /* Sequencer Index Register */
-      if (value > 4) {
-        BX_DEBUG(("io write 3c4: value > 4"));
-        }
-      BX_VGA_THIS s.sequencer.index = value;
-      break;
-
-    case 0x03c5: /* Sequencer Registers 00..04 */
-      switch (BX_VGA_THIS s.sequencer.index) {
-        case 0: /* sequencer: reset */
-#if !defined(VGA_TRACE_FEATURE)
-          BX_DEBUG(("write 0x3c5: sequencer reset: value=0x%02x",
-                      (unsigned) value));
-#endif
-          if (BX_VGA_THIS s.sequencer.reset1 && ((value & 0x01) == 0)) {
-            BX_VGA_THIS s.sequencer.char_map_select = 0;
-            BX_VGA_THIS s.charmap_address = 0;
-            bx_gui->set_text_charmap(
-              & BX_VGA_THIS s.vga_memory[0x20000 + BX_VGA_THIS s.charmap_address]);
-            BX_VGA_THIS s.vga_mem_updated = 1;
-          }
-          BX_VGA_THIS s.sequencer.reset1 = (value >> 0) & 0x01;
-          BX_VGA_THIS s.sequencer.reset2 = (value >> 1) & 0x01;
-          break;
-        case 1: /* sequencer: clocking mode */
-#if !defined(VGA_TRACE_FEATURE)
-          BX_DEBUG(("io write 3c5=%02x: clocking mode reg: ignoring",
-                      (unsigned) value));
-#endif
-          BX_VGA_THIS s.sequencer.reg1 = value & 0x3f;
-          BX_VGA_THIS s.x_dotclockdiv2 = ((value & 0x08) > 0);
-          break;
-        case 2: /* sequencer: map mask register */
-          BX_VGA_THIS s.sequencer.map_mask = (value & 0x0f);
-          for (i=0; i<4; i++)
-            BX_VGA_THIS s.sequencer.map_mask_bit[i] = (value >> i) & 0x01;
-          break;
-        case 3: /* sequencer: character map select register */
-          BX_VGA_THIS s.sequencer.char_map_select = value;
-          charmap1 = value & 0x13;
-          if (charmap1 > 3) charmap1 = (charmap1 & 3) + 4;
-          charmap2 = (value & 0x2C) >> 2;
-          if (charmap2 > 3) charmap2 = (charmap2 & 3) + 4;
-         if (BX_VGA_THIS s.CRTC.reg[0x09] > 0) {
-            BX_VGA_THIS s.charmap_address = (charmap1 << 13);
-            bx_gui->set_text_charmap(
-              & BX_VGA_THIS s.vga_memory[0x20000 + BX_VGA_THIS s.charmap_address]);
-            BX_VGA_THIS s.vga_mem_updated = 1;
-            }
-          if (charmap2 != charmap1)
-            BX_INFO(("char map select: #2=%d (unused)", charmap2));
-          break;
-        case 4: /* sequencer: memory mode register */
-          BX_VGA_THIS s.sequencer.extended_mem   = (value >> 1) & 0x01;
-          BX_VGA_THIS s.sequencer.odd_even       = (value >> 2) & 0x01;
-          BX_VGA_THIS s.sequencer.chain_four     = (value >> 3) & 0x01;
-
-#if !defined(VGA_TRACE_FEATURE)
-          BX_DEBUG(("io write 3c5: index 4:"));
-          BX_DEBUG(("  extended_mem %u",
-              (unsigned) BX_VGA_THIS s.sequencer.extended_mem));
-          BX_DEBUG(("  odd_even %u",
-              (unsigned) BX_VGA_THIS s.sequencer.odd_even));
-          BX_DEBUG(("  chain_four %u",
-              (unsigned) BX_VGA_THIS s.sequencer.chain_four));
-#endif
-          break;
-        default:
-          BX_DEBUG(("io write 3c5: index %u unhandled",
-            (unsigned) BX_VGA_THIS s.sequencer.index));
-        }
-      break;
-
-    case 0x03c6: /* PEL mask */
-      BX_VGA_THIS s.pel.mask = value;
-      if (BX_VGA_THIS s.pel.mask != 0xff)
-        BX_DEBUG(("io write 3c6: PEL mask=0x%02x != 0xFF", value));
-      // BX_VGA_THIS s.pel.mask should be and'd with final value before
-      // indexing into color register BX_VGA_THIS s.pel.data[]
-      break;
-
-    case 0x03c7: // PEL address, read mode
-      BX_VGA_THIS s.pel.read_data_register = value;
-      BX_VGA_THIS s.pel.read_data_cycle    = 0;
-      BX_VGA_THIS s.pel.dac_state = 0x03;
-      break;
-
-    case 0x03c8: /* PEL address write mode */
-      BX_VGA_THIS s.pel.write_data_register = value;
-      BX_VGA_THIS s.pel.write_data_cycle    = 0;
-      BX_VGA_THIS s.pel.dac_state = 0x00;
-      break;
-
-    case 0x03c9: /* PEL Data Register, colors 00..FF */
-      switch (BX_VGA_THIS s.pel.write_data_cycle) {
-        case 0:
-          BX_VGA_THIS s.pel.data[BX_VGA_THIS s.pel.write_data_register].red = value;
-          break;
-        case 1:
-          BX_VGA_THIS s.pel.data[BX_VGA_THIS s.pel.write_data_register].green = value;
-          break;
-        case 2:
-          BX_VGA_THIS s.pel.data[BX_VGA_THIS s.pel.write_data_register].blue = value;
-
-          needs_update |= bx_gui->palette_change(BX_VGA_THIS s.pel.write_data_register,
-            BX_VGA_THIS s.pel.data[BX_VGA_THIS s.pel.write_data_register].red<<2,
-            BX_VGA_THIS s.pel.data[BX_VGA_THIS s.pel.write_data_register].green<<2,
-            BX_VGA_THIS s.pel.data[BX_VGA_THIS s.pel.write_data_register].blue<<2);
-          break;
-        }
-
-      BX_VGA_THIS s.pel.write_data_cycle++;
-      if (BX_VGA_THIS s.pel.write_data_cycle >= 3) {
-        //BX_INFO(("BX_VGA_THIS s.pel.data[%u] {r=%u, g=%u, b=%u}",
-        //  (unsigned) BX_VGA_THIS s.pel.write_data_register,
-        //  (unsigned) BX_VGA_THIS s.pel.data[BX_VGA_THIS s.pel.write_data_register].red,
-        //  (unsigned) BX_VGA_THIS s.pel.data[BX_VGA_THIS s.pel.write_data_register].green,
-        //  (unsigned) BX_VGA_THIS s.pel.data[BX_VGA_THIS s.pel.write_data_register].blue);
-        BX_VGA_THIS s.pel.write_data_cycle = 0;
-        BX_VGA_THIS s.pel.write_data_register++;
-        }
-      break;
-
-    case 0x03ca: /* Graphics 2 Position (EGA) */
-      // ignore, EGA only???
-      break;
-
-    case 0x03cc: /* Graphics 1 Position (EGA) */
-      // ignore, EGA only???
-      break;
-
-    case 0x03ce: /* Graphics Controller Index Register */
-      if (value > 0x08) /* ??? */
-        BX_DEBUG(("io write: 3ce: value > 8"));
-      BX_VGA_THIS s.graphics_ctrl.index = value;
-      break;
-
-    case 0x03cd: /* ??? */
-      BX_DEBUG(("io write to 03cd = %02x", (unsigned) value));
-      break;
-
-    case 0x03cf: /* Graphics Controller Registers 00..08 */
-      switch (BX_VGA_THIS s.graphics_ctrl.index) {
-        case 0: /* Set/Reset */
-          BX_VGA_THIS s.graphics_ctrl.set_reset = value & 0x0f;
-          break;
-        case 1: /* Enable Set/Reset */
-          BX_VGA_THIS s.graphics_ctrl.enable_set_reset = value & 0x0f;
-          break;
-        case 2: /* Color Compare */
-          BX_VGA_THIS s.graphics_ctrl.color_compare = value & 0x0f;
-          break;
-        case 3: /* Data Rotate */
-          BX_VGA_THIS s.graphics_ctrl.data_rotate = value & 0x07;
-          /* ??? is this bits 3..4 or 4..5 */
-          BX_VGA_THIS s.graphics_ctrl.raster_op    = (value >> 3) & 0x03; /* ??? */
-          break;
-        case 4: /* Read Map Select */
-          BX_VGA_THIS s.graphics_ctrl.read_map_select = value & 0x03;
-#if !defined(VGA_TRACE_FEATURE)
-          BX_DEBUG(("io write to 03cf = %02x (RMS)", (unsigned) value));
-#endif
-          break;
-        case 5: /* Mode */
-          BX_VGA_THIS s.graphics_ctrl.write_mode        = value & 0x03;
-          BX_VGA_THIS s.graphics_ctrl.read_mode         = (value >> 3) & 0x01;
-          BX_VGA_THIS s.graphics_ctrl.odd_even   = (value >> 4) & 0x01;
-          BX_VGA_THIS s.graphics_ctrl.shift_reg         = (value >> 5) & 0x03;
-
-          if (BX_VGA_THIS s.graphics_ctrl.odd_even)
-            BX_DEBUG(("io write: 3cf: reg 05: value = %02xh",
-              (unsigned) value));
-          if (BX_VGA_THIS s.graphics_ctrl.shift_reg)
-            BX_DEBUG(("io write: 3cf: reg 05: value = %02xh",
-              (unsigned) value));
-          break;
-        case 6: /* Miscellaneous */
-          prev_graphics_alpha = BX_VGA_THIS s.graphics_ctrl.graphics_alpha;
-          prev_chain_odd_even = BX_VGA_THIS s.graphics_ctrl.chain_odd_even;
-          prev_memory_mapping = BX_VGA_THIS s.graphics_ctrl.memory_mapping;
-
-          BX_VGA_THIS s.graphics_ctrl.graphics_alpha = value & 0x01;
-          BX_VGA_THIS s.graphics_ctrl.chain_odd_even = (value >> 1) & 0x01;
-          BX_VGA_THIS s.graphics_ctrl.memory_mapping = (value >> 2) & 0x03;
-#if !defined(VGA_TRACE_FEATURE)
-          BX_DEBUG(("memory_mapping set to %u",
-              (unsigned) BX_VGA_THIS s.graphics_ctrl.memory_mapping));
-          BX_DEBUG(("graphics mode set to %u",
-              (unsigned) BX_VGA_THIS s.graphics_ctrl.graphics_alpha));
-          BX_DEBUG(("odd_even mode set to %u",
-              (unsigned) BX_VGA_THIS s.graphics_ctrl.odd_even));
-          BX_DEBUG(("io write: 3cf: reg 06: value = %02xh",
-                (unsigned) value));
-#endif
-          if (prev_memory_mapping != BX_VGA_THIS s.graphics_ctrl.memory_mapping)
-            needs_update = 1;
-          if (prev_graphics_alpha != BX_VGA_THIS s.graphics_ctrl.graphics_alpha) {
-            needs_update = 1;
-            old_iHeight = 0;
-          }
-          break;
-        case 7: /* Color Don't Care */
-          BX_VGA_THIS s.graphics_ctrl.color_dont_care = value & 0x0f;
-          break;
-        case 8: /* Bit Mask */
-          BX_VGA_THIS s.graphics_ctrl.bitmask = value;
-          break;
-        default:
-          /* ??? */
-          BX_DEBUG(("io write: 3cf: index %u unhandled",
-            (unsigned) BX_VGA_THIS s.graphics_ctrl.index));
-        }
-      break;
-
-    case 0x03b4: /* CRTC Index Register (monochrome emulation modes) */
-    case 0x03d4: /* CRTC Index Register (color emulation modes) */
-      BX_VGA_THIS s.CRTC.address = value & 0x7f;
-      if (BX_VGA_THIS s.CRTC.address > 0x18)
-        BX_DEBUG(("write: invalid CRTC register 0x%02x selected",
-          (unsigned) BX_VGA_THIS s.CRTC.address));
-      break;
-
-    case 0x03b5: /* CRTC Registers (monochrome emulation modes) */
-    case 0x03d5: /* CRTC Registers (color emulation modes) */
-      if (BX_VGA_THIS s.CRTC.address > 0x18) {
-        BX_DEBUG(("write: invalid CRTC register 0x%02x ignored",
-          (unsigned) BX_VGA_THIS s.CRTC.address));
-        return;
-      }
-      if (value != BX_VGA_THIS s.CRTC.reg[BX_VGA_THIS s.CRTC.address]) {
-        BX_VGA_THIS s.CRTC.reg[BX_VGA_THIS s.CRTC.address] = value;
-        switch (BX_VGA_THIS s.CRTC.address) {
-          case 0x07:
-            BX_VGA_THIS s.vertical_display_end &= 0xff;
-            if (BX_VGA_THIS s.CRTC.reg[0x07] & 0x02) BX_VGA_THIS s.vertical_display_end |= 0x100;
-            if (BX_VGA_THIS s.CRTC.reg[0x07] & 0x40) BX_VGA_THIS s.vertical_display_end |= 0x200;
-            BX_VGA_THIS s.line_compare &= 0x2ff;
-            if (BX_VGA_THIS s.CRTC.reg[0x07] & 0x10) BX_VGA_THIS s.line_compare |= 0x100;
-            needs_update = 1;
-            break;
-          case 0x08:
-            // Vertical pel panning change
-            needs_update = 1;
-            break;
-          case 0x09:
-            BX_VGA_THIS s.y_doublescan = ((value & 0x9f) > 0);
-            BX_VGA_THIS s.line_compare &= 0x1ff;
-            if (BX_VGA_THIS s.CRTC.reg[0x09] & 0x40) BX_VGA_THIS s.line_compare |= 0x200;
-            needs_update = 1;
-            break;
-          case 0x0A:
-          case 0x0B:
-          case 0x0E:
-          case 0x0F:
-            // Cursor size / location change
-            BX_VGA_THIS s.vga_mem_updated = 1;
-            break;
-          case 0x0C:
-          case 0x0D:
-            // Start address change
-            if (BX_VGA_THIS s.graphics_ctrl.graphics_alpha) {
-              needs_update = 1;
-            } else {
-              BX_VGA_THIS s.vga_mem_updated = 1;
-            }
-            break;
-          case 0x12:
-            BX_VGA_THIS s.vertical_display_end &= 0x300;
-            BX_VGA_THIS s.vertical_display_end |= BX_VGA_THIS s.CRTC.reg[0x12];
-            break;
-          case 0x13:
-          case 0x14:
-          case 0x17:
-            // Line offset change
-            BX_VGA_THIS s.line_offset = BX_VGA_THIS s.CRTC.reg[0x13] << 1;
-            if (BX_VGA_THIS s.CRTC.reg[0x14] & 0x40) BX_VGA_THIS s.line_offset <<= 2;
-            else if ((BX_VGA_THIS s.CRTC.reg[0x17] & 0x40) == 0) BX_VGA_THIS s.line_offset <<= 1;
-            needs_update = 1;
-            break;
-          case 0x18:
-            BX_VGA_THIS s.line_compare &= 0x300;
-            BX_VGA_THIS s.line_compare |= BX_VGA_THIS s.CRTC.reg[0x18];
-            needs_update = 1;
-            break;
-        }
-
-      }
-      break;
-
-    case 0x03da: /* Feature Control (color emulation modes) */
-      BX_DEBUG(("io write: 3da: ignoring: feature ctrl & vert sync"));
-      break;
-
-    case 0x03c1: /* */
-    default:
-      BX_ERROR(("unsupported io write to port 0x%04x, val=0x%02x",
-        (unsigned) address, (unsigned) value));
-    }
-  if (needs_update) {
-    BX_VGA_THIS s.vga_mem_updated = 1;
-    // Mark all video as updated so the changes will go through
-    if ((BX_VGA_THIS s.graphics_ctrl.graphics_alpha)
-#if BX_SUPPORT_VBE  
-        || (BX_VGA_THIS s.vbe_enabled)
-#endif
-       ) {
-      for (unsigned xti = 0; xti < BX_NUM_X_TILES; xti++) {
-        for (unsigned yti = 0; yti < BX_NUM_Y_TILES; yti++) {
-          SET_TILE_UPDATED (xti, yti, 1);
-        }
-      }
-    } else {
-      memset(BX_VGA_THIS s.text_snapshot, 0,
-             sizeof(BX_VGA_THIS s.text_snapshot));
-    }
-  }
-}
-
-void 
-bx_vga_c::set_update_interval (unsigned interval)
-{
-  BX_INFO (("Changing timer interval to %d\n", interval));
-  BX_VGA_THIS timer_handler (theVga);
-  bx_pc_system.activate_timer (BX_VGA_THIS timer_id, interval, 1);
-}
-
-  void
-bx_vga_c::trigger_timer(void *this_ptr)
-{
-  timer_handler(this_ptr);
-}
-
-  void
-bx_vga_c::timer_handler(void *this_ptr)
-{
-#if !BX_USE_VGA_SMF
-  
-  bx_vga_c *class_ptr = (bx_vga_c *) this_ptr;
-
-  class_ptr->timer();
-}
-
-  void
-bx_vga_c::timer(void)
-{
-#else
-  UNUSED(this_ptr);
-#endif
-
-  update();
-  bx_gui->flush();
-
-}
-
-
-  void
-bx_vga_c::update(void)
-{
-  unsigned iHeight, iWidth;
-
-  /* no screen update necessary */
-  if (BX_VGA_THIS s.vga_mem_updated==0)
-    return;
-
-  /* skip screen update when the sequencer is in reset mode or video is disabled */
-  if (!BX_VGA_THIS s.sequencer.reset1 || !BX_VGA_THIS s.sequencer.reset2
-      || !BX_VGA_THIS s.attribute_ctrl.video_enabled)
-    return;
-
-  /* skip screen update if the vertical retrace is in progress
-     (using 72 Hz vertical frequency) */
-  if ((bx_pc_system.time_usec() % 13888) < 70)
-    return;
-
-#if BX_SUPPORT_VBE  
-  if ((BX_VGA_THIS s.vbe_enabled) && (BX_VGA_THIS s.vbe_bpp != VBE_DISPI_BPP_4))
-  {
-    // specific VBE code display update code
-    // this is partly copied/modified from the 320x200x8 update more below
-    unsigned xc, yc, xti, yti;
-    unsigned r;
-    unsigned long pixely, bmp_ofs_y, tile_ofs_y;
-
-    if (BX_VGA_THIS s.vbe_bpp == VBE_DISPI_BPP_32)
-    {
-      Bit32u *vidmem = (Bit32u *)(&BX_VGA_THIS s.vbe_memory[BX_VGA_THIS s.vbe_virtual_start]);
-      Bit32u *tile   = (Bit32u *)(BX_VGA_THIS s.tile);
-      Bit16u width  =  BX_VGA_THIS s.vbe_virtual_xres;
-
-      Bit32u *vidptr, *tileptr;
-
-      iWidth=BX_VGA_THIS s.vbe_xres;
-      iHeight=BX_VGA_THIS s.vbe_yres;
-
-      for (yc=0, yti = 0; yc<iHeight; yc+=Y_TILESIZE, yti++)
-      {
-        for (xc=0, xti = 0; xc<iWidth; xc+=X_TILESIZE, xti++)
-        {
-          if (GET_TILE_UPDATED (xti, yti))
-          {
-            for (r=0; r<Y_TILESIZE; r++)
-            {
-              pixely    = yc + r;
-              // calc offsets into video and tile memory
-              bmp_ofs_y = pixely*width;
-              tile_ofs_y = r*X_TILESIZE;
-              // get offsets so that we do less calc in the inner loop
-              vidptr = &vidmem[bmp_ofs_y+xc];
-              tileptr = &tile[tile_ofs_y];
-              memmove(tileptr, vidptr, X_TILESIZE<<2);
-            }
-            SET_TILE_UPDATED (xti, yti, 0);
-            bx_gui->graphics_tile_update(BX_VGA_THIS s.tile, xc, yc);
-          }
-        }
-      }
-    }
-    else if (BX_VGA_THIS s.vbe_bpp == VBE_DISPI_BPP_24)
-    {
-      Bit8u *vidmem = &BX_VGA_THIS s.vbe_memory[BX_VGA_THIS s.vbe_virtual_start];
-      Bit8u *tile   =  BX_VGA_THIS s.tile;
-      Bit16u width  =  BX_VGA_THIS s.vbe_virtual_xres*3;
-
-      Bit8u *vidptr, *tileptr;
-
-      iWidth=BX_VGA_THIS s.vbe_xres;
-      iHeight=BX_VGA_THIS s.vbe_yres;
-
-      for (yc=0, yti = 0; yc<iHeight; yc+=Y_TILESIZE, yti++)
-      {
-        for (xc=0, xti = 0; xc<iWidth; xc+=X_TILESIZE, xti++)
-        {
-          if (GET_TILE_UPDATED (xti, yti))
-          {
-            for (r=0; r<Y_TILESIZE; r++)
-            {
-              pixely    = yc + r;
-              // calc offsets into video and tile memory
-              bmp_ofs_y = pixely*width;
-              tile_ofs_y = r*X_TILESIZE*3;
-              // get offsets so that we do less calc in the inner loop
-              vidptr = &vidmem[bmp_ofs_y+xc*3];
-              tileptr = &tile[tile_ofs_y];
-              memmove(tileptr, vidptr, X_TILESIZE*3);
-            }
-            SET_TILE_UPDATED (xti, yti, 0);
-            bx_gui->graphics_tile_update(BX_VGA_THIS s.tile, xc, yc);
-          }
-        }
-      }
-    }
-    else if ((BX_VGA_THIS s.vbe_bpp == VBE_DISPI_BPP_15) ||
-             (BX_VGA_THIS s.vbe_bpp == VBE_DISPI_BPP_16))
-    {
-      Bit16u *vidmem = (Bit16u *)(&BX_VGA_THIS s.vbe_memory[BX_VGA_THIS s.vbe_virtual_start]);
-      Bit16u *tile   = (Bit16u *)(BX_VGA_THIS s.tile);
-      Bit16u width  =  BX_VGA_THIS s.vbe_virtual_xres;
-
-      Bit16u *vidptr, *tileptr;
-
-      iWidth=BX_VGA_THIS s.vbe_xres;
-      iHeight=BX_VGA_THIS s.vbe_yres;
-
-      for (yc=0, yti = 0; yc<iHeight; yc+=Y_TILESIZE, yti++)
-      {
-        for (xc=0, xti = 0; xc<iWidth; xc+=X_TILESIZE, xti++)
-        {
-          if (GET_TILE_UPDATED (xti, yti))
-          {
-            for (r=0; r<Y_TILESIZE; r++)
-            {
-              pixely    = yc + r;
-              // calc offsets into video and tile memory
-              bmp_ofs_y = pixely*width;
-              tile_ofs_y = r*X_TILESIZE;
-              // get offsets so that we do less calc in the inner loop
-              vidptr = &vidmem[bmp_ofs_y+xc];
-              tileptr = &tile[tile_ofs_y];
-              memmove(tileptr, vidptr, X_TILESIZE<<1);
-            }
-            SET_TILE_UPDATED (xti, yti, 0);
-            bx_gui->graphics_tile_update(BX_VGA_THIS s.tile, xc, yc);
-          }
-        }
-      }
-    }
-    else /* Update 8bpp mode */
-    {
-      Bit8u *vidmem = &BX_VGA_THIS s.vbe_memory[BX_VGA_THIS s.vbe_virtual_start]; 
-      Bit8u *tile   =  BX_VGA_THIS s.tile;
-      Bit16u width  =  BX_VGA_THIS s.vbe_virtual_xres;
-
-      Bit8u *vidptr, *tileptr;
-
-      iWidth=BX_VGA_THIS s.vbe_xres;
-      iHeight=BX_VGA_THIS s.vbe_yres;
-
-      for (yc=0, yti = 0; yc<iHeight; yc+=Y_TILESIZE, yti++)
-      {
-        for (xc=0, xti = 0; xc<iWidth; xc+=X_TILESIZE, xti++)
-        {
-          // If the tile has not been updated, copy it into the tile buffer for update  
-          if (GET_TILE_UPDATED (xti, yti)) {
-            for (r=0; r<Y_TILESIZE; r++) {
-              // actual video y coord is tile_y + y
-              pixely = yc + r;
-              // calc offsets into video and tile memory
-              bmp_ofs_y = pixely*width;
-              tile_ofs_y = r*X_TILESIZE;
-              // get offsets so that we do less calc in the inner loop
-              vidptr = &vidmem[bmp_ofs_y+xc];
-              tileptr = &tile[tile_ofs_y];
-              memmove(tileptr, vidptr, X_TILESIZE);
-            }
-            SET_TILE_UPDATED (xti, yti, 0);
-            bx_gui->graphics_tile_update(BX_VGA_THIS s.tile, xc, yc);
-          }
-        }
-      }
-    }
-
-    old_iWidth = iWidth;
-    old_iHeight = iHeight;
-    BX_VGA_THIS s.vga_mem_updated = 0;
-    // after a vbe display update, don't try to do any 'normal vga' updates anymore
-    return;
-  }
-#endif  
-  // fields that effect the way video memory is serialized into screen output:
-  // GRAPHICS CONTROLLER:
-  //   BX_VGA_THIS s.graphics_ctrl.shift_reg:
-  //     0: output data in standard VGA format or CGA-compatible 640x200 2 color
-  //        graphics mode (mode 6)
-  //     1: output data in CGA-compatible 320x200 4 color graphics mode
-  //        (modes 4 & 5)
-  //     2: output data 8 bits at a time from the 4 bit planes
-  //        (mode 13 and variants like modeX)
-
-  // if (BX_VGA_THIS s.vga_mem_updated==0 || BX_VGA_THIS s.attribute_ctrl.video_enabled == 0)
-
-  if (BX_VGA_THIS s.graphics_ctrl.graphics_alpha) {
-    Bit8u color;
-    unsigned bit_no, r, c, x, y;
-    unsigned long byte_offset, start_addr;
-    unsigned xc, yc, xti, yti;
-
-    start_addr = (BX_VGA_THIS s.CRTC.reg[0x0c] << 8) | BX_VGA_THIS s.CRTC.reg[0x0d];
-
-//BX_DEBUG(("update: shiftreg=%u, chain4=%u, mapping=%u",
-//  (unsigned) BX_VGA_THIS s.graphics_ctrl.shift_reg,
-//  (unsigned) BX_VGA_THIS s.sequencer.chain_four,
-//  (unsigned) BX_VGA_THIS s.graphics_ctrl.memory_mapping);
-
-    determine_screen_dimensions(&iHeight, &iWidth);
-    if( (iWidth != old_iWidth) || (iHeight != old_iHeight) || (old_BPP > 8) ) {
-      bx_gui->dimension_update(iWidth, iHeight);
-      old_iWidth = iWidth;
-      old_iHeight = iHeight;
-      old_BPP = 8;
-    }
-
-    switch ( BX_VGA_THIS s.graphics_ctrl.shift_reg ) {
-
-      case 0:
-        Bit8u attribute, palette_reg_val, DAC_regno;
-        unsigned long line_compare;
-
-        if (BX_VGA_THIS s.graphics_ctrl.memory_mapping == 3) { // CGA 640x200x2
-
-          for (yc=0, yti=0; yc<iHeight; yc+=Y_TILESIZE, yti++) {
-            for (xc=0, xti=0; xc<iWidth; xc+=X_TILESIZE, xti++) {
-              if (GET_TILE_UPDATED (xti, yti)) {
-                for (r=0; r<Y_TILESIZE; r++) {
-                  y = yc + r;
-                  if (BX_VGA_THIS s.y_doublescan) y >>= 1;
-                  for (c=0; c<X_TILESIZE; c++) {
-
-                    x = xc + c;
-                    /* 0 or 0x2000 */
-                    byte_offset = start_addr + ((y & 1) << 13);
-                    /* to the start of the line */
-                    byte_offset += (320 / 4) * (y / 2);
-                    /* to the byte start */
-                    byte_offset += (x / 8);
-
-                    bit_no = 7 - (x % 8);
-                    palette_reg_val = (((BX_VGA_THIS s.vga_memory[byte_offset]) >> bit_no) & 1);
-                    DAC_regno = BX_VGA_THIS s.attribute_ctrl.palette_reg[palette_reg_val];
-                    BX_VGA_THIS s.tile[r*X_TILESIZE + c] = DAC_regno;
-                  }
-                }
-                SET_TILE_UPDATED (xti, yti, 0);
-                bx_gui->graphics_tile_update(BX_VGA_THIS s.tile, xc, yc);
-              }
-            }
-          }
-        } else { // output data in serial fashion with each display plane
-                 // output on its associated serial output.  Standard EGA/VGA format
-
-          line_compare = BX_VGA_THIS s.line_compare;
-          if (BX_VGA_THIS s.y_doublescan) line_compare >>= 1;
-
-          for (yc=0, yti=0; yc<iHeight; yc+=Y_TILESIZE, yti++) {
-            for (xc=0, xti=0; xc<iWidth; xc+=X_TILESIZE, xti++) {
-              if (GET_TILE_UPDATED (xti, yti)) {
-                for (r=0; r<Y_TILESIZE; r++) {
-                  y = yc + r;
-                  if (BX_VGA_THIS s.y_doublescan) y >>= 1;
-                  for (c=0; c<X_TILESIZE; c++) {
-                    x = xc + c;
-                    if (BX_VGA_THIS s.x_dotclockdiv2) x >>= 1;
-                    bit_no = 7 - (x % 8);
-                    if (y > line_compare) {
-                      byte_offset = x / 8 +
-                        ((y - line_compare - 1) * BX_VGA_THIS s.line_offset);
-                    } else {
-                      byte_offset = start_addr + x / 8 +
-                        (y * BX_VGA_THIS s.line_offset);
-                    }
-                    attribute =
-                      (((BX_VGA_THIS s.vga_memory[0*65536 + byte_offset] >> bit_no) & 0x01) << 0) |
-                      (((BX_VGA_THIS s.vga_memory[1*65536 + byte_offset] >> bit_no) & 0x01) << 1) |
-                      (((BX_VGA_THIS s.vga_memory[2*65536 + byte_offset] >> bit_no) & 0x01) << 2) |
-                      (((BX_VGA_THIS s.vga_memory[3*65536 + byte_offset] >> bit_no) & 0x01) << 3);
-
-                    attribute &= BX_VGA_THIS s.attribute_ctrl.color_plane_enable;
-                    // undocumented feature ???: colors 0..7 high intensity, colors 8..15 blinking
-                    // using low/high intensity. Blinking is not implemented yet.
-                    if (BX_VGA_THIS s.attribute_ctrl.mode_ctrl.blink_intensity) attribute ^= 0x08;
-                    palette_reg_val = BX_VGA_THIS s.attribute_ctrl.palette_reg[attribute];
-                    if (BX_VGA_THIS s.attribute_ctrl.mode_ctrl.internal_palette_size) {
-                      // use 4 lower bits from palette register
-                      // use 4 higher bits from color select register
-                      // 16 banks of 16-color registers
-                      DAC_regno = (palette_reg_val & 0x0f) |
-                                  (BX_VGA_THIS s.attribute_ctrl.color_select << 4);
-                      }
-                    else {
-                      // use 6 lower bits from palette register
-                      // use 2 higher bits from color select register
-                      // 4 banks of 64-color registers
-                      DAC_regno = (palette_reg_val & 0x3f) |
-                                  ((BX_VGA_THIS s.attribute_ctrl.color_select & 0x0c) << 4);
-                      }
-                    // DAC_regno &= video DAC mask register ???
-
-                    BX_VGA_THIS s.tile[r*X_TILESIZE + c] = DAC_regno;
-                    }
-                  }
-                SET_TILE_UPDATED (xti, yti, 0);
-                bx_gui->graphics_tile_update(BX_VGA_THIS s.tile, xc, yc);
-                }
-              }
-            }
-          }
-        break; // case 0
-
-      case 1: // output the data in a CGA-compatible 320x200 4 color graphics
-              // mode.  (modes 4 & 5)
-
-        /* CGA 320x200x4 start */
-
-        for (yc=0, yti=0; yc<iHeight; yc+=Y_TILESIZE, yti++) {
-          for (xc=0, xti=0; xc<iWidth; xc+=X_TILESIZE, xti++) {
-            if (GET_TILE_UPDATED (xti, yti)) {
-              for (r=0; r<Y_TILESIZE; r++) {
-                y = yc + r;
-                if (BX_VGA_THIS s.y_doublescan) y >>= 1;
-                for (c=0; c<X_TILESIZE; c++) {
-
-                  x = xc + c;
-                  if (BX_VGA_THIS s.x_dotclockdiv2) x >>= 1;
-                  /* 0 or 0x2000 */
-                  byte_offset = start_addr + ((y & 1) << 13);
-                  /* to the start of the line */
-                  byte_offset += (320 / 4) * (y / 2);
-                  /* to the byte start */
-                  byte_offset += (x / 4);
-
-                  attribute = 6 - 2*(x % 4);
-                  palette_reg_val = (BX_VGA_THIS s.vga_memory[byte_offset]) >> attribute;
-                  palette_reg_val &= 3;
-                  DAC_regno = BX_VGA_THIS s.attribute_ctrl.palette_reg[palette_reg_val];
-                  BX_VGA_THIS s.tile[r*X_TILESIZE + c] = DAC_regno;
-                }
-              }
-              SET_TILE_UPDATED (xti, yti, 0);
-              bx_gui->graphics_tile_update(BX_VGA_THIS s.tile, xc, yc);
-            }
-          }
-        }
-        /* CGA 320x200x4 end */
-
-        break; // case 1
-
-      case 2: // output the data eight bits at a time from the 4 bit plane
-              // (format for VGA mode 13 hex)
-
-        if ( BX_VGA_THIS s.sequencer.chain_four ) {
-          unsigned long pixely, pixelx, plane;
-          // bx_vga_dump_status();
-
-          if (BX_VGA_THIS s.misc_output.select_high_bank != 1)
-            BX_PANIC(("update: select_high_bank != 1"));
-
-          for (yc=0, yti=0; yc<iHeight; yc+=Y_TILESIZE, yti++) {
-            for (xc=0, xti=0; xc<iWidth; xc+=X_TILESIZE, xti++) {
-              if (GET_TILE_UPDATED (xti, yti)) {
-                for (r=0; r<Y_TILESIZE; r++) {
-                  pixely = yc + r;
-                  if (BX_VGA_THIS s.y_doublescan) pixely >>= 1;
-                  for (c=0; c<X_TILESIZE; c++) {
-                    pixelx = (xc + c) >> 1;
-                    plane  = (pixelx % 4);
-                    byte_offset = start_addr + (plane * 65536) +
-                                  (pixely * BX_VGA_THIS s.line_offset) + (pixelx & ~0x03);
-                    color = BX_VGA_THIS s.vga_memory[byte_offset];
-                    BX_VGA_THIS s.tile[r*X_TILESIZE + c] = color;
-                    }
-                  }
-                SET_TILE_UPDATED (xti, yti, 0);
-                bx_gui->graphics_tile_update(BX_VGA_THIS s.tile, xc, yc);
-                }
-              }
-            }
-          }
-
-        else { // chain_four == 0, modeX
-          unsigned long pixely, pixelx, plane;
-
-          for (yc=0, yti=0; yc<iHeight; yc+=Y_TILESIZE, yti++) {
-            for (xc=0, xti=0; xc<iWidth; xc+=X_TILESIZE, xti++) {
-              if (GET_TILE_UPDATED (xti, yti)) {
-                for (r=0; r<Y_TILESIZE; r++) {
-                  pixely = yc + r;
-                  if (BX_VGA_THIS s.y_doublescan) pixely >>= 1;
-                  for (c=0; c<X_TILESIZE; c++) {
-                    pixelx = (xc + c) >> 1;
-                    plane  = (pixelx % 4);
-                    byte_offset = (plane * 65536) +
-                                  (pixely * BX_VGA_THIS s.line_offset)
-                                  + (pixelx >> 2);
-                    color = BX_VGA_THIS s.vga_memory[start_addr + byte_offset];
-                    BX_VGA_THIS s.tile[r*X_TILESIZE + c] = color;
-                    }
-                  }
-                SET_TILE_UPDATED (xti, yti, 0);
-                bx_gui->graphics_tile_update(BX_VGA_THIS s.tile, xc, yc);
-                }
-             }
-           }
-          }
-        break; // case 2
-
-      default:
-        BX_PANIC(("update: shift_reg == %u", (unsigned)
-          BX_VGA_THIS s.graphics_ctrl.shift_reg ));
-      }
-
-    BX_VGA_THIS s.vga_mem_updated = 0;
-    return;
-    }
-
-  else { // text mode
-    unsigned long start_address;
-    unsigned long cursor_address, cursor_x, cursor_y;
-    bx_vga_tminfo_t tm_info;
-
-
-    tm_info.cs_start = BX_VGA_THIS s.CRTC.reg[0x0a] & 0x3f;
-    tm_info.cs_end = BX_VGA_THIS s.CRTC.reg[0x0b] & 0x1f;
-    tm_info.line_offset = BX_VGA_THIS s.CRTC.reg[0x13] << 2;
-    tm_info.line_compare = BX_VGA_THIS s.line_compare;
-    tm_info.h_panning = BX_VGA_THIS s.attribute_ctrl.horiz_pel_panning & 0x0f;
-    tm_info.v_panning = BX_VGA_THIS s.CRTC.reg[0x08] & 0x1f;
-    tm_info.line_graphics = BX_VGA_THIS s.attribute_ctrl.mode_ctrl.enable_line_graphics;
-    if ((BX_VGA_THIS s.sequencer.reg1 & 0x01) == 0) {
-      if (tm_info.h_panning == 8)
-        tm_info.h_panning = 0;
-      else
-        tm_info.h_panning++;
-    }
-
-    switch (BX_VGA_THIS s.graphics_ctrl.memory_mapping) {
-      case 0: // 128K @ A0000
-      case 1: // 64K @ A0000
-       iWidth = 8*80;  // TODO: should use font size
-       iHeight = 16*25;
-       if( (iWidth != old_iWidth) || (iHeight != old_iHeight) || (old_BPP > 8) )
-       {
-         bx_gui->dimension_update(iWidth, iHeight, 16, 8);
-         old_iWidth = iWidth;
-         old_iHeight = iHeight;
-          old_BPP = 8;
-       }
-        /* pass old text snapshot & new VGA memory contents */
-        start_address = 0x0;
-        cursor_address = 2*((BX_VGA_THIS s.CRTC.reg[0x0e] << 8) |
-                          BX_VGA_THIS s.CRTC.reg[0x0f]);
-        if (cursor_address < start_address) {
-          cursor_x = 0xffff;
-          cursor_y = 0xffff;
-          }
-        else {
-          cursor_x = ((cursor_address - start_address)/2) % 80;
-          cursor_y = ((cursor_address - start_address)/2) / 80;
-          }
-        bx_gui->text_update(BX_VGA_THIS s.text_snapshot,
-                          &BX_VGA_THIS s.vga_memory[start_address],
-                           cursor_x, cursor_y, tm_info, 25);
-        // screen updated, copy new VGA memory contents into text snapshot
-        memcpy(BX_VGA_THIS s.text_snapshot,
-              &BX_VGA_THIS s.vga_memory[start_address],
-               2*80*25);
-        BX_VGA_THIS s.vga_mem_updated = 0;
-        break;
-
-      case 2: // B0000 .. B7FFF
-      case 3: // B8000 .. BFFFF
-        unsigned VDE, MSL, rows, cWidth;
-
-        // Verticle Display End: find out how many lines are displayed
-        VDE = BX_VGA_THIS s.vertical_display_end;
-        // Maximum Scan Line: height of character cell
-        MSL = BX_VGA_THIS s.CRTC.reg[0x09] & 0x1f;
-        if (MSL == 0) {
-          //BX_ERROR(("character height = 1, skipping text update"));
-          return;
-        }
-        if ((MSL == 1) && (BX_VGA_THIS s.CRTC.reg[0x06] == 100)) {
-          // emulated CGA graphics mode 160x100x16 colors
-          MSL = 3;
-          rows = 100;
-          cWidth = 8;
-          iWidth = cWidth * BX_VGA_THIS s.CRTC.reg[1];
-          iHeight = 400;
-        } else {
-          rows = (VDE+1)/(MSL+1);
-          if (rows > BX_MAX_TEXT_LINES)
-            BX_PANIC(("text rows>%d: %d",BX_MAX_TEXT_LINES,rows));
-          cWidth = ((BX_VGA_THIS s.sequencer.reg1 & 0x01) == 1) ? 8 : 9;
-          iWidth = cWidth * (BX_VGA_THIS s.CRTC.reg[1] + 1);
-          iHeight = VDE+1;
-        }
-       if( (iWidth != old_iWidth) || (iHeight != old_iHeight) || (MSL != old_MSL) || (old_BPP > 8) )
-       {
-         bx_gui->dimension_update(iWidth, iHeight, MSL+1, cWidth);
-         old_iWidth = iWidth;
-         old_iHeight = iHeight;
-         old_MSL = MSL;
-          old_BPP = 8;
-       }
-        // pass old text snapshot & new VGA memory contents
-        start_address = 2*((BX_VGA_THIS s.CRTC.reg[12] << 8) + BX_VGA_THIS s.CRTC.reg[13]);
-        cursor_address = 2*((BX_VGA_THIS s.CRTC.reg[0x0e] << 8) |
-                          BX_VGA_THIS s.CRTC.reg[0x0f]);
-        if (cursor_address < start_address) {
-          cursor_x = 0xffff;
-          cursor_y = 0xffff;
-          }
-        else {
-          cursor_x = ((cursor_address - start_address)/2) % (iWidth/cWidth);
-          cursor_y = ((cursor_address - start_address)/2) / (iWidth/cWidth);
-          }
-        bx_gui->text_update(BX_VGA_THIS s.text_snapshot,
-                          &BX_VGA_THIS s.vga_memory[start_address],
-                           cursor_x, cursor_y, tm_info, rows);
-        // screen updated, copy new VGA memory contents into text snapshot
-        memcpy(BX_VGA_THIS s.text_snapshot,
-              &BX_VGA_THIS s.vga_memory[start_address],
-               2*80*rows);
-        BX_VGA_THIS s.vga_mem_updated = 0;
-        break;
-      default:
-        BX_DEBUG(("update(): color text mode: mem map is %u",
-                 (unsigned) BX_VGA_THIS s.graphics_ctrl.memory_mapping));
-      }
-    }
-}
-
-
-  Bit8u
-bx_vga_c::mem_read(Bit32u addr)
-{
-  Bit32u offset;
-
-#if BX_SUPPORT_VBE  
-  // if in a vbe enabled mode, read from the vbe_memory
-  if ((BX_VGA_THIS s.vbe_enabled) && (BX_VGA_THIS s.vbe_bpp != VBE_DISPI_BPP_4))
-  {
-        return vbe_mem_read(addr);
-  }
-#endif  
-
-#if defined(VGA_TRACE_FEATURE)
-//     BX_DEBUG(("8-bit memory read from %08x", addr));
-#endif
-
-#ifdef __OS2__
-
-#if BX_PLUGINS
-#error Fix the code for plugins
-#endif
-
-  if ( bx_options.videomode == BX_VIDEO_DIRECT )
-     {
-     char value;
-
-     value = devices->mem->video[addr-0xA0000];
-
-     return value;
-     }
-#endif
-
-  switch (BX_VGA_THIS s.graphics_ctrl.memory_mapping) {
-    case 1: // 0xA0000 .. 0xAFFFF
-      if (addr > 0xAFFFF) return 0xff;
-      offset = addr - 0xA0000;
-      break;
-    case 2: // 0xB0000 .. 0xB7FFF
-      if ((addr < 0xB0000) || (addr > 0xB7FFF)) return 0xff;
-      return BX_VGA_THIS s.vga_memory[addr - 0xB0000];
-      break;
-    case 3: // 0xB8000 .. 0xBFFFF
-      if (addr < 0xB8000) return 0xff;
-      return BX_VGA_THIS s.vga_memory[addr - 0xB8000];
-      break;
-    default: // 0xA0000 .. 0xBFFFF
-      return BX_VGA_THIS s.vga_memory[addr - 0xA0000];
-    }
-
-  // addr between 0xA0000 and 0xAFFFF
-  if ( BX_VGA_THIS s.sequencer.chain_four ) {
-
-    // Mode 13h: 320 x 200 256 color mode: chained pixel representation
-    return BX_VGA_THIS s.vga_memory[(offset & ~0x03) + (offset % 4)*65536];
-    }
-
-  /* addr between 0xA0000 and 0xAFFFF */
-  switch (BX_VGA_THIS s.graphics_ctrl.read_mode) {
-    case 0: /* read mode 0 */
-      BX_VGA_THIS s.graphics_ctrl.latch[0] = BX_VGA_THIS s.vga_memory[          offset];
-      BX_VGA_THIS s.graphics_ctrl.latch[1] = BX_VGA_THIS s.vga_memory[1*65536 + offset];
-      BX_VGA_THIS s.graphics_ctrl.latch[2] = BX_VGA_THIS s.vga_memory[2*65536 + offset];
-      BX_VGA_THIS s.graphics_ctrl.latch[3] = BX_VGA_THIS s.vga_memory[3*65536 + offset];
-      return(BX_VGA_THIS s.graphics_ctrl.latch[BX_VGA_THIS s.graphics_ctrl.read_map_select]);
-      break;
-
-    case 1: /* read mode 1 */
-      {
-      Bit8u color_compare, color_dont_care;
-      Bit8u latch0, latch1, latch2, latch3, retval;
-
-      color_compare   = BX_VGA_THIS s.graphics_ctrl.color_compare & 0x0f;
-      color_dont_care = BX_VGA_THIS s.graphics_ctrl.color_dont_care & 0x0f;
-      latch0 = BX_VGA_THIS s.graphics_ctrl.latch[0] = BX_VGA_THIS s.vga_memory[          offset];
-      latch1 = BX_VGA_THIS s.graphics_ctrl.latch[1] = BX_VGA_THIS s.vga_memory[1*65536 + offset];
-      latch2 = BX_VGA_THIS s.graphics_ctrl.latch[2] = BX_VGA_THIS s.vga_memory[2*65536 + offset];
-      latch3 = BX_VGA_THIS s.graphics_ctrl.latch[3] = BX_VGA_THIS s.vga_memory[3*65536 + offset];
-
-      latch0 ^= ccdat[color_compare][0];
-      latch1 ^= ccdat[color_compare][1];
-      latch2 ^= ccdat[color_compare][2];
-      latch3 ^= ccdat[color_compare][3];
-
-      latch0 &= ccdat[color_dont_care][0];
-      latch1 &= ccdat[color_dont_care][1];
-      latch2 &= ccdat[color_dont_care][2];
-      latch3 &= ccdat[color_dont_care][3];
-
-      retval = ~(latch0 | latch1 | latch2 | latch3);
-
-      return retval;
-      }
-      break;
-    default:
-      return 0;
-    }
-}
-
-  void
-bx_vga_c::mem_write(Bit32u addr, Bit8u value)
-{
-  Bit32u offset;
-  Bit8u new_val[4];
-  unsigned start_addr;
-
-#if BX_SUPPORT_VBE
-  // if in a vbe enabled mode, write to the vbe_memory
-  if ((BX_VGA_THIS s.vbe_enabled) && (BX_VGA_THIS s.vbe_bpp != VBE_DISPI_BPP_4))
-  {
-        vbe_mem_write(addr,value);
-        return;
-  }
-#endif
-
-#if defined(VGA_TRACE_FEATURE)
-//     BX_DEBUG(("8-bit memory write to %08x = %02x", addr, value));
-#endif
-
-#ifdef __OS2__
-
-#if BX_PLUGINS
-#error Fix the code for plugins
-#endif
-
-  if ( bx_options.videomode == BX_VIDEO_DIRECT )
-    {
-    devices->mem->video[addr-0xA0000] = value;
-
-    return;
-    }
-#endif
-
-  switch (BX_VGA_THIS s.graphics_ctrl.memory_mapping) {
-    case 1: // 0xA0000 .. 0xAFFFF
-      if (addr > 0xAFFFF) return;
-      offset = addr - 0xA0000;
-      break;
-    case 2: // 0xB0000 .. 0xB7FFF
-      if ((addr < 0xB0000) || (addr > 0xB7FFF)) return;
-      offset = addr - 0xB0000;
-      break;
-    case 3: // 0xB8000 .. 0xBFFFF
-      if (addr < 0xB8000) return;
-      offset = addr - 0xB8000;
-      break;
-    default: // 0xA0000 .. 0xBFFFF
-      offset = addr - 0xA0000;
-    }
-
-  start_addr = (BX_VGA_THIS s.CRTC.reg[0x0c] << 8) | BX_VGA_THIS s.CRTC.reg[0x0d];
-
-  if (BX_VGA_THIS s.graphics_ctrl.graphics_alpha) {
-    if (BX_VGA_THIS s.graphics_ctrl.memory_mapping == 3) { // 0xB8000 .. 0xBFFFF
-      unsigned x_tileno, x_tileno2, y_tileno;
-
-      /* CGA 320x200x4 / 640x200x2 start */
-      BX_VGA_THIS s.vga_memory[offset] = value;
-      offset -= start_addr;
-      if (offset>=0x2000) {
-        y_tileno = offset - 0x2000;
-        y_tileno /= (320/4);
-        y_tileno <<= 1; //2 * y_tileno;
-        y_tileno++;
-        x_tileno = (offset - 0x2000) % (320/4);
-        x_tileno <<= 2; //*= 4;
-      } else {
-        y_tileno = offset / (320/4);
-        y_tileno <<= 1; //2 * y_tileno;
-        x_tileno = offset % (320/4);
-        x_tileno <<= 2; //*=4;
-      }
-      x_tileno2=x_tileno;
-      if (BX_VGA_THIS s.graphics_ctrl.shift_reg==0) {
-        x_tileno*=2;
-        x_tileno2+=7;
-      } else {
-        x_tileno2+=3;
-      }
-      if (BX_VGA_THIS s.x_dotclockdiv2) {
-        x_tileno/=(X_TILESIZE/2);
-        x_tileno2/=(X_TILESIZE/2);
-      } else {
-        x_tileno/=X_TILESIZE;
-        x_tileno2/=X_TILESIZE;
-      }
-      if (BX_VGA_THIS s.y_doublescan) {
-        y_tileno/=(Y_TILESIZE/2);
-      } else {
-        y_tileno/=Y_TILESIZE;
-      }
-      BX_VGA_THIS s.vga_mem_updated = 1;
-      SET_TILE_UPDATED (x_tileno, y_tileno, 1);
-      if (x_tileno2!=x_tileno) {
-        SET_TILE_UPDATED (x_tileno2, y_tileno, 1);
-      }
-      return;
-      /* CGA 320x200x4 / 640x200x2 end */
-      }
-    else if (BX_VGA_THIS s.graphics_ctrl.memory_mapping != 1) {
-
-      BX_PANIC(("mem_write: graphics: mapping = %u",
-               (unsigned) BX_VGA_THIS s.graphics_ctrl.memory_mapping));
-      return;
-      }
-
-    if ( BX_VGA_THIS s.sequencer.chain_four ) {
-      unsigned x_tileno, y_tileno;
-
-      // 320 x 200 256 color mode: chained pixel representation
-      BX_VGA_THIS s.vga_memory[(offset & ~0x03) + (offset % 4)*65536] = value;
-      offset -= start_addr;
-      x_tileno = (offset % BX_VGA_THIS s.line_offset) / (X_TILESIZE/2);
-      if (BX_VGA_THIS s.y_doublescan) {
-        y_tileno = (offset / BX_VGA_THIS s.line_offset) / (Y_TILESIZE/2);
-      } else {
-        y_tileno = (offset / BX_VGA_THIS s.line_offset) / Y_TILESIZE;
-      }
-      BX_VGA_THIS s.vga_mem_updated = 1;
-      SET_TILE_UPDATED (x_tileno, y_tileno, 1);
-      return;
-      }
-
-    }
-
-  /* addr between 0xA0000 and 0xAFFFF */
-  switch (BX_VGA_THIS s.graphics_ctrl.write_mode) {
-    unsigned i;
-
-    case 0: /* write mode 0 */
-      {
-        const Bit8u bitmask = BX_VGA_THIS s.graphics_ctrl.bitmask;
-        const Bit8u set_reset = BX_VGA_THIS s.graphics_ctrl.set_reset;
-        const Bit8u enable_set_reset = BX_VGA_THIS s.graphics_ctrl.enable_set_reset;
-        /* perform rotate on CPU data in case its needed */
-        if (BX_VGA_THIS s.graphics_ctrl.data_rotate) {
-          value = (value >> BX_VGA_THIS s.graphics_ctrl.data_rotate) |
-                  (value << (8 - BX_VGA_THIS s.graphics_ctrl.data_rotate));
-        }
-        new_val[0] = BX_VGA_THIS s.graphics_ctrl.latch[0] & ~bitmask;
-        new_val[1] = BX_VGA_THIS s.graphics_ctrl.latch[1] & ~bitmask;
-        new_val[2] = BX_VGA_THIS s.graphics_ctrl.latch[2] & ~bitmask;
-        new_val[3] = BX_VGA_THIS s.graphics_ctrl.latch[3] & ~bitmask;
-        switch (BX_VGA_THIS s.graphics_ctrl.raster_op) {
-          case 0: // replace
-            new_val[0] |= ((enable_set_reset & 1)
-                           ? ((set_reset & 1) ? bitmask : 0)
-                           : (value & bitmask));
-            new_val[1] |= ((enable_set_reset & 2)
-                           ? ((set_reset & 2) ? bitmask : 0)
-                           : (value & bitmask));
-            new_val[2] |= ((enable_set_reset & 4)
-                           ? ((set_reset & 4) ? bitmask : 0)
-                           : (value & bitmask));
-            new_val[3] |= ((enable_set_reset & 8)
-                           ? ((set_reset & 8) ? bitmask : 0)
-                           : (value & bitmask));
-            break;
-          case 1: // AND
-            new_val[0] |= ((enable_set_reset & 1)
-                           ? ((set_reset & 1)
-                              ? (BX_VGA_THIS s.graphics_ctrl.latch[0] & bitmask)
-                              : 0)
-                           : (value & BX_VGA_THIS s.graphics_ctrl.latch[0]) & bitmask);
-            new_val[1] |= ((enable_set_reset & 2)
-                           ? ((set_reset & 2)
-                              ? (BX_VGA_THIS s.graphics_ctrl.latch[1] & bitmask)
-                              : 0)
-                           : (value & BX_VGA_THIS s.graphics_ctrl.latch[1]) & bitmask);
-            new_val[2] |= ((enable_set_reset & 4)
-                           ? ((set_reset & 4)
-                              ? (BX_VGA_THIS s.graphics_ctrl.latch[2] & bitmask)
-                              : 0)
-                           : (value & BX_VGA_THIS s.graphics_ctrl.latch[2]) & bitmask);
-            new_val[3] |= ((enable_set_reset & 8)
-                           ? ((set_reset & 8)
-                              ? (BX_VGA_THIS s.graphics_ctrl.latch[3] & bitmask)
-                              : 0)
-                           : (value & BX_VGA_THIS s.graphics_ctrl.latch[3]) & bitmask);
-            break;
-          case 2: // OR
-            new_val[0]
-              |= ((enable_set_reset & 1)
-                  ? ((set_reset & 1)
-                     ? bitmask
-                     : (BX_VGA_THIS s.graphics_ctrl.latch[0] & bitmask))
-                  : ((value | BX_VGA_THIS s.graphics_ctrl.latch[0]) & bitmask));
-            new_val[1]
-              |= ((enable_set_reset & 2)
-                  ? ((set_reset & 2)
-                     ? bitmask
-                     : (BX_VGA_THIS s.graphics_ctrl.latch[1] & bitmask))
-                  : ((value | BX_VGA_THIS s.graphics_ctrl.latch[1]) & bitmask));
-            new_val[2]
-              |= ((enable_set_reset & 4)
-                  ? ((set_reset & 4)
-                     ? bitmask
-                     : (BX_VGA_THIS s.graphics_ctrl.latch[2] & bitmask))
-                  : ((value | BX_VGA_THIS s.graphics_ctrl.latch[2]) & bitmask));
-            new_val[3]
-              |= ((enable_set_reset & 8)
-                  ? ((set_reset & 8)
-                     ? bitmask
-                     : (BX_VGA_THIS s.graphics_ctrl.latch[3] & bitmask))
-                  : ((value | BX_VGA_THIS s.graphics_ctrl.latch[3]) & bitmask));
-            break;
-          case 3: // XOR
-            new_val[0]
-              |= ((enable_set_reset & 1)
-                 ? ((set_reset & 1)
-                    ? (~BX_VGA_THIS s.graphics_ctrl.latch[0] & bitmask)
-                    : (BX_VGA_THIS s.graphics_ctrl.latch[0] & bitmask))
-                 : (value ^ BX_VGA_THIS s.graphics_ctrl.latch[0]) & bitmask);
-            new_val[1]
-              |= ((enable_set_reset & 2)
-                 ? ((set_reset & 2)
-                    ? (~BX_VGA_THIS s.graphics_ctrl.latch[1] & bitmask)
-                    : (BX_VGA_THIS s.graphics_ctrl.latch[1] & bitmask))
-                 : (value ^ BX_VGA_THIS s.graphics_ctrl.latch[1]) & bitmask);
-            new_val[2]
-              |= ((enable_set_reset & 4)
-                 ? ((set_reset & 4)
-                    ? (~BX_VGA_THIS s.graphics_ctrl.latch[2] & bitmask)
-                    : (BX_VGA_THIS s.graphics_ctrl.latch[2] & bitmask))
-                 : (value ^ BX_VGA_THIS s.graphics_ctrl.latch[2]) & bitmask);
-            new_val[3]
-              |= ((enable_set_reset & 8)
-                 ? ((set_reset & 8)
-                    ? (~BX_VGA_THIS s.graphics_ctrl.latch[3] & bitmask)
-                    : (BX_VGA_THIS s.graphics_ctrl.latch[3] & bitmask))
-                 : (value ^ BX_VGA_THIS s.graphics_ctrl.latch[3]) & bitmask);
-            break;
-          default:
-            BX_PANIC(("vga_mem_write: write mode 0: op = %u",
-                      (unsigned) BX_VGA_THIS s.graphics_ctrl.raster_op));
-        }
-      }
-      break;
-
-    case 1: /* write mode 1 */
-      for (i=0; i<4; i++ ) {
-        new_val[i] = BX_VGA_THIS s.graphics_ctrl.latch[i];
-        }
-      break;
-
-    case 2: /* write mode 2 */
-      {
-        const Bit8u bitmask = BX_VGA_THIS s.graphics_ctrl.bitmask;
-
-        new_val[0] = BX_VGA_THIS s.graphics_ctrl.latch[0] & ~bitmask;
-        new_val[1] = BX_VGA_THIS s.graphics_ctrl.latch[1] & ~bitmask;
-        new_val[2] = BX_VGA_THIS s.graphics_ctrl.latch[2] & ~bitmask;
-        new_val[3] = BX_VGA_THIS s.graphics_ctrl.latch[3] & ~bitmask;
-        switch (BX_VGA_THIS s.graphics_ctrl.raster_op) {
-          case 0: // write
-            new_val[0] |= (value & 1) ? bitmask : 0;
-            new_val[1] |= (value & 2) ? bitmask : 0;
-            new_val[2] |= (value & 4) ? bitmask : 0;
-            new_val[3] |= (value & 8) ? bitmask : 0;
-            break;
-          case 1: // AND
-            new_val[0] |= (value & 1)
-              ? (BX_VGA_THIS s.graphics_ctrl.latch[0] & bitmask)
-              : 0;
-            new_val[1] |= (value & 2)
-              ? (BX_VGA_THIS s.graphics_ctrl.latch[1] & bitmask)
-              : 0;
-            new_val[2] |= (value & 4)
-              ? (BX_VGA_THIS s.graphics_ctrl.latch[2] & bitmask)
-              : 0;
-            new_val[3] |= (value & 8)
-              ? (BX_VGA_THIS s.graphics_ctrl.latch[3] & bitmask)
-              : 0;
-            break;
-          case 2: // OR
-            new_val[0] |= (value & 1)
-              ? bitmask
-              : (BX_VGA_THIS s.graphics_ctrl.latch[0] & bitmask);
-            new_val[1] |= (value & 2)
-              ? bitmask
-              : (BX_VGA_THIS s.graphics_ctrl.latch[1] & bitmask);
-            new_val[2] |= (value & 4)
-              ? bitmask
-              : (BX_VGA_THIS s.graphics_ctrl.latch[2] & bitmask);
-            new_val[3] |= (value & 8)
-              ? bitmask
-              : (BX_VGA_THIS s.graphics_ctrl.latch[3] & bitmask);
-            break;
-          case 3: // XOR
-            new_val[0] |= (value & 1)
-              ? (~BX_VGA_THIS s.graphics_ctrl.latch[0] & bitmask)
-              : (BX_VGA_THIS s.graphics_ctrl.latch[0] & bitmask);
-            new_val[1] |= (value & 2)
-              ? (~BX_VGA_THIS s.graphics_ctrl.latch[1] & bitmask)
-              : (BX_VGA_THIS s.graphics_ctrl.latch[1] & bitmask);
-            new_val[2] |= (value & 4)
-              ? (~BX_VGA_THIS s.graphics_ctrl.latch[2] & bitmask)
-              : (BX_VGA_THIS s.graphics_ctrl.latch[2] & bitmask);
-            new_val[3] |= (value & 8)
-              ? (~BX_VGA_THIS s.graphics_ctrl.latch[3] & bitmask)
-              : (BX_VGA_THIS s.graphics_ctrl.latch[3] & bitmask);
-            break;
-        }
-      }
-      break;
-
-    case 3: /* write mode 3 */
-      {
-        const Bit8u bitmask = BX_VGA_THIS s.graphics_ctrl.bitmask & value;
-        const Bit8u set_reset = BX_VGA_THIS s.graphics_ctrl.set_reset;
-
-        /* perform rotate on CPU data */
-        if (BX_VGA_THIS s.graphics_ctrl.data_rotate) {
-          value = (value >> BX_VGA_THIS s.graphics_ctrl.data_rotate) |
-                  (value << (8 - BX_VGA_THIS s.graphics_ctrl.data_rotate));
-        }
-        new_val[0] = BX_VGA_THIS s.graphics_ctrl.latch[0] & ~bitmask;
-        new_val[1] = BX_VGA_THIS s.graphics_ctrl.latch[1] & ~bitmask;
-        new_val[2] = BX_VGA_THIS s.graphics_ctrl.latch[2] & ~bitmask;
-        new_val[3] = BX_VGA_THIS s.graphics_ctrl.latch[3] & ~bitmask;
-
-        value &= bitmask;
-
-        switch (BX_VGA_THIS s.graphics_ctrl.raster_op) {
-          case 0: // write
-            new_val[0] |= (set_reset & 1) ? value : 0;
-            new_val[1] |= (set_reset & 2) ? value : 0;
-            new_val[2] |= (set_reset & 4) ? value : 0;
-            new_val[3] |= (set_reset & 8) ? value : 0;
-            break;
-          case 1: // AND
-            new_val[0] |= ((set_reset & 1) ? value : 0)
-              & BX_VGA_THIS s.graphics_ctrl.latch[0];
-            new_val[1] |= ((set_reset & 2) ? value : 0)
-              & BX_VGA_THIS s.graphics_ctrl.latch[1];
-            new_val[2] |= ((set_reset & 4) ? value : 0)
-              & BX_VGA_THIS s.graphics_ctrl.latch[2];
-            new_val[3] |= ((set_reset & 8) ? value : 0)
-              & BX_VGA_THIS s.graphics_ctrl.latch[3];
-            break;
-          case 2: // OR
-            new_val[0] |= ((set_reset & 1) ? value : 0)
-              | BX_VGA_THIS s.graphics_ctrl.latch[0];
-            new_val[1] |= ((set_reset & 2) ? value : 0)
-              | BX_VGA_THIS s.graphics_ctrl.latch[1];
-            new_val[2] |= ((set_reset & 4) ? value : 0)
-              | BX_VGA_THIS s.graphics_ctrl.latch[2];
-            new_val[3] |= ((set_reset & 8) ? value : 0)
-              | BX_VGA_THIS s.graphics_ctrl.latch[3];
-            break;
-          case 3: // XOR
-            new_val[0] |= ((set_reset & 1) ? value : 0)
-              ^ BX_VGA_THIS s.graphics_ctrl.latch[0];
-            new_val[1] |= ((set_reset & 2) ? value : 0)
-              ^ BX_VGA_THIS s.graphics_ctrl.latch[1];
-            new_val[2] |= ((set_reset & 4) ? value : 0)
-              ^ BX_VGA_THIS s.graphics_ctrl.latch[2];
-            new_val[3] |= ((set_reset & 8) ? value : 0)
-              ^ BX_VGA_THIS s.graphics_ctrl.latch[3];
-            break;
-        }
-      }
-      break;
-
-    default:
-      BX_PANIC(("vga_mem_write: write mode %u ?",
-        (unsigned) BX_VGA_THIS s.graphics_ctrl.write_mode));
-  }
-
-  if (BX_VGA_THIS s.sequencer.map_mask & 0x0f) {
-    BX_VGA_THIS s.vga_mem_updated = 1;
-    if (BX_VGA_THIS s.sequencer.map_mask_bit[0])
-      BX_VGA_THIS s.vga_memory[0*65536 + offset] = new_val[0];
-    if (BX_VGA_THIS s.sequencer.map_mask_bit[1])
-      BX_VGA_THIS s.vga_memory[1*65536 + offset] = new_val[1];
-    if (BX_VGA_THIS s.sequencer.map_mask_bit[2]) {
-      if ((!BX_VGA_THIS s.graphics_ctrl.graphics_alpha) &&
-          ((offset & 0xe000) == BX_VGA_THIS s.charmap_address)) {
-        bx_gui->set_text_charbyte((offset & 0x1fff), new_val[2]);
-        }
-      BX_VGA_THIS s.vga_memory[2*65536 + offset] = new_val[2];
-      }
-    if (BX_VGA_THIS s.sequencer.map_mask_bit[3])
-      BX_VGA_THIS s.vga_memory[3*65536 + offset] = new_val[3];
-
-    unsigned x_tileno, y_tileno;
-
-    if (BX_VGA_THIS s.graphics_ctrl.shift_reg == 2) {
-      offset -= start_addr;
-      x_tileno = (offset % BX_VGA_THIS s.line_offset) * 4 / (X_TILESIZE / 2);
-      if (BX_VGA_THIS s.y_doublescan) {
-        y_tileno = (offset / BX_VGA_THIS s.line_offset) / (Y_TILESIZE / 2);
-      } else {
-        y_tileno = (offset / BX_VGA_THIS s.line_offset) / Y_TILESIZE;
-      }
-      SET_TILE_UPDATED (x_tileno, y_tileno, 1);
-    } else {
-      if (BX_VGA_THIS s.line_compare < BX_VGA_THIS s.vertical_display_end) {
-        if (BX_VGA_THIS s.x_dotclockdiv2) {
-          x_tileno = (offset % BX_VGA_THIS s.line_offset) / (X_TILESIZE / 16);
-        } else {
-          x_tileno = (offset % BX_VGA_THIS s.line_offset) / (X_TILESIZE / 8);
-        }
-        if (BX_VGA_THIS s.y_doublescan) {
-          y_tileno = ((offset / BX_VGA_THIS s.line_offset) * 2 + BX_VGA_THIS s.line_compare + 1) / Y_TILESIZE;
-        } else {
-          y_tileno = ((offset / BX_VGA_THIS s.line_offset) + BX_VGA_THIS s.line_compare + 1) / Y_TILESIZE;
-        }
-        SET_TILE_UPDATED (x_tileno, y_tileno, 1);
-      }
-      if (offset >= start_addr) {
-        offset -= start_addr;
-        if (BX_VGA_THIS s.x_dotclockdiv2) {
-          x_tileno = (offset % BX_VGA_THIS s.line_offset) / (X_TILESIZE / 16);
-        } else {
-          x_tileno = (offset % BX_VGA_THIS s.line_offset) / (X_TILESIZE / 8);
-        }
-        if (BX_VGA_THIS s.y_doublescan) {
-          y_tileno = (offset / BX_VGA_THIS s.line_offset) / (Y_TILESIZE / 2);
-        } else {
-          y_tileno = (offset / BX_VGA_THIS s.line_offset) / Y_TILESIZE;
-        }
-        SET_TILE_UPDATED (x_tileno, y_tileno, 1);
-      }
-    }
-  }
-}
-
-  void
-bx_vga_c::get_text_snapshot(Bit8u **text_snapshot, unsigned *txHeight,
-                                                   unsigned *txWidth)
-{
-  unsigned VDE, MSL;
-
-  if (!BX_VGA_THIS s.graphics_ctrl.graphics_alpha) {
-    *text_snapshot = &BX_VGA_THIS s.text_snapshot[0];
-    VDE = BX_VGA_THIS s.vertical_display_end;
-    MSL = BX_VGA_THIS s.CRTC.reg[0x09] & 0x1f;
-    *txHeight = (VDE+1)/(MSL+1);
-    *txWidth = BX_VGA_THIS s.CRTC.reg[1] + 1;
-  } else {
-    *txHeight = 0;
-    *txWidth = 0;
-  }
-}
-
-  Bit8u
-bx_vga_c::get_actl_palette_idx(Bit8u index)
-{
-  return BX_VGA_THIS s.attribute_ctrl.palette_reg[index];
-}
-
-  void
-bx_vga_c::dump_status(void)
-{
-  BX_INFO(("s.misc_output.color_emulation = %u",
-            (unsigned) BX_VGA_THIS s.misc_output.color_emulation));
-  BX_INFO(("s.misc_output.enable_ram = %u",
-            (unsigned) BX_VGA_THIS s.misc_output.enable_ram));
-  BX_INFO(("s.misc_output.clock_select = %u",
-            (unsigned) BX_VGA_THIS s.misc_output.clock_select));
-  if (BX_VGA_THIS s.misc_output.clock_select == 0)
-    BX_INFO(("  25Mhz 640 horiz pixel clock"));
-  else
-    BX_INFO(("  28Mhz 720 horiz pixel clock"));
-  BX_INFO(("s.misc_output.select_high_bank = %u",
-            (unsigned) BX_VGA_THIS s.misc_output.select_high_bank));
-  BX_INFO(("s.misc_output.horiz_sync_pol = %u",
-            (unsigned) BX_VGA_THIS s.misc_output.horiz_sync_pol));
-  BX_INFO(("s.misc_output.vert_sync_pol = %u",
-            (unsigned) BX_VGA_THIS s.misc_output.vert_sync_pol));
-  switch ( (BX_VGA_THIS s.misc_output.vert_sync_pol << 1) |
-           BX_VGA_THIS s.misc_output.horiz_sync_pol ) {
-    case 0: BX_INFO(("  (reserved")); break;
-    case 1: BX_INFO(("  400 lines")); break;
-    case 2: BX_INFO(("  350 lines")); break;
-    case 3: BX_INFO(("  480 lines")); break;
-    default: BX_INFO(("  ???"));
-    }
-
-  BX_INFO(("s.graphics_ctrl.odd_even = %u",
-            (unsigned) BX_VGA_THIS s.graphics_ctrl.odd_even));
-  BX_INFO(("s.graphics_ctrl.chain_odd_even = %u",
-            (unsigned) BX_VGA_THIS s.graphics_ctrl.chain_odd_even));
-  BX_INFO(("s.graphics_ctrl.shift_reg = %u",
-            (unsigned) BX_VGA_THIS s.graphics_ctrl.shift_reg));
-  BX_INFO(("s.graphics_ctrl.graphics_alpha = %u",
-            (unsigned) BX_VGA_THIS s.graphics_ctrl.graphics_alpha));
-  BX_INFO(("s.graphics_ctrl.memory_mapping = %u",
-            (unsigned) BX_VGA_THIS s.graphics_ctrl.memory_mapping));
-  switch (BX_VGA_THIS s.graphics_ctrl.memory_mapping) {
-    case 0: BX_INFO(("  A0000-BFFFF")); break;
-    case 1: BX_INFO(("  A0000-AFFFF")); break;
-    case 2: BX_INFO(("  B0000-B7FFF")); break;
-    case 3: BX_INFO(("  B8000-BFFFF")); break;
-    default: BX_INFO(("  ???"));
-    }
-
-  BX_INFO(("s.sequencer.extended_mem = %u",
-            (unsigned) BX_VGA_THIS s.sequencer.extended_mem));
-  BX_INFO(("s.sequencer.odd_even = %u (inverted)",
-            (unsigned) BX_VGA_THIS s.sequencer.odd_even));
-  BX_INFO(("s.sequencer.chain_four = %u",
-            (unsigned) BX_VGA_THIS s.sequencer.chain_four));
-
-  BX_INFO(("s.attribute_ctrl.video_enabled = %u",
-            (unsigned) BX_VGA_THIS s.attribute_ctrl.video_enabled));
-  BX_INFO(("s.attribute_ctrl.mode_ctrl.graphics_alpha = %u",
-            (unsigned) BX_VGA_THIS s.attribute_ctrl.mode_ctrl.graphics_alpha));
-  BX_INFO(("s.attribute_ctrl.mode_ctrl.display_type = %u",
-            (unsigned) BX_VGA_THIS s.attribute_ctrl.mode_ctrl.display_type));
-  BX_INFO(("s.attribute_ctrl.mode_ctrl.internal_palette_size = %u",
-            (unsigned) BX_VGA_THIS s.attribute_ctrl.mode_ctrl.internal_palette_size));
-  BX_INFO(("s.attribute_ctrl.mode_ctrl.pixel_clock_select = %u",
-            (unsigned) BX_VGA_THIS s.attribute_ctrl.mode_ctrl.pixel_clock_select));
-}
-
-
-  void
-bx_vga_c::redraw_area(unsigned x0, unsigned y0, unsigned width,
-                      unsigned height)
-{
-  unsigned xi, yi, x1, y1, xmax, ymax;
-
-  BX_VGA_THIS s.vga_mem_updated = 1;
-
-#if BX_SUPPORT_VBE
-  if (BX_VGA_THIS s.graphics_ctrl.graphics_alpha || BX_VGA_THIS s.vbe_enabled) {
-#else
-  if (BX_VGA_THIS s.graphics_ctrl.graphics_alpha) {
-#endif
-    // graphics mode
-    x1 = x0 + width  - 1;
-    y1 = y0 + height - 1;
-
-    xmax = old_iWidth;
-    ymax = old_iHeight;
-#if BX_SUPPORT_VBE
-    if (BX_VGA_THIS s.vbe_enabled) {
-      xmax = BX_VGA_THIS s.vbe_xres;
-      ymax = BX_VGA_THIS s.vbe_yres;
-    }
-#endif
-    for (yi=0; yi<ymax; yi+=Y_TILESIZE) {
-      for (xi=0; xi<xmax; xi+=X_TILESIZE) {
-        // is redraw rectangle outside x boundaries of this tile?
-        if (x1 < xi) continue;
-        if (x0 > (xi+X_TILESIZE-1)) continue;
-
-        // is redraw rectangle outside y boundaries of this tile?
-        if (y1 < yi) continue;
-        if (y0 > (yi+Y_TILESIZE-1)) continue;
-       unsigned xti = xi/X_TILESIZE;
-       unsigned yti = yi/Y_TILESIZE;
-        SET_TILE_UPDATED (xti, yti, 1);
-        }
-      }
-    }
-  else {
-    // text mode
-    memset(BX_VGA_THIS s.text_snapshot, 0,
-           sizeof(BX_VGA_THIS s.text_snapshot));
-    }
-}
-
-
-#if BX_SUPPORT_VBE
-  Bit8u  BX_CPP_AttrRegparmN(1)
-bx_vga_c::vbe_mem_read(Bit32u addr)
-{
-  Bit32u offset;
-
-  if (addr >= VBE_DISPI_LFB_PHYSICAL_ADDRESS)
-  {
-    // LFB read
-    offset = addr - VBE_DISPI_LFB_PHYSICAL_ADDRESS;
-  }
-  else
-  {
-    // banked mode read
-    offset = BX_VGA_THIS s.vbe_bank*65536 + addr - 0xA0000;
-  }
-
-  // check for out of memory read
-  if (offset > VBE_DISPI_TOTAL_VIDEO_MEMORY_BYTES)
-    return 0;
-
-  return (BX_VGA_THIS s.vbe_memory[offset]);
-}
-
-  void BX_CPP_AttrRegparmN(2)
-bx_vga_c::vbe_mem_write(Bit32u addr, Bit8u value)
-{
-  Bit32u offset;
-  unsigned x_tileno, y_tileno;
-
-  if (BX_VGA_THIS s.vbe_lfb_enabled)
-  {
-    if (addr >= VBE_DISPI_LFB_PHYSICAL_ADDRESS)
-    {
-      // LFB write
-      offset = addr - VBE_DISPI_LFB_PHYSICAL_ADDRESS;
-    }
-    else
-    {
-      // banked mode write while in LFB mode -> ignore
-      return;
-    }
-  }
-  else
-  {
-    if (addr < VBE_DISPI_LFB_PHYSICAL_ADDRESS)
-    {
-      // banked mode write
-      offset = (BX_VGA_THIS s.vbe_bank*65536) + (addr - 0xA0000);
-    }
-    else
-    {
-      // LFB write while in banked mode -> ignore
-      return;
-    }
-  }
-
-  // check for out of memory write
-  if (offset < VBE_DISPI_TOTAL_VIDEO_MEMORY_BYTES)
-  {
-    BX_VGA_THIS s.vbe_memory[offset]=value;
-  }
-  else
-  {
-    // make sure we don't flood the logfile
-    static int count=0;
-    if (count<100)
-    {
-      count ++;
-      BX_INFO(("VBE_mem_write out of video memory write at %x",offset));
-    }
-  }
-
-  offset-=BX_VGA_THIS s.vbe_virtual_start;
-
-  // only update the UI when writing 'onscreen'
-  if (offset < BX_VGA_THIS s.vbe_visable_screen_size)
-  {
-    y_tileno = ((offset / BX_VGA_THIS s.vbe_bpp_multiplier) / BX_VGA_THIS s.vbe_virtual_xres) / Y_TILESIZE;
-    x_tileno = ((offset / BX_VGA_THIS s.vbe_bpp_multiplier) % BX_VGA_THIS s.vbe_virtual_xres) / X_TILESIZE;
-
-    if ((y_tileno < BX_NUM_Y_TILES) && (x_tileno < BX_NUM_X_TILES))
-    {
-      BX_VGA_THIS s.vga_mem_updated = 1;
-      SET_TILE_UPDATED (x_tileno, y_tileno, 1);
-    }
-  }  
-}
-
-  Bit32u
-bx_vga_c::vbe_read_handler(void *this_ptr, Bit32u address, unsigned io_len)
-{
-#if !BX_USE_VGA_SMF
-  bx_vga_c *class_ptr = (bx_vga_c *) this_ptr;
-
-  return( class_ptr->vbe_read(address, io_len) );
-}
-
-
-  Bit32u
-bx_vga_c::vbe_read(Bit32u address, unsigned io_len)
-{
-#else
-  UNUSED(this_ptr);
-#endif  // !BX_USE_VGA_SMF
-
-//  BX_INFO(("VBE_read %x (len %x)", address, io_len));
-
-  if ((address==VBE_DISPI_IOPORT_INDEX) ||
-      (address==VBE_DISPI_IOPORT_INDEX_OLD))
-  {
-    // index register
-    return (Bit32u) BX_VGA_THIS s.vbe_curindex;
-  }
-  else
-  {
-    // data register read
-    
-    switch (BX_VGA_THIS s.vbe_curindex)
-    {
-      case VBE_DISPI_INDEX_ID: // Display Interface ID check
-      {
-        return BX_VGA_THIS s.vbe_cur_dispi;
-      } break;
-      
-      case VBE_DISPI_INDEX_XRES: // x resolution
-      {
-        return BX_VGA_THIS s.vbe_xres;
-      } break;
-
-      case VBE_DISPI_INDEX_YRES: // y resolution
-      {
-        return BX_VGA_THIS s.vbe_yres;
-      } break;
-      
-      case VBE_DISPI_INDEX_BPP: // bpp
-      {
-        return BX_VGA_THIS s.vbe_bpp;
-      } break;
-
-      case VBE_DISPI_INDEX_ENABLE: // vbe enabled
-      {
-        return BX_VGA_THIS s.vbe_enabled;
-      } break;
-      
-      case VBE_DISPI_INDEX_BANK: // current bank
-      {
-        return BX_VGA_THIS s.vbe_bank;
-      } break;
-
-      case VBE_DISPI_INDEX_X_OFFSET:
-      {
-       return BX_VGA_THIS s.vbe_offset_x;
-      } break;
-
-      case VBE_DISPI_INDEX_Y_OFFSET:
-      {
-       return BX_VGA_THIS s.vbe_offset_y;
-      } break;
-
-      case VBE_DISPI_INDEX_VIRT_WIDTH:
-      {
-       return BX_VGA_THIS s.vbe_virtual_xres;
-       
-      } break;
-      
-      case VBE_DISPI_INDEX_VIRT_HEIGHT:
-      {
-       return BX_VGA_THIS s.vbe_virtual_yres;          
-      } break;
-        
-
-      default:
-      {
-        BX_PANIC(("VBE unknown data read index 0x%x",BX_VGA_THIS s.vbe_curindex));
-      } break;
-    }      
-  }
-  BX_PANIC(("VBE_read shouldn't reach this"));
-  return 0; /* keep compiler happy */
-}
-
-  void
-bx_vga_c::vbe_write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len)
-{
-#if !BX_USE_VGA_SMF
-  bx_vga_c *class_ptr = (bx_vga_c *) this_ptr;
-
-  class_ptr->vbe_write(address, value, io_len);
-}
-
-  Bit32u
-bx_vga_c::vbe_write(Bit32u address, Bit32u value, unsigned io_len)
-{ 
-#else
-  UNUSED(this_ptr);
-#endif  
-
-//  BX_INFO(("VBE_write %x = %x (len %x)", address, value, io_len));
-  
-  switch(address)
-  {
-    // index register    
-    case VBE_DISPI_IOPORT_INDEX:
-    // legacy index register    
-    case VBE_DISPI_IOPORT_INDEX_OLD:
-
-      BX_VGA_THIS s.vbe_curindex = (Bit16u) value;
-      break;
-
-    // data register
-    // FIXME: maybe do some 'sanity' checks on received data?
-    case VBE_DISPI_IOPORT_DATA:
-    // legacy data register
-    case VBE_DISPI_IOPORT_DATA_OLD:
-      switch (BX_VGA_THIS s.vbe_curindex)
-      {
-        case VBE_DISPI_INDEX_ID: // Display Interface ID check
-        {
-          if ( (value == VBE_DISPI_ID0) ||
-               (value == VBE_DISPI_ID1) ||
-               (value == VBE_DISPI_ID2) )
-          {
-            // allow backwards compatible with previous dispi bioses
-            BX_VGA_THIS s.vbe_cur_dispi=value;
-          }
-          else
-          {
-            BX_PANIC(("VBE unknown Display Interface %x",value));
-          }
-
-          // make sure we don't flood the logfile
-          static int count=0;
-          if (count < 100)
-          {
-            count++;
-            BX_INFO(("VBE known Display Interface %x",value));
-          }
-        } break;
-
-        case VBE_DISPI_INDEX_XRES: // set xres
-        {
-          // check that we don't set xres during vbe enabled
-          if (!BX_VGA_THIS s.vbe_enabled)
-          {
-            // check for within max xres range
-            if (value <= VBE_DISPI_MAX_XRES)
-            {
-              BX_VGA_THIS s.vbe_xres=(Bit16u) value;
-              BX_INFO(("VBE set xres (%d)",value));
-            }
-            else
-            {
-              BX_INFO(("VBE set xres more then max xres (%d)",value));
-            }
-          }
-          else
-          {
-            BX_INFO(("VBE set xres during vbe enabled!"));
-          }
-        } break;
-
-        case VBE_DISPI_INDEX_YRES: // set yres
-        {
-          // check that we don't set yres during vbe enabled
-          if (!BX_VGA_THIS s.vbe_enabled)
-          {
-            // check for within max yres range
-            if (value <= VBE_DISPI_MAX_YRES)
-            {
-              BX_VGA_THIS s.vbe_yres=(Bit16u) value;
-              BX_INFO(("VBE set yres (%d)",value));
-            }
-            else
-            {
-              BX_INFO(("VBE set yres more then max yres (%d)",value));
-            }
-          }
-          else
-          {
-            BX_INFO(("VBE set yres during vbe enabled!"));
-          }
-        } break;
-
-        case VBE_DISPI_INDEX_BPP: // set bpp
-        {
-          // check that we don't set bpp during vbe enabled
-          if (!BX_VGA_THIS s.vbe_enabled)
-          {
-            // for backward compatiblity
-            if (value == 0) value = VBE_DISPI_BPP_8;
-            // check for correct bpp range
-            if ((value == VBE_DISPI_BPP_4) || (value == VBE_DISPI_BPP_8) || (value == VBE_DISPI_BPP_15) ||
-                (value == VBE_DISPI_BPP_16) || (value == VBE_DISPI_BPP_24) || (value == VBE_DISPI_BPP_32))
-            {
-              BX_VGA_THIS s.vbe_bpp=(Bit16u) value;
-              BX_INFO(("VBE set bpp (%d)",value));
-            }
-            else
-            {
-              BX_INFO(("VBE set bpp with unknown bpp (%d)",value));
-            }
-          }
-          else
-          {
-            BX_INFO(("VBE set bpp during vbe enabled!"));
-          }
-        } break;
-
-        case VBE_DISPI_INDEX_BANK: // set bank
-        {
-          value=value & 0xff ; // FIXME lobyte = vbe bank A?
-
-          // check for max bank nr
-          if (value < (VBE_DISPI_TOTAL_VIDEO_MEMORY_KB /64))
-          {
-            if (!BX_VGA_THIS s.vbe_lfb_enabled)
-            {
-              BX_DEBUG(("VBE set bank to %d", value));
-              BX_VGA_THIS s.vbe_bank=value;
-            }
-            else
-            {
-              BX_ERROR(("VBE set bank in LFB mode ignored"));
-            }
-          }
-          else
-          {
-            BX_INFO(("VBE set invalid bank (%d)",value));
-          }
-        } break;
-
-        case VBE_DISPI_INDEX_ENABLE: // enable video
-        {
-          if (value & VBE_DISPI_ENABLED)
-          {
-            unsigned depth=0;
-
-            // setup virtual resolution to be the same as current reso      
-            BX_VGA_THIS s.vbe_virtual_yres=BX_VGA_THIS s.vbe_yres;
-            BX_VGA_THIS s.vbe_virtual_xres=BX_VGA_THIS s.vbe_xres;
-
-            // reset offset
-            BX_VGA_THIS s.vbe_offset_x=0;
-            BX_VGA_THIS s.vbe_offset_y=0;
-            BX_VGA_THIS s.vbe_virtual_start=0;
-
-            switch((BX_VGA_THIS s.vbe_bpp))
-            {
-              // Default pixel sizes
-              case VBE_DISPI_BPP_8: 
-                BX_VGA_THIS s.vbe_bpp_multiplier = 1;
-                BX_VGA_THIS s.vbe_line_byte_width = BX_VGA_THIS s.vbe_virtual_xres;
-                BX_VGA_THIS s.vbe_visable_screen_size = ((BX_VGA_THIS s.vbe_xres) * (BX_VGA_THIS s.vbe_yres));
-                depth=8;
-                break;
-
-              case VBE_DISPI_BPP_4: 
-                BX_VGA_THIS s.vbe_bpp_multiplier = 1;
-                BX_VGA_THIS s.vbe_line_byte_width = BX_VGA_THIS s.vbe_virtual_xres;
-                BX_VGA_THIS s.vbe_visable_screen_size = ((BX_VGA_THIS s.vbe_xres) * (BX_VGA_THIS s.vbe_yres));
-                depth=4;
-                break;
-
-              case VBE_DISPI_BPP_15:
-                BX_VGA_THIS s.vbe_bpp_multiplier = 2; 
-                BX_VGA_THIS s.vbe_line_byte_width = BX_VGA_THIS s.vbe_virtual_xres * 2;
-                BX_VGA_THIS s.vbe_visable_screen_size = ((BX_VGA_THIS s.vbe_xres) * (BX_VGA_THIS s.vbe_yres)) * 2;
-                depth=15;
-                break;                   
-
-              case VBE_DISPI_BPP_16:
-                BX_VGA_THIS s.vbe_bpp_multiplier = 2; 
-                BX_VGA_THIS s.vbe_line_byte_width = BX_VGA_THIS s.vbe_virtual_xres * 2;
-                BX_VGA_THIS s.vbe_visable_screen_size = ((BX_VGA_THIS s.vbe_xres) * (BX_VGA_THIS s.vbe_yres)) * 2;
-                depth=16;
-                break;                   
-
-              case VBE_DISPI_BPP_24: 
-                BX_VGA_THIS s.vbe_bpp_multiplier = 3; 
-                BX_VGA_THIS s.vbe_line_byte_width = BX_VGA_THIS s.vbe_virtual_xres * 3;
-                BX_VGA_THIS s.vbe_visable_screen_size = ((BX_VGA_THIS s.vbe_xres) * (BX_VGA_THIS s.vbe_yres)) * 3;
-                depth=24;
-                break;                   
-
-              case VBE_DISPI_BPP_32: 
-                BX_VGA_THIS s.vbe_bpp_multiplier = 4; 
-                BX_VGA_THIS s.vbe_line_byte_width = BX_VGA_THIS s.vbe_virtual_xres << 2;
-                BX_VGA_THIS s.vbe_visable_screen_size = ((BX_VGA_THIS s.vbe_xres) * (BX_VGA_THIS s.vbe_yres)) << 2;
-                depth=32;
-                break;                   
-            }
-
-            BX_INFO(("VBE enabling x %d, y %d, bpp %d, %u bytes visible", BX_VGA_THIS s.vbe_xres, BX_VGA_THIS s.vbe_yres, BX_VGA_THIS s.vbe_bpp, BX_VGA_THIS s.vbe_visable_screen_size));
-
-            if (depth > 4)
-            {
-              BX_VGA_THIS s.vbe_lfb_enabled=(bx_bool)(value & VBE_DISPI_LFB_ENABLED);
-              if ((value & VBE_DISPI_NOCLEARMEM) == 0)
-              {
-                memset(BX_VGA_THIS s.vbe_memory, 0, BX_VGA_THIS s.vbe_visable_screen_size);
-              }
-              bx_gui->dimension_update(BX_VGA_THIS s.vbe_xres, BX_VGA_THIS s.vbe_yres, 0, 0, depth);
-              old_BPP = depth;
-              // some test applications expect these standard VGA settings
-              BX_VGA_THIS s.CRTC.reg[9] = 0x00;
-              BX_VGA_THIS s.attribute_ctrl.mode_ctrl.graphics_alpha = 1;
-              BX_VGA_THIS s.graphics_ctrl.memory_mapping = 1;
-              BX_VGA_THIS s.CRTC.reg[1] = (BX_VGA_THIS s.vbe_xres / 8) - 1;
-              BX_VGA_THIS s.CRTC.reg[19] = BX_VGA_THIS s.vbe_xres >> 2;
-              BX_VGA_THIS s.attribute_ctrl.mode_ctrl.pixel_clock_select = 1;
-              BX_VGA_THIS s.CRTC.reg[18] = (BX_VGA_THIS s.vbe_yres - 1) & 0xff;
-              BX_VGA_THIS s.CRTC.reg[7] &= ~0x42;
-              if ((BX_VGA_THIS s.vbe_yres - 1) & 0x0100) {
-                BX_VGA_THIS s.CRTC.reg[7] |= 0x02;
-              }
-              if ((BX_VGA_THIS s.vbe_yres - 1) & 0x0200) {
-                BX_VGA_THIS s.CRTC.reg[7] |= 0x40;
-              }
-            }
-          }
-          else
-          {
-            if (BX_VGA_THIS s.vbe_enabled) BX_INFO(("VBE disabling"));
-            BX_VGA_THIS s.vbe_lfb_enabled=0;
-          }     
-          BX_VGA_THIS s.vbe_enabled=(bx_bool)(value & VBE_DISPI_ENABLED);
-        } break;
-
-        case VBE_DISPI_INDEX_X_OFFSET:
-        {
-          // BX_INFO(("VBE offset x %x",value));
-          BX_VGA_THIS s.vbe_offset_x=(Bit16u)value;
-
-          BX_VGA_THIS s.vbe_virtual_start = ((BX_VGA_THIS s.vbe_offset_y) * (BX_VGA_THIS s.vbe_line_byte_width)) +
-                                             ((BX_VGA_THIS s.vbe_offset_x) * (BX_VGA_THIS s.vbe_bpp_multiplier));
-
-          BX_VGA_THIS s.vga_mem_updated = 1;
-          for (unsigned xti = 0; xti < BX_NUM_X_TILES; xti++) {
-            for (unsigned yti = 0; yti < BX_NUM_Y_TILES; yti++) {
-              SET_TILE_UPDATED (xti, yti, 1);
-            }
-          }
-        } break;
-
-        case VBE_DISPI_INDEX_Y_OFFSET:
-        {
-          // BX_INFO(("VBE offset y %x",value));
-          BX_VGA_THIS s.vbe_offset_y=(Bit16u)value;
-          BX_VGA_THIS s.vbe_virtual_start = ((BX_VGA_THIS s.vbe_offset_y) * (BX_VGA_THIS s.vbe_line_byte_width)) +
-                                             ((BX_VGA_THIS s.vbe_offset_x) * (BX_VGA_THIS s.vbe_bpp_multiplier));
-
-          BX_VGA_THIS s.vga_mem_updated = 1;
-          for (unsigned xti = 0; xti < BX_NUM_X_TILES; xti++) {
-            for (unsigned yti = 0; yti < BX_NUM_Y_TILES; yti++) {
-              SET_TILE_UPDATED (xti, yti, 1);
-            }
-          }
-        } break;
-
-        case VBE_DISPI_INDEX_VIRT_WIDTH:
-        {
-          BX_INFO(("VBE requested virtual width %d",value));
-
-          // calculate virtual width & height dimensions
-          // req:
-          //   virt_width > xres
-          //   virt_height >=yres
-          //   virt_width*virt_height < MAX_VIDEO_MEMORY
-
-          // basicly 2 situations
-
-          // situation 1: 
-          //   MAX_VIDEO_MEMORY / virt_width >= yres
-          //        adjust result height
-          //   else
-          //        adjust result width based upon virt_height=yres
-          Bit16u new_width=value;
-          Bit16u new_height=(sizeof(BX_VGA_THIS s.vbe_memory) / BX_VGA_THIS s.vbe_bpp_multiplier) / new_width;
-          if (new_height >=BX_VGA_THIS s.vbe_yres)
-          {
-            // we have a decent virtual width & new_height
-            BX_INFO(("VBE decent virtual height %d",new_height));
-          }
-          else
-          {
-            // no decent virtual height: adjust width & height
-            new_height=BX_VGA_THIS s.vbe_yres;
-            new_width=(sizeof(BX_VGA_THIS s.vbe_memory) / BX_VGA_THIS s.vbe_bpp_multiplier) / new_height;
-
-            BX_INFO(("VBE recalc virtual width %d height %d",new_width, new_height));
-          }
-
-          BX_VGA_THIS s.vbe_virtual_xres=new_width;
-          BX_VGA_THIS s.vbe_virtual_yres=new_height;
-          BX_VGA_THIS s.vbe_visable_screen_size = (new_width * (BX_VGA_THIS s.vbe_yres)) * BX_VGA_THIS s.vbe_bpp_multiplier;
-
-        } break;
-       /*      
-        case VBE_DISPI_INDEX_VIRT_HEIGHT:
-        {
-          BX_INFO(("VBE virtual height %x",value));
-
-        } break;
-       */  
-        default:
-        {
-          BX_PANIC(("VBE unknown data write index 0x%x",BX_VGA_THIS s.vbe_curindex));
-        } break;      
-      }        
-      break;
-         
-  } // end switch address
-}
-
-#endif
diff --git a/tools/ioemu/iodev/vga.h b/tools/ioemu/iodev/vga.h
deleted file mode 100644 (file)
index cafb60c..0000000
+++ /dev/null
@@ -1,300 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: vga.h,v 1.36 2003/12/31 10:33:27 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-#if BX_SUPPORT_VBE
-  #define VBE_DISPI_TOTAL_VIDEO_MEMORY_MB 4
-
-  #define VBE_DISPI_BANK_ADDRESS          0xA0000
-  #define VBE_DISPI_BANK_SIZE_KB          64
-
-  #define VBE_DISPI_MAX_XRES              1024
-  #define VBE_DISPI_MAX_YRES              768
-
-  #define VBE_DISPI_IOPORT_INDEX          0x01CE
-  #define VBE_DISPI_IOPORT_DATA           0x01CF
-
-  #define VBE_DISPI_IOPORT_INDEX_OLD      0xFF80
-  #define VBE_DISPI_IOPORT_DATA_OLD       0xFF81
-
-  #define VBE_DISPI_INDEX_ID              0x0
-  #define VBE_DISPI_INDEX_XRES            0x1
-  #define VBE_DISPI_INDEX_YRES            0x2
-  #define VBE_DISPI_INDEX_BPP             0x3
-  #define VBE_DISPI_INDEX_ENABLE          0x4
-  #define VBE_DISPI_INDEX_BANK            0x5
-  #define VBE_DISPI_INDEX_VIRT_WIDTH      0x6
-  #define VBE_DISPI_INDEX_VIRT_HEIGHT     0x7
-  #define VBE_DISPI_INDEX_X_OFFSET        0x8
-  #define VBE_DISPI_INDEX_Y_OFFSET        0x9
-
-  #define VBE_DISPI_ID0                   0xB0C0
-  #define VBE_DISPI_ID1                   0xB0C1
-  #define VBE_DISPI_ID2                   0xB0C2
-
-  #define VBE_DISPI_BPP_4                 0x04
-  #define VBE_DISPI_BPP_8                 0x08
-  #define VBE_DISPI_BPP_15                0x0F
-  #define VBE_DISPI_BPP_16                0x10
-  #define VBE_DISPI_BPP_24                0x18
-  #define VBE_DISPI_BPP_32                0x20
-
-  #define VBE_DISPI_DISABLED              0x00
-  #define VBE_DISPI_ENABLED               0x01
-  #define VBE_DISPI_NOCLEARMEM            0x80
-  #define VBE_DISPI_LFB_ENABLED           0x40
-
-  #define VBE_DISPI_LFB_PHYSICAL_ADDRESS  0xE0000000
-
-  
-#define VBE_DISPI_TOTAL_VIDEO_MEMORY_KB                (VBE_DISPI_TOTAL_VIDEO_MEMORY_MB * 1024)  
-#define VBE_DISPI_TOTAL_VIDEO_MEMORY_BYTES     (VBE_DISPI_TOTAL_VIDEO_MEMORY_KB * 1024)  
-
-#define BX_MAX_XRES VBE_DISPI_MAX_XRES
-#define BX_MAX_YRES VBE_DISPI_MAX_YRES
-
-#else
-
-#define BX_MAX_XRES 800
-#define BX_MAX_YRES 600
-
-#endif //BX_SUPPORT_VBE
-
-#define X_TILESIZE 16
-#define Y_TILESIZE 24
-#define BX_NUM_X_TILES (BX_MAX_XRES /X_TILESIZE)
-#define BX_NUM_Y_TILES (BX_MAX_YRES /Y_TILESIZE)
-
-// Support varying number of rows of text.  This used to
-// be limited to only 25 lines.
-#define BX_MAX_TEXT_LINES 100
-
-#if BX_USE_VGA_SMF
-#  define BX_VGA_SMF  static
-#  define BX_VGA_THIS theVga->
-#else
-#  define BX_VGA_SMF
-#  define BX_VGA_THIS this->
-#endif
-
-
-class bx_vga_c : public bx_vga_stub_c {
-public:
-
-  bx_vga_c(void);
-  ~bx_vga_c(void);
-  virtual void   init(void);
-  virtual void  bios_init(void);
-  virtual void   reset(unsigned type);
-  virtual Bit8u  mem_read(Bit32u addr);
-  // Note: either leave value of type Bit8u, or mask it when
-  //       used to 8 bits, in memory.cc
-  virtual void   mem_write(Bit32u addr, Bit8u value);
-  virtual void   trigger_timer(void *this_ptr);
-
-#if BX_SUPPORT_VBE
-  BX_VGA_SMF Bit8u  vbe_mem_read(Bit32u addr) BX_CPP_AttrRegparmN(1);
-  BX_VGA_SMF void   vbe_mem_write(Bit32u addr, Bit8u value) BX_CPP_AttrRegparmN(2);
-#endif
-
-  virtual void   redraw_area(unsigned x0, unsigned y0,
-                             unsigned width, unsigned height);
-
-  virtual void   set_update_interval (unsigned interval);
-  virtual void   get_text_snapshot(Bit8u **text_snapshot, unsigned *txHeight,
-                                   unsigned *txWidth);
-  virtual Bit8u  get_actl_palette_idx(Bit8u index);
-
-private:
-
-  static Bit32u read_handler(void *this_ptr, Bit32u address, unsigned io_len);
-  static void   write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);
-  static void   write_handler_no_log(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);
-
-#if BX_SUPPORT_VBE
-  static Bit32u vbe_read_handler(void *this_ptr, Bit32u address, unsigned io_len);
-  static void   vbe_write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);
-#endif
-
-  struct {
-    struct {
-      bx_bool color_emulation;  // 1=color emulation, base address = 3Dx
-                                // 0=mono emulation,  base address = 3Bx
-      bx_bool enable_ram;       // enable CPU access to video memory if set
-      Bit8u   clock_select;     // 0=25Mhz 1=28Mhz
-      bx_bool select_high_bank; // when in odd/even modes, select
-                                // high 64k bank if set
-      bx_bool horiz_sync_pol;   // bit6: negative if set
-      bx_bool vert_sync_pol;    // bit7: negative if set
-                                //   bit7,bit6 represent number of lines on display:
-                                //   0 = reserved
-                                //   1 = 400 lines
-                                //   2 = 350 lines
-                                //   3 - 480 lines
-      } misc_output;
-
-    struct {
-      Bit8u   address;
-      Bit8u   reg[0x19];
-      } CRTC;
-
-    struct {
-      bx_bool  flip_flop; /* 0 = address, 1 = data-write */
-      unsigned address;  /* register number */
-      bx_bool  video_enabled;
-      Bit8u    palette_reg[16];
-      Bit8u    overscan_color;
-      Bit8u    color_plane_enable;
-      Bit8u    horiz_pel_panning;
-      Bit8u    color_select;
-      struct {
-        bx_bool graphics_alpha;
-        bx_bool display_type;
-        bx_bool enable_line_graphics;
-        bx_bool blink_intensity;
-        bx_bool pixel_panning_compat;
-        bx_bool pixel_clock_select;
-        bx_bool internal_palette_size;
-        } mode_ctrl;
-      } attribute_ctrl;
-
-    struct {
-      Bit8u write_data_register;
-      Bit8u write_data_cycle; /* 0, 1, 2 */
-      Bit8u read_data_register;
-      Bit8u read_data_cycle; /* 0, 1, 2 */
-      Bit8u dac_state;
-      struct {
-        Bit8u red;
-        Bit8u green;
-        Bit8u blue;
-        } data[256];
-      Bit8u mask;
-      } pel;
-
-
-    struct {
-      Bit8u   index;
-      Bit8u   set_reset;
-      Bit8u   enable_set_reset;
-      Bit8u   color_compare;
-      Bit8u   data_rotate;
-      Bit8u   raster_op;
-      Bit8u   read_map_select;
-      Bit8u   write_mode;
-      bx_bool read_mode;
-      bx_bool odd_even;
-      bx_bool chain_odd_even;
-      Bit8u   shift_reg;
-      bx_bool graphics_alpha;
-      Bit8u   memory_mapping; /* 0 = use A0000-BFFFF
-                               * 1 = use A0000-AFFFF EGA/VGA graphics modes
-                               * 2 = use B0000-B7FFF Monochrome modes
-                               * 3 = use B8000-BFFFF CGA modes
-                               */
-      Bit8u   color_dont_care;
-      Bit8u   bitmask;
-      Bit8u   latch[4];
-      } graphics_ctrl;
-
-    struct {
-      Bit8u   index;
-      Bit8u   map_mask;
-      bx_bool map_mask_bit[4];
-      bx_bool reset1;
-      bx_bool reset2;
-      Bit8u   reg1;
-      Bit8u   char_map_select;
-      bx_bool extended_mem;
-      bx_bool odd_even;
-      bx_bool chain_four;
-      } sequencer;
-
-    bx_bool  vga_mem_updated;
-    unsigned x_tilesize;
-    unsigned y_tilesize;
-    unsigned line_offset;
-    unsigned line_compare;
-    unsigned vertical_display_end;
-    bx_bool  vga_tile_updated[BX_NUM_X_TILES][BX_NUM_Y_TILES];
-    Bit8u vga_memory[256 * 1024];
-    Bit8u text_snapshot[32 * 1024]; // current text snapshot
-    Bit8u rgb[3 * 256];
-    Bit8u tile[X_TILESIZE * Y_TILESIZE * 4]; /**< Currently allocates the tile as large as needed. */
-    Bit16u charmap_address;
-    bx_bool x_dotclockdiv2;
-    bx_bool y_doublescan;
-
-#if BX_SUPPORT_VBE    
-    Bit8u vbe_memory[VBE_DISPI_TOTAL_VIDEO_MEMORY_BYTES];
-    Bit16u  vbe_cur_dispi;
-    Bit16u  vbe_xres;
-    Bit16u  vbe_yres;
-    Bit16u  vbe_bpp;
-    Bit16u  vbe_bank;
-    bx_bool vbe_enabled;
-    Bit16u  vbe_curindex;
-    Bit32u  vbe_visable_screen_size; /**< in bytes */
-    Bit16u  vbe_offset_x;               /**< Virtual screen x start (in pixels) */ 
-    Bit16u  vbe_offset_y;               /**< Virtual screen y start (in pixels) */
-    Bit16u  vbe_virtual_xres;
-    Bit16u  vbe_virtual_yres;
-    Bit16u  vbe_line_byte_width; /**< For dealing with bpp>8, this is they width of a line in bytes. */
-    Bit32u  vbe_virtual_start;   /**< For dealing with bpp>8, this is where the virtual screen starts. */
-    Bit8u   vbe_bpp_multiplier;  /**< We have to save this b/c sometimes we need to recalculate stuff with it. */
-    bx_bool vbe_lfb_enabled;
-#endif    
-    } s;  // state information
-
-
-#if !BX_USE_VGA_SMF
-  Bit32u read(Bit32u address, unsigned io_len);
-  void   write(Bit32u address, Bit32u value, unsigned io_len, bx_bool no_log);
-#else
-  void write(Bit32u address, Bit32u value, unsigned io_len, bx_bool no_log);
-#endif
-
-#if BX_SUPPORT_VBE
-
-#if !BX_USE_VGA_SMF
-  Bit32u vbe_read(Bit32u address, unsigned io_len);
-  void   vbe_write(Bit32u address, Bit32u value, unsigned io_len, bx_bool no_log);
-#else
-  void vbe_write(Bit32u address, Bit32u value, unsigned io_len, bx_bool no_log);
-#endif
-#endif
-
-  int timer_id;
-
-  public:
-  static void   timer_handler(void *);
-  BX_VGA_SMF void   timer(void);
-
-  private:
-  BX_VGA_SMF void   update(void);
-  BX_VGA_SMF void   dump_status(void);
-  BX_VGA_SMF void determine_screen_dimensions(unsigned *piHeight,
-                                              unsigned *piWidth);
-  };
diff --git a/tools/ioemu/iodev/virt_timer.cc b/tools/ioemu/iodev/virt_timer.cc
deleted file mode 100644 (file)
index eb108a0..0000000
+++ /dev/null
@@ -1,552 +0,0 @@
-////////////////////////////////////////////////////////////////////////
-// $Id: virt_timer.cc,v 1.19.2.1 2004/02/06 22:14:36 danielg4 Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-/////////////////////////////////////////////////////////////////////////
-//
-//Realtime Algorithm (with gettimeofday)
-//  HAVE:
-//    Real number of usec.
-//    Emulated number of usec.
-//  WANT:
-//    Number of ticks to use.
-//    Number of emulated usec to wait until next try.
-//
-//  ticks=number of ticks needed to match total real usec.
-//  if(desired ticks > max ticks for elapsed real time)
-//     ticks = max ticks for elapsed real time.
-//  if(desired ticks > max ticks for elapsed emulated usec)
-//     ticks = max ticks for emulated usec.
-//  next wait ticks = number of ticks until next event.
-//  next wait real usec = (current ticks + next wait ticks) * usec per ticks
-//  next wait emulated usec = next wait real usec * emulated usec / real usec
-//  if(next wait emulated usec < minimum emulated usec for next wait ticks)
-//     next wait emulated usec = minimum emulated usec for next wait ticks.
-//  if(next wait emulated usec > max emulated usec wait)
-//     next wait emulated usec = max emulated usec wait.
-//
-//  How to calculate elapsed real time:
-//    store an unused time value whenever no ticks are used in a given time.
-//    add this to the current elapsed time.
-//  How to calculate elapsed emulated time:
-//    same as above.
-//  Above can be done by not updating last_usec and last_sec.
-//
-//  How to calculate emulated usec/real usec:
-//    Each time there are actual ticks:
-//      Alpha_product(old emulated usec, emulated usec);
-//      Alpha_product(old real usec, real usec);
-//    Divide resulting values.
-//
-/////////////////////////////////////////////////////////////////////////
-
-#include "bochs.h"
-
-#define BX_USE_VIRTUAL_TIMERS 1
-#define BX_VIRTUAL_TIMERS_REALTIME 1
-
-//Important constant #defines:
-#define USEC_PER_SECOND (1000000)
-
-
-// define a macro to convert floating point numbers into 64-bit integers.
-// In MSVC++ you can convert a 64-bit float into a 64-bit signed integer,
-// but it will not convert a 64-bit float into a 64-bit unsigned integer.
-// This macro works around that.
-#define F2I(x)  ((Bit64u)(Bit64s) (x))
-#define I2F(x)  ((double)(Bit64s) (x))
-
-//CONFIGURATION #defines:
-
-
-//MAINLINE Configuration (For realtime PIT):
-
-//How much faster than real time we can go:
-#define MAX_MULT (1.25)
-
-//Minimum number of emulated useconds per second.
-//  Now calculated using BX_MIN_IPS, the minimum number of
-//   instructions per second.
-#define MIN_USEC_PER_SECOND (((((Bit64u)USEC_PER_SECOND)*((Bit64u)BX_MIN_IPS))/((Bit64u)(bx_options.Oips->get())))+(Bit64u)1)
-
-
-//DEBUG configuration:
-
-//Debug with printf options.
-#define DEBUG_REALTIME_WITH_PRINTF 0
-
-//Use to test execution at multiples of real time.
-#define TIME_DIVIDER (1)
-#define TIME_MULTIPLIER (1)
-#define TIME_HEADSTART (0)
-
-
-#define GET_VIRT_REALTIME64_USEC() (((bx_get_realtime64_usec()*(Bit64u)TIME_MULTIPLIER/(Bit64u)TIME_DIVIDER)))
-//Set up Logging.
-#define LOG_THIS bx_virt_timer.
-
-//A single instance.
-bx_virt_timer_c bx_virt_timer;
-
-
-//Generic MAX and MIN Functions
-#define BX_MAX(a,b) ( ((a)>(b))?(a):(b) )
-#define BX_MIN(a,b) ( ((a)>(b))?(b):(a) )
-
-
-//USEC_ALPHA is multiplier for the past.
-//USEC_ALPHA_B is 1-USEC_ALPHA, or multiplier for the present.
-#define USEC_ALPHA ((double)(.8))
-#define USEC_ALPHA_B ((double)(((double)1)-USEC_ALPHA))
-#define USEC_ALPHA2 ((double)(.5))
-#define USEC_ALPHA2_B ((double)(((double)1)-USEC_ALPHA2))
-#define ALPHA_LOWER(old,new) ((Bit64u)((old<new)?((USEC_ALPHA*(I2F(old)))+(USEC_ALPHA_B*(I2F(new)))):((USEC_ALPHA2*(I2F(old)))+(USEC_ALPHA2_B*(I2F(new))))))
-
-
-//Conversion between emulated useconds and optionally realtime ticks.
-#define TICKS_TO_USEC(a) ( ((a)*usec_per_second)/ticks_per_second )
-#define USEC_TO_TICKS(a) ( ((a)*ticks_per_second)/usec_per_second )
-
-bx_virt_timer_c::bx_virt_timer_c( void )
-{
-  put("VTIMER");
-  settype(VTIMERLOG);
-
-  numTimers = 0;
-  current_timers_time = 0;
-  timers_next_event_time = BX_MAX_VIRTUAL_TIME;
-  last_sequential_time = 0;
-  in_timer_handler = 0;
-  virtual_next_event_time = BX_MAX_VIRTUAL_TIME;
-  current_virtual_time = 0;
-
-  use_virtual_timers = BX_USE_VIRTUAL_TIMERS;
-  init_done = 0;
-}
-
-bx_virt_timer_c::~bx_virt_timer_c( void )
-{
-}
-
-
-
-const Bit64u bx_virt_timer_c::NullTimerInterval = BX_MAX_VIRTUAL_TIME;
-
-void
-bx_virt_timer_c::nullTimer(void* this_ptr) {
-  UNUSED(this_ptr);
-}
-
-void
-bx_virt_timer_c::periodic(Bit64u time_passed) {
-  //Assert that we haven't skipped any events.
-  BX_ASSERT (time_passed <= timers_next_event_time);
-  BX_ASSERT(!in_timer_handler);
-
-  //Update time variables.
-  timers_next_event_time -= time_passed;
-  current_timers_time += time_passed;
-
-  //If no events are occurring, just pass the time and we're done.
-  if( time_passed < timers_next_event_time ) {
-    return;
-  }
-  //Starting timer handler calls.
-  in_timer_handler = 1;
-  //Otherwise, cause any events to occur that should.
-  unsigned i;
-  for(i=0;i<numTimers;i++) {
-    if( timer[i].inUse && timer[i].active ) {
-      //Assert that we haven't skipped any timers.
-      BX_ASSERT(current_timers_time <= timer[i].timeToFire);
-      if(timer[i].timeToFire == current_timers_time) {
-       if(timer[i].continuous) {
-         timer[i].timeToFire+=timer[i].period;
-       } else {
-         timer[i].active = 0;
-       }
-       //This function MUST return, or the timer mechanism
-       // will be broken.
-       timer[i].funct(timer[i].this_ptr);
-      }
-    }
-  }
-  //Finished timer handler calls.
-  in_timer_handler = 0;
-  //Use a second FOR loop so that a timer function call can
-  //  change the behavior of another timer.
-  //timers_next_event_time normally contains a cycle count, not a cycle time.
-  //  here we use it as a temporary variable that IS a cycle time,
-  //  but then convert it back to a cycle count afterwards.
-  timers_next_event_time = current_timers_time + BX_MAX_VIRTUAL_TIME;
-  for(i=0;i<numTimers;i++) {
-    if( timer[i].inUse && timer[i].active && ((timer[i].timeToFire)<timers_next_event_time) ) {
-      timers_next_event_time = timer[i].timeToFire;
-    }
-  }
-  timers_next_event_time-=current_timers_time;
-  next_event_time_update();
-  //FIXME
-}
-
-
-//Get the current virtual time.
-//  This may return the same value on subsequent calls.
-Bit64u
-bx_virt_timer_c::time_usec(void) {
-  if(!use_virtual_timers) {
-    return bx_pc_system.time_usec();
-  }
-
-  //Update the time here only if we're not in a timer handler.
-  //If we're in a timer handler we're up-to-date, and otherwise
-  // this prevents call stack loops.
-  if(!in_timer_handler) {
-    timer_handler();
-  }
-
-  return current_timers_time;
-}
-
-//Get the current virtual time.
-//  This will return a monotonically increasing value.
-// MUST NOT be called from within a timer interrupt.
-Bit64u
-bx_virt_timer_c::time_usec_sequential(void) {
-  if(!use_virtual_timers) {
-    return bx_pc_system.time_usec_sequential();
-  }
-
-  //Can't prevent call stack loops here, so this
-  // MUST NOT be called from within a timer handler.
-  BX_ASSERT(timers_next_event_time>0);
-  BX_ASSERT(!in_timer_handler);
-
-  if(last_sequential_time >= current_timers_time) {
-    periodic(1);
-    last_sequential_time = current_timers_time;
-  }
-  return current_timers_time;
-}
-
-
-
-//Register a timer handler to go off after a given interval.
-//Register a timer handler to go off with a periodic interval.
-int
-bx_virt_timer_c::register_timer( void *this_ptr, bx_timer_handler_t handler,
-                                Bit32u useconds,
-                                bx_bool continuous, bx_bool active,
-                                const char *id) {
-  if(!use_virtual_timers) {
-    return bx_pc_system.register_timer(this_ptr, handler, useconds,
-                                      continuous, active, id);
-  }
-
-  //We don't like starting with a zero period timer.
-  BX_ASSERT((!active) || (useconds>0));
-
-  //Search for an unused timer.
-  unsigned int i;
-  for (i=0; i < numTimers; i++) {
-    if (timer[i].inUse == 0 || i==numTimers)
-      break;
-    }
-  // If we didn't find a free slot, increment the bound, numTimers.
-  if (i==numTimers)
-    numTimers++; // One new timer installed.
-  BX_ASSERT(numTimers<BX_MAX_VIRTUAL_TIMERS);
-
-  timer[i].inUse = 1;
-  timer[i].period = useconds;
-  timer[i].timeToFire = current_timers_time + (Bit64u)useconds;
-  timer[i].active = active;
-  timer[i].continuous = continuous;
-  timer[i].funct = handler;
-  timer[i].this_ptr = this_ptr;
-  strncpy(timer[i].id, id, BxMaxTimerIDLen);
-  timer[i].id[BxMaxTimerIDLen-1]=0; //I like null terminated strings.
-
-  if(useconds < timers_next_event_time) {
-    timers_next_event_time = useconds;
-    next_event_time_update();
-    //FIXME
-  }
-  return i;
-}
-
-//unregister a previously registered timer.
-unsigned
-bx_virt_timer_c::unregisterTimer(int timerID) {
-  if(!use_virtual_timers) {
-    return bx_pc_system.unregisterTimer(timerID);
-  }
-
-  BX_ASSERT(timerID >= 0);
-  BX_ASSERT(timerID < BX_MAX_VIRTUAL_TIMERS);
-
-  if (timer[timerID].active) {
-    BX_PANIC(("unregisterTimer: timer '%s' is still active!", timer[timerID].id));
-    return(0); // Fail.
-    }
-
-
-  //No need to prevent doing this to unused timers.
-  timer[timerID].inUse = 0;
-  return(1);
-}
-
-void
-bx_virt_timer_c::start_timers(void) {
-  if(!use_virtual_timers) {
-    bx_pc_system.start_timers();
-    return;
-  }
-  //FIXME
-}
-
-//activate a deactivated but registered timer.
-void
-bx_virt_timer_c::activate_timer( unsigned timer_index, Bit32u useconds,
-                      bx_bool continuous ) {
-  if(!use_virtual_timers) {
-    bx_pc_system.activate_timer(timer_index, useconds, continuous);
-    return;
-  }
-
-  BX_ASSERT(timer_index >= 0);
-  BX_ASSERT(timer_index < BX_MAX_VIRTUAL_TIMERS);
-
-  BX_ASSERT(timer[timer_index].inUse);
-  BX_ASSERT(useconds>0);
-
-  timer[timer_index].period=useconds;
-  timer[timer_index].timeToFire = current_timers_time + (Bit64u)useconds;
-  timer[timer_index].active=1;
-  timer[timer_index].continuous=continuous;
-
-  if(useconds < timers_next_event_time) {
-    timers_next_event_time = useconds;
-    next_event_time_update();
-    //FIXME
-  }
-}
-
-//deactivate (but don't unregister) a currently registered timer.
-void
-bx_virt_timer_c::deactivate_timer( unsigned timer_index ) {
-  if(!use_virtual_timers) {
-    bx_pc_system.deactivate_timer(timer_index);
-    return;
-  }
-
-  BX_ASSERT(timer_index >= 0);
-  BX_ASSERT(timer_index < BX_MAX_VIRTUAL_TIMERS);
-
-  //No need to prevent doing this to unused/inactive timers.
-  timer[timer_index].active = 0;
-}
-
-void
-bx_virt_timer_c::advance_virtual_time(Bit64u time_passed) {
-  BX_ASSERT(time_passed <= virtual_next_event_time);
-
-  current_virtual_time += time_passed;
-  virtual_next_event_time -= time_passed;
-
-  if(current_virtual_time > current_timers_time) {
-    periodic(current_virtual_time - current_timers_time);
-  }
-}
-
-//Called when next_event_time changes.
-void
-bx_virt_timer_c::next_event_time_update(void) {
-  virtual_next_event_time = timers_next_event_time + current_timers_time - current_virtual_time;
-  if(init_done) {
-    bx_pc_system.deactivate_timer(system_timer_id);
-    BX_ASSERT(virtual_next_event_time);
-    bx_pc_system.activate_timer(system_timer_id, 
-                               (Bit32u)BX_MIN(0x7FFFFFFF,BX_MAX(1,TICKS_TO_USEC(virtual_next_event_time))),
-                               0);
-  }
-}
-
-void
-bx_virt_timer_c::init(void) {
-
-  if ( (bx_options.clock.Osync->get ()!=BX_CLOCK_SYNC_REALTIME)
-    && (bx_options.clock.Osync->get ()!=BX_CLOCK_SYNC_BOTH) )
-    virtual_timers_realtime = 0;
-  else
-    virtual_timers_realtime = 1;
-
-  if (virtual_timers_realtime) {
-    BX_INFO(("using 'realtime pit' synchronization method"));
-  }
-
-  register_timer(this, nullTimer, (Bit32u)NullTimerInterval, 1, 1, "Null Timer");
-
-  system_timer_id = bx_pc_system.register_timer(this, pc_system_timer_handler,virtual_next_event_time , 0, 1, "Virtual Timer");
-
-  //Real time variables:
-#if BX_HAVE_REALTIME_USEC
-  last_real_time=GET_VIRT_REALTIME64_USEC()+(Bit64u)TIME_HEADSTART*(Bit64u)USEC_PER_SECOND;
-#endif
-  total_real_usec=0;
-  last_realtime_delta=0;
-  //System time variables:
-  last_usec = 0
-;
-  usec_per_second = USEC_PER_SECOND;
-  stored_delta=0;
-  last_system_usec=0;
-  em_last_realtime=0;
-  //Virtual timer variables:
-  total_ticks=0;
-  last_realtime_ticks=0;
-  ticks_per_second = USEC_PER_SECOND;
-
-  init_done = 1;
-}
-
-void
-bx_virt_timer_c::timer_handler(void) {
-  if(!virtual_timers_realtime) {
-    Bit64u temp_final_time = bx_pc_system.time_usec();
-    temp_final_time-=current_virtual_time;
-    while(temp_final_time) {
-      if((temp_final_time)>(virtual_next_event_time)) {
-       temp_final_time-=virtual_next_event_time;
-       advance_virtual_time(virtual_next_event_time);
-      } else {
-       advance_virtual_time(temp_final_time);
-       temp_final_time-=temp_final_time;
-      }
-    }
-    bx_pc_system.activate_timer(system_timer_id,
-                               (Bit32u)BX_MIN(0x7FFFFFFF,(virtual_next_event_time>2)?(virtual_next_event_time-2):1),
-                               0);
-    return;
-  }
-
-  Bit64u usec_delta = bx_pc_system.time_usec()-last_usec;
-
-  if (usec_delta) {
-#if BX_HAVE_REALTIME_USEC
-    Bit64u ticks_delta = 0;
-    Bit64u real_time_delta = GET_VIRT_REALTIME64_USEC() - last_real_time;
-    Bit64u real_time_total = real_time_delta + total_real_usec;
-    Bit64u system_time_delta = (Bit64u)usec_delta + (Bit64u)stored_delta;
-    if(real_time_delta) {
-      last_realtime_delta = real_time_delta;
-      last_realtime_ticks = total_ticks;
-    }
-    ticks_per_second = USEC_PER_SECOND;
-
-    //Start out with the number of ticks we would like
-    // to have to line up with real time.
-    ticks_delta = real_time_total - total_ticks;
-    if(real_time_total < total_ticks) {
-      //This slows us down if we're already ahead.
-      //  probably only an issue on startup, but it solves some problems.
-      ticks_delta = 0;
-    }
-    if(ticks_delta + total_ticks - last_realtime_ticks > (F2I(MAX_MULT * I2F(last_realtime_delta)))) {
-      //This keeps us from going too fast in relation to real time.
-#if 0
-      ticks_delta = (F2I(MAX_MULT * I2F(last_realtime_delta))) + last_realtime_ticks - total_ticks;
-#endif
-      ticks_per_second = F2I(MAX_MULT * I2F(USEC_PER_SECOND));
-    }
-    if(ticks_delta > system_time_delta * USEC_PER_SECOND / MIN_USEC_PER_SECOND) {
-      //This keeps us from having too few instructions between ticks.
-      ticks_delta = system_time_delta * USEC_PER_SECOND / MIN_USEC_PER_SECOND;
-    }
-    if(ticks_delta > virtual_next_event_time) {
-      //This keeps us from missing ticks.
-      ticks_delta = virtual_next_event_time;
-    }
-
-    if(ticks_delta) {
-
-#  if DEBUG_REALTIME_WITH_PRINTF
-      //Every second print some info.
-      if(((last_real_time + real_time_delta) / USEC_PER_SECOND) > (last_real_time / USEC_PER_SECOND)) {
-       Bit64u temp1, temp2, temp3, temp4;
-       temp1 = (Bit64u) total_real_usec;
-       temp2 = (total_real_usec);
-       temp3 = (Bit64u)total_ticks;
-       temp4 = (Bit64u)((total_real_usec) - total_ticks);
-       printf("useconds: %llu, ",temp1);
-       printf("expect ticks: %llu, ",temp2);
-       printf("ticks: %llu, ",temp3);
-       printf("diff: %llu\n",temp4);
-      }
-#  endif
-
-      last_real_time += real_time_delta;
-      total_real_usec += real_time_delta;
-      last_system_usec += system_time_delta;
-      stored_delta = 0;
-      total_ticks += ticks_delta;
-    } else {
-      stored_delta = system_time_delta;
-    }
-
-
-    Bit64u a,b;
-    a=(usec_per_second);
-    if(real_time_delta) {
-      //FIXME
-      Bit64u em_realtime_delta = last_system_usec + stored_delta - em_last_realtime;
-      b=((Bit64u)USEC_PER_SECOND * em_realtime_delta / real_time_delta);
-      em_last_realtime = last_system_usec + stored_delta;
-    } else {
-      b=a;
-    }
-    usec_per_second = ALPHA_LOWER(a,b);
-#else
-    BX_ASSERT(0);
-#endif
-#if BX_HAVE_REALTIME_USEC
-    advance_virtual_time(ticks_delta);
-#endif
-  }
-
-  last_usec=last_usec + usec_delta;
-  bx_pc_system.deactivate_timer(system_timer_id);
-  BX_ASSERT(virtual_next_event_time);
-  bx_pc_system.activate_timer(system_timer_id, 
-                             (Bit32u)BX_MIN(0x7FFFFFFF,BX_MAX(1,TICKS_TO_USEC(virtual_next_event_time))),
-                             0);
-
-}
-
-void
-bx_virt_timer_c::pc_system_timer_handler(void* this_ptr) {
-  ((bx_virt_timer_c *)this_ptr)->timer_handler();
-}
-
diff --git a/tools/ioemu/iodev/virt_timer.h b/tools/ioemu/iodev/virt_timer.h
deleted file mode 100644 (file)
index a10b16c..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-
-#ifndef _BX_VIRT_TIMER_H
-#define _BX_VIRT_TIMER_H
-
-
-#define BX_MAX_VIRTUAL_TIMERS (15+BX_SMP_PROCESSORS)
-#define BX_NULL_VIRTUAL_TIMER_HANDLE 10000
-
-#define BX_MAX_VIRTUAL_TIME (0x7fffffff)
-
-class bx_virt_timer_c : public logfunctions {
- private:
-
-  struct {
-    bx_bool inUse;      // Timer slot is in-use (currently registered).
-    Bit64u  period;     // Timer periodocity in virtual useconds.
-    Bit64u  timeToFire; // Time to fire next (in virtual useconds).
-    bx_bool active;     // 0=inactive, 1=active.
-    bx_bool continuous; // 0=one-shot timer, 1=continuous periodicity.
-    bx_timer_handler_t funct;  // A callback function for when the
-                               //   timer fires.
-                               //   This function MUST return.
-    void *this_ptr;            // The this-> pointer for C++ callbacks
-                               //   has to be stored as well.
-    char id[BxMaxTimerIDLen]; // String ID of timer.
-  } timer[BX_MAX_VIRTUAL_TIMERS];
-
-  unsigned   numTimers;  // Number of currently allocated timers.
-
-  //Variables for the timer subsystem:
-  Bit64u current_timers_time;
-  Bit64u timers_next_event_time;
-
-  Bit64u last_sequential_time;
-  bx_bool in_timer_handler;
-
-  //Variables for the time sync subsystem:
-  Bit64u virtual_next_event_time;
-  Bit64u current_virtual_time;
-
-  //Real time variables:
-  Bit64u last_real_time;
-  Bit64u total_real_usec;
-  Bit64u last_realtime_delta;
-  //System time variables:
-  Bit64u last_usec;
-  Bit64u usec_per_second;
-  Bit64u stored_delta;
-  Bit64u last_system_usec;
-  Bit64u em_last_realtime;
-  //Virtual timer variables:
-  Bit64u total_ticks;
-  Bit64u last_realtime_ticks;
-  Bit64u ticks_per_second;
-
-  bx_bool init_done;
-
-  int system_timer_id;
-
-  //Whether or not to use virtual timers.
-  bx_bool use_virtual_timers;
-  bx_bool virtual_timers_realtime;
-
-  // A special null timer is always inserted in the timer[0] slot.  This
-  // make sure that at least one timer is always active, and that the
-  // duration is always less than a maximum 32-bit integer, so a 32-bit
-  // counter can be used for the current countdown.
-  static const Bit64u NullTimerInterval;
-  static void nullTimer(void* this_ptr);
-
-
-  //Step the given number of cycles, optionally calling any timer handlers.
-  void periodic(Bit64u time_passed);
-
-
-  //Called when next_event_time changes.
-  void next_event_time_update(void);
-
-  //Called to advance the virtual time.
-  // calls periodic as needed.
-  void advance_virtual_time(Bit64u time_passed);
-
- public:
-
-
-  //Get the current virtual time.
-  //  This may return the same value on subsequent calls.
-  Bit64u time_usec(void);
-
-  //Get the current virtual time.
-  //  This will return a monotonically increasing value.
-  // MUST NOT be called from within a timer handler.
-  Bit64u time_usec_sequential(void);
-
-  //Register a timer handler to go off after a given interval.
-  //Register a timer handler to go off with a periodic interval.
-  int    register_timer( void *this_ptr, bx_timer_handler_t handler,
-                         Bit32u useconds,
-                         bx_bool continuous, bx_bool active, const char *id);
-
-  //unregister a previously registered timer.
-  unsigned unregisterTimer(int timerID);
-
-  void   start_timers(void);
-
-  //activate a deactivated but registered timer.
-  void   activate_timer( unsigned timer_index, Bit32u useconds,
-                         bx_bool continuous );
-
-  //deactivate (but don't unregister) a currently registered timer.
-  void   deactivate_timer( unsigned timer_index );
-
-
-  //Timer handler passed to pc_system
-  static void pc_system_timer_handler(void* this_ptr);
-
-  //The real timer handler.
-  void timer_handler();
-
-  //Initialization
-  void init(void);
-  bx_virt_timer_c(void);
-  ~bx_virt_timer_c(void);
-
-};
-
-
-
-extern bx_virt_timer_c bx_virt_timer;
-
-#endif // _BX_VIRT_TIMER_H
diff --git a/tools/ioemu/keyboard_rdesktop.c b/tools/ioemu/keyboard_rdesktop.c
new file mode 100644 (file)
index 0000000..a98df10
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ * QEMU keylayout reader: read rdesktop style keylaouts
+ *
+ * Copyright (c) 2004,2005 Johannes E. Schindelin
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <ctype.h>
+
+#ifdef KEYBOARD_IGNORE_CASE
+#define STRCMP strcasecmp
+#else
+#define STRCMP strcmp
+#endif
+
+/* binary search through nameToKeysym */
+static int get_keysym(const char* name)
+{
+       int i1=-1,i2=sizeof(name2keysym)/sizeof(name2keysym_t),i3=i2/2,r;
+       while((r=STRCMP(name,name2keysym[i3].name))!=0) {
+               if(r<0)
+                       i2=i3;
+               else
+                       i1=i3;
+               i3=(i1+i2)/2;
+               if(i2-i1<2)
+                       return 0;
+       }
+       return name2keysym[i3].keysym;
+}
+
+typedef unsigned short WORD;
+#define MAX_NORMAL_KEYCODE 512
+#define MAX_EXTRA_COUNT 256
+typedef struct {
+       WORD keysym2keycode[MAX_NORMAL_KEYCODE];
+       struct {
+               int keysym;
+               WORD keycode;
+       } keysym2keycode_extra[MAX_EXTRA_COUNT];
+       int extra_count;
+} kbd_layout_t;
+
+static int parse_int(const char* text)
+{
+       if(!strncmp(text,"0x",2)) {
+               int result=0;
+               sscanf(text+2,"%x",&result);
+               return result;
+       }
+       return atoi(text);
+}
+
+static kbd_layout_t* parse_keyboard_layout(const char* language,kbd_layout_t* k)
+{
+       FILE* f;
+    const char* prefix="/keymaps/";
+    char* file_name=malloc(strlen(prefix)+strlen(language)+strlen(bios_dir)+1);
+
+       if(!k)
+               k=calloc(sizeof(kbd_layout_t),1);
+       strcpy(file_name,bios_dir);
+       strcat(file_name,prefix);
+       strcat(file_name,language);
+       if(file_name[strlen(file_name)-1]=='\n')
+               file_name[strlen(file_name)-1]=0;
+       if(!(f=fopen(file_name,"r"))) {
+               term_printf("Warning: could not read keymap - falling back native keycodes!\n");
+               free(file_name);
+               return 0;
+       }
+       free(file_name);
+       while(!feof(f)) {
+               char line[1024];
+               fgets(line,1024,f);
+               if(line[0]=='#')
+                       continue;
+               if(!strncmp(line,"map ",4))
+                       continue;
+               if(!strncmp(line,"include ",8))
+                       parse_keyboard_layout(line+8,k);
+               else {
+                       char* end_of_keysym=line;
+                       while(*end_of_keysym!=0 && *end_of_keysym!=' ')
+                               end_of_keysym++;
+                       if(*end_of_keysym) {
+                               int keysym;
+                               *end_of_keysym=0;
+                               keysym=get_keysym(line);
+                               if(keysym==0) {
+                                       term_printf("Warning: 1unknown keysym %s\n",line);
+                               } else {
+                                       const char* rest=end_of_keysym+1;
+                                       int keycode=parse_int(rest);
+                                       /* if(keycode&0x80)
+                                               keycode=(keycode<<8)^0x80e0; */
+                                       if(keysym<MAX_NORMAL_KEYCODE) {
+                                               //term_printf("Setting keysym %s (%d) to %d\n",line,keysym,keycode);
+                                               k->keysym2keycode[keysym]=keycode;
+#ifndef KEYBOARD_IGNORE_CASE
+                                               line[0]=toupper(line[0]);
+                                               keysym=get_keysym(line);
+                                               if(keysym)
+                                                       k->keysym2keycode[keysym]=keycode;
+#endif
+                                       } else {
+                                               if(k->extra_count>=MAX_EXTRA_COUNT) {
+                                                       term_printf("Warning: Could not assign keysym %s (0x%x) because of memory constraints.\n",line,keysym);
+                                               } else {
+                                                       //term_printf("Setting %d: %d,%d\n",k->extra_count,keysym,keycode);
+                                                       k->keysym2keycode_extra[k->extra_count].keysym=keysym;
+                                                       k->keysym2keycode_extra[k->extra_count].keycode=keycode;
+                                                       k->extra_count++;
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+       fclose(f);
+       return k;
+}
+
+static void* init_keyboard_layout(const char* language)
+{
+       return parse_keyboard_layout(language,0);
+}
+
+static WORD keysym2scancode(void* kbd_layout, int keysym)
+{
+       kbd_layout_t* k=kbd_layout;
+       if(keysym<MAX_NORMAL_KEYCODE) {
+               if(k->keysym2keycode[keysym]==0)
+                       term_printf("Warning: no scancode found for keysym %d\n",keysym);
+               return k->keysym2keycode[keysym];
+       } else {
+               int i;
+#ifdef XK_ISO_Left_Tab
+               if(keysym==XK_ISO_Left_Tab)
+                       keysym=XK_Tab;
+#endif
+               for(i=0;i<k->extra_count;i++)
+                       if(k->keysym2keycode_extra[i].keysym==keysym)
+                               return k->keysym2keycode_extra[i].keycode;
+       }
+       return 0;
+}
+
diff --git a/tools/ioemu/keymaps/ar b/tools/ioemu/keymaps/ar
new file mode 100644 (file)
index 0000000..c430c03
--- /dev/null
@@ -0,0 +1,98 @@
+# generated from XKB map ar
+include common
+map 0x401
+exclam 0x02 shift
+at 0x03 shift
+numbersign 0x04 shift
+dollar 0x05 shift
+percent 0x06 shift
+asciicircum 0x07 shift
+ampersand 0x08 shift
+asterisk 0x09 shift
+parenleft 0x0a shift
+parenright 0x0b shift
+minus 0x0c
+underscore 0x0c shift
+equal 0x0d
+plus 0x0d shift
+Arabic_dad 0x10 altgr
+Arabic_fatha 0x10 shift altgr
+Arabic_sad 0x11 altgr
+Arabic_fathatan 0x11 shift altgr
+Arabic_theh 0x12 altgr
+Arabic_damma 0x12 shift altgr
+Arabic_qaf 0x13 altgr
+Arabic_dammatan 0x13 shift altgr
+Arabic_feh 0x14 altgr
+UFEF9 0x14 shift altgr
+Arabic_ghain 0x15 altgr
+Arabic_hamzaunderalef 0x15 shift altgr
+Arabic_ain 0x16 altgr
+grave 0x16 shift altgr
+Arabic_ha 0x17 altgr
+division 0x17 shift altgr
+Arabic_khah 0x18 altgr
+multiply 0x18 shift altgr
+Arabic_hah 0x19 altgr
+Arabic_semicolon 0x19 shift altgr
+bracketleft 0x1a
+braceleft 0x1a shift
+Arabic_jeem 0x1a altgr
+bracketright 0x1b
+braceright 0x1b shift
+Arabic_dal 0x1b altgr
+Arabic_sheen 0x1e altgr
+backslash 0x1e shift altgr
+Arabic_seen 0x1f altgr
+Arabic_yeh 0x20 altgr
+bracketleft 0x20 shift altgr
+Arabic_beh 0x21 altgr
+bracketright 0x21 shift altgr
+Arabic_lam 0x22 altgr
+UFEF7 0x22 shift altgr
+Arabic_alef 0x23 altgr
+Arabic_hamzaonalef 0x23 shift altgr
+Arabic_teh 0x24 altgr
+Arabic_tatweel 0x24 shift altgr
+Arabic_noon 0x25 altgr
+Arabic_comma 0x25 shift altgr
+Arabic_meem 0x26 altgr
+slash 0x26 shift altgr
+semicolon 0x27
+colon 0x27 shift
+Arabic_kaf 0x27 altgr
+apostrophe 0x28
+quotedbl 0x28 shift
+Arabic_tah 0x28 altgr
+grave 0x29
+asciitilde 0x29 shift
+Arabic_thal 0x29 altgr
+Arabic_shadda 0x29 shift altgr
+backslash 0x2b
+bar 0x2b shift
+less 0x2b altgr
+greater 0x2b shift altgr
+Arabic_hamzaonyeh 0x2c altgr
+asciitilde 0x2c shift altgr
+Arabic_hamza 0x2d altgr
+Arabic_sukun 0x2d shift altgr
+Arabic_hamzaonwaw 0x2e altgr
+Arabic_kasra 0x2e shift altgr
+Arabic_ra 0x2f altgr
+Arabic_kasratan 0x2f shift altgr
+UFEFB 0x30 altgr
+UFEF5 0x30 shift altgr
+Arabic_alefmaksura 0x31 altgr
+Arabic_maddaonalef 0x31 shift altgr
+Arabic_tehmarbuta 0x32 altgr
+apostrophe 0x32 shift altgr
+comma 0x33
+less 0x33 shift
+Arabic_waw 0x33 altgr
+period 0x34
+greater 0x34 shift
+Arabic_zain 0x34 altgr
+slash 0x35
+question 0x35 shift
+Arabic_zah 0x35 altgr
+Arabic_question_mark 0x35 shift altgr
diff --git a/tools/ioemu/keymaps/common b/tools/ioemu/keymaps/common
new file mode 100644 (file)
index 0000000..0b53f1c
--- /dev/null
@@ -0,0 +1,157 @@
+include modifiers
+
+#
+# Top row
+#
+1 0x2
+2 0x3
+3 0x4
+4 0x5
+5 0x6
+6 0x7
+7 0x8
+8 0x9
+9 0xa
+0 0xb
+BackSpace 0xe
+
+#
+# QWERTY first row
+#
+Tab 0xf localstate
+ISO_Left_Tab 0xf shift
+q 0x10 addupper
+w 0x11 addupper
+e 0x12 addupper
+r 0x13 addupper
+t 0x14 addupper
+y 0x15 addupper
+u 0x16 addupper
+i 0x17 addupper
+o 0x18 addupper
+p 0x19 addupper
+
+#
+# QWERTY second row
+#
+a 0x1e addupper
+s 0x1f addupper
+d 0x20 addupper
+f 0x21 addupper
+g 0x22 addupper
+h 0x23 addupper
+j 0x24 addupper
+k 0x25 addupper
+l 0x26 addupper
+Return 0x1c localstate
+
+#
+# QWERTY third row
+#
+z 0x2c addupper
+x 0x2d addupper
+c 0x2e addupper
+v 0x2f addupper
+b 0x30 addupper
+n 0x31 addupper
+m 0x32 addupper
+
+space 0x39 localstate
+
+less 0x56
+greater 0x56 shift
+bar 0x56 altgr
+brokenbar 0x56 shift altgr
+
+#
+# Esc and Function keys
+#
+Escape 0x1 localstate
+F1 0x3b localstate
+F2 0x3c localstate
+F3 0x3d localstate
+F4 0x3e localstate
+F5 0x3f localstate
+F6 0x40 localstate
+F7 0x41 localstate
+F8 0x42 localstate
+F9 0x43 localstate
+F10 0x44 localstate
+F11 0x57 localstate
+F12 0x58 localstate
+
+# Printscreen, Scrollock and Pause
+# Printscreen really requires four scancodes (0xe0, 0x2a, 0xe0, 0x37),
+# but (0xe0, 0x37) seems to work. 
+Print 0xb7 localstate
+Sys_Req 0xb7 localstate
+Execute 0xb7 localstate
+Scroll_Lock 0x46
+
+#
+# Insert - PgDown
+#
+Insert 0xd2 localstate
+Delete 0xd3 localstate
+Home 0xc7 localstate
+End 0xcf localstate
+Page_Up 0xc9 localstate
+Page_Down 0xd1 localstate
+
+#
+# Arrow keys
+#
+Left 0xcb localstate
+Up 0xc8 localstate
+Down 0xd0 localstate
+Right 0xcd localstate
+
+#
+# Numpad
+#
+Num_Lock 0x45
+KP_Divide 0xb5
+KP_Multiply 0x37
+KP_Subtract 0x4a
+KP_Add 0x4e
+KP_Enter 0x9c
+
+KP_Decimal 0x53 numlock
+KP_Separator 0x53 numlock
+KP_Delete 0x53
+
+KP_0 0x52 numlock
+KP_Insert 0x52
+
+KP_1 0x4f numlock
+KP_End 0x4f
+
+KP_2 0x50 numlock
+KP_Down 0x50
+
+KP_3 0x51 numlock
+KP_Next 0x51
+
+KP_4 0x4b numlock
+KP_Left 0x4b
+
+KP_5 0x4c numlock
+KP_Begin 0x4c
+
+KP_6 0x4d numlock
+KP_Right 0x4d
+
+KP_7 0x47 numlock
+KP_Home 0x47
+
+KP_8 0x48 numlock
+KP_Up 0x48
+
+KP_9 0x49 numlock
+KP_Prior 0x49
+
+Caps_Lock 0x3a
+#
+# Inhibited keys
+#
+Multi_key 0x0 inhibit
diff --git a/tools/ioemu/keymaps/convert-map b/tools/ioemu/keymaps/convert-map
new file mode 100644 (file)
index 0000000..889b703
--- /dev/null
@@ -0,0 +1,63 @@
+#!/usr/bin/env python2
+# -*-Python-*-
+#
+# 
+# Copyright (C) 2001  Peter Åstrand <peter@cendio.se>
+# 
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License. 
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import sys
+
+def main():
+    f = open(sys.argv[1])
+    while 1:
+        line = f.readline()
+        if not line: break
+
+        if line.startswith("#") or line.startswith("include"):
+            print line,
+            continue
+
+        fields = line.split()
+
+        if line.startswith("map"):
+            print "map 0x%s" % fields[1]
+            continue
+
+        scancode = fields[0]
+        for pos in range(1, len(fields)):
+            keysym = fields[pos]
+
+            if pos == 1:
+                modifiers = ""
+            elif pos == 2:
+                modifiers = "shift"
+            elif pos == 3:
+                modifiers = "altgr"
+            elif pos == 4:
+                modifiers = "shift altgr"
+            else:
+                raise("Invalid line: %s" % line)
+            
+            print "%s 0x%s %s" % (keysym, scancode, modifiers)
+
+
+
+if __name__ == "__main__":
+    if len(sys.argv) < 2:
+        print "Convert old-style keymaps to new style"
+        print "Usage: %s <old-style-keymap>" % sys.argv[0]
+        sys.exit(1)
+    else:
+        main()
diff --git a/tools/ioemu/keymaps/da b/tools/ioemu/keymaps/da
new file mode 100644 (file)
index 0000000..3884dcf
--- /dev/null
@@ -0,0 +1,120 @@
+# generated from XKB map dk
+include common
+map 0x406
+exclam 0x02 shift
+exclamdown 0x02 altgr
+onesuperior 0x02 shift altgr
+quotedbl 0x03 shift
+at 0x03 altgr
+twosuperior 0x03 shift altgr
+numbersign 0x04 shift
+sterling 0x04 altgr
+threesuperior 0x04 shift altgr
+currency 0x05 shift
+dollar 0x05 altgr
+onequarter 0x05 shift altgr
+percent 0x06 shift
+onehalf 0x06 altgr
+cent 0x06 shift altgr
+ampersand 0x07 shift
+yen 0x07 altgr
+fiveeighths 0x07 shift altgr
+slash 0x08 shift
+braceleft 0x08 altgr
+division 0x08 shift altgr
+parenleft 0x09 shift
+bracketleft 0x09 altgr
+guillemotleft 0x09 shift altgr
+parenright 0x0a shift
+bracketright 0x0a altgr
+guillemotright 0x0a shift altgr
+equal 0x0b shift
+braceright 0x0b altgr
+degree 0x0b shift altgr
+plus 0x0c
+question 0x0c shift
+plusminus 0x0c altgr
+questiondown 0x0c shift altgr
+dead_acute 0x0d
+dead_grave 0x0d shift
+bar 0x0d altgr
+brokenbar 0x0d shift altgr
+Greek_OMEGA 0x10 shift altgr
+lstroke 0x11 altgr
+Lstroke 0x11 shift altgr
+EuroSign 0x12 altgr
+cent 0x12 shift altgr
+registered 0x13 altgr
+thorn 0x14 altgr
+THORN 0x14 shift altgr
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oe 0x18 altgr
+OE 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+aring 0x1a
+Aring 0x1a shift
+dead_diaeresis 0x1a altgr
+dead_abovering 0x1a shift altgr
+dead_diaeresis 0x1b
+dead_circumflex 0x1b shift
+dead_tilde 0x1b altgr
+dead_caron 0x1b shift altgr
+ordfeminine 0x1e altgr
+masculine 0x1e shift altgr
+ssharp 0x1f altgr
+section 0x1f shift altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+dstroke 0x21 altgr
+ordfeminine 0x21 shift altgr
+eng 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+kra 0x25 altgr
+lstroke 0x26 altgr
+Lstroke 0x26 shift altgr
+ae 0x27
+AE 0x27 shift
+oslash 0x28
+Ooblique 0x28 shift
+dead_caron 0x28 shift altgr
+onehalf 0x29
+section 0x29 shift
+threequarters 0x29 altgr
+paragraph 0x29 shift altgr
+apostrophe 0x2b
+asterisk 0x2b shift
+dead_doubleacute 0x2b altgr
+multiply 0x2b shift altgr
+guillemotleft 0x2c altgr
+guillemotright 0x2d altgr
+copyright 0x2e altgr
+leftdoublequotemark 0x2f altgr
+grave 0x2f shift altgr
+rightdoublequotemark 0x30 altgr
+mu 0x32 altgr
+masculine 0x32 shift altgr
+comma 0x33
+semicolon 0x33 shift
+dead_cedilla 0x33 altgr
+dead_ogonek 0x33 shift altgr
+period 0x34
+colon 0x34 shift
+periodcentered 0x34 altgr
+dead_abovedot 0x34 shift altgr
+minus 0x35
+underscore 0x35 shift
+hyphen 0x35 altgr
+macron 0x35 shift altgr
+nobreakspace 0x39 altgr
+less 0x56
+greater 0x56 shift
+backslash 0x56 altgr
+notsign 0x56 shift altgr
diff --git a/tools/ioemu/keymaps/de b/tools/ioemu/keymaps/de
new file mode 100644 (file)
index 0000000..ed929c7
--- /dev/null
@@ -0,0 +1,114 @@
+# generated from XKB map de
+include common
+map 0x407
+exclam 0x02 shift
+onesuperior 0x02 altgr
+exclamdown 0x02 shift altgr
+quotedbl 0x03 shift
+twosuperior 0x03 altgr
+oneeighth 0x03 shift altgr
+section 0x04 shift
+threesuperior 0x04 altgr
+sterling 0x04 shift altgr
+dollar 0x05 shift
+onequarter 0x05 altgr
+currency 0x05 shift altgr
+percent 0x06 shift
+onehalf 0x06 altgr
+threeeighths 0x06 shift altgr
+ampersand 0x07 shift
+threequarters 0x07 altgr
+fiveeighths 0x07 shift altgr
+slash 0x08 shift
+braceleft 0x08 altgr
+seveneighths 0x08 shift altgr
+parenleft 0x09 shift
+bracketleft 0x09 altgr
+trademark 0x09 shift altgr
+parenright 0x0a shift
+bracketright 0x0a altgr
+plusminus 0x0a shift altgr
+equal 0x0b shift
+braceright 0x0b altgr
+ssharp 0x0c
+question 0x0c shift
+backslash 0x0c altgr
+questiondown 0x0c shift altgr
+acute 0x0d
+dead_acute 0x0d
+grave 0x0d shift
+dead_grave 0x0d shift
+dead_cedilla 0x0d altgr
+dead_ogonek 0x0d shift altgr
+at 0x10 altgr
+Greek_OMEGA 0x10 shift altgr
+EuroSign 0x12 altgr
+paragraph 0x13 altgr
+registered 0x13 shift altgr
+tslash 0x14 altgr
+Tslash 0x14 shift altgr
+z 0x15 addupper
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oslash 0x18 altgr
+Ooblique 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+udiaeresis 0x1a
+Udiaeresis 0x1a shift
+dead_diaeresis 0x1a altgr
+dead_abovering 0x1a shift altgr
+plus 0x1b
+asterisk 0x1b shift
+asciitilde 0x1b altgr
+dead_tilde 0x1b altgr
+dead_macron 0x1b shift altgr
+ae 0x1e altgr
+AE 0x1e shift altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+dstroke 0x21 altgr
+ordfeminine 0x21 shift altgr
+eng 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+kra 0x25 altgr
+odiaeresis 0x27
+Odiaeresis 0x27 shift
+dead_doubleacute 0x27 altgr
+adiaeresis 0x28
+Adiaeresis 0x28 shift
+dead_caron 0x28 shift altgr
+asciicircum 0x29
+dead_circumflex 0x29
+degree 0x29 shift
+notsign 0x29 altgr
+numbersign 0x2b
+apostrophe 0x2b shift
+dead_breve 0x2b shift altgr
+y 0x2c addupper
+guillemotleft 0x2c altgr
+guillemotright 0x2d altgr
+cent 0x2e altgr
+copyright 0x2e shift altgr
+leftdoublequotemark 0x2f altgr
+rightdoublequotemark 0x30 altgr
+mu 0x32 altgr
+masculine 0x32 shift altgr
+comma 0x33
+semicolon 0x33 shift
+horizconnector 0x33 altgr
+multiply 0x33 shift altgr
+period 0x34
+colon 0x34 shift
+periodcentered 0x34 altgr
+division 0x34 shift altgr
+minus 0x35
+underscore 0x35 shift
+dead_belowdot 0x35 altgr
+dead_abovedot 0x35 shift altgr
diff --git a/tools/ioemu/keymaps/de-ch b/tools/ioemu/keymaps/de-ch
new file mode 100644 (file)
index 0000000..f83837b
--- /dev/null
@@ -0,0 +1,169 @@
+# rdesktop Swiss-German (de-ch) keymap file 
+# 2003-06-03 by noldi@tristar.ch 
+#
+include common
+map 0x00000807
+#
+# Scan Code 1
+section 0x29
+degree 0x29 shift
+notsign 0x29 altgr inhibit
+#
+# Scan Code 2
+plus 0x2 shift
+brokenbar 0x02 altgr
+#
+# Scan Code 3
+quotedbl 0x03 shift
+at 0x03 altgr
+#
+# Scan Code 4
+asterisk 0x04 shift
+numbersign 0x04 altgr
+#
+# Scan Code 5
+ccedilla 0x05 shift
+onequarter 0x05 altgr inhibit
+#
+# Scan Code 6
+percent 0x06 shift
+onehalf 0x06 altgr inhibit
+#
+# Scan Code 7
+ampersand 0x07 shift
+notsign 0x07 altgr
+#
+# Scan Code 8
+slash 0x08 shift
+bar 0x08 altgr
+#
+# Scan Code 9
+parenleft 0x09 shift
+cent 0x09 altgr
+# 
+# Scan Code 10
+parenright 0x0a shift
+#
+# Scan Code 11
+equal 0x0b shift
+braceright 0x0b altgr inhibit
+#
+# Scan Code 12
+apostrophe 0x0c 
+question 0x0c shift
+dead_acute 0x0c altgr
+#
+# Scan Code 13
+dead_circumflex 0x0d
+dead_grave 0x0d shift
+dead_tilde 0x0d altgr
+#
+# Scan Code 19
+EuroSign 0x12 altgr
+#
+# Scan Code 22
+z 0x15 addupper
+#
+# Scan Code 27
+udiaeresis 0x1a
+egrave 0x1a shift
+bracketleft 0x1a altgr
+# 
+# Scan Code 28
+dead_diaeresis 0x1b
+exclam 0x1b shift 
+bracketright 0x1b altgr
+#
+# Scan Code 40
+odiaeresis 0x27
+eacute 0x27 shift
+#
+# Scan Code 41
+adiaeresis 0x28
+agrave 0x28 shift
+braceleft 0x28 altgr
+#
+# Scan Code 42 (only on international keyboards)
+dollar 0x2b
+sterling 0x2b shift
+braceright 0x2b altgr
+#
+# Scan Code 45 (only on international keyboards)
+backslash 0x56 altgr
+#
+# Scan Code 46
+y 0x2c addupper
+# 
+# Scan Code 53
+comma 0x33
+semicolon 0x33 shift
+# 
+# Scan Code 54
+period 0x34
+colon 0x34 shift
+#
+# Scan Code 55
+minus 0x35 
+underscore 0x35 shift
+#
+# Suppress Windows unsupported AltGr keys
+#
+# Scan Code 17
+paragraph 0x10 altgr inhibit
+#
+# Scan Code 21
+tslash 0x14 altgr inhibit
+#
+# Scan Code 22
+leftarrow 0x15 altgr inhibit
+#
+# Scan Code 23
+downarrow 0x16 altgr inhibit
+#
+# Scan Code 24
+rightarrow 0x17 altgr inhibit
+#
+# Scan Code 25
+oslash 0x18 altgr inhibit
+#
+# Scan Code 26
+thorn 0x19 altgr inhibit
+#
+# Scan Code 31
+ae 0x1e altgr inhibit
+#
+# Scan Code 32
+ssharp 0x1f altgr inhibit
+#
+# Scan Code 33
+eth 0x20 altgr inhibit
+#
+# Scan Code 34
+dstroke 0x21 altgr inhibit
+#
+# Scan Code 35
+eng 0x22 altgr inhibit
+#
+# Scan Code 36
+hstroke 0x23 altgr inhibit
+#
+# Scan Code 38
+kra 0x25 altgr inhibit
+#
+# Scan Code 39
+lstroke 0x26 altgr inhibit
+#
+# Scan Code 46
+guillemotleft 0x2c altgr inhibit
+#
+# Scan Code 47
+guillemotright 0x2d altgr inhibit
+#
+# Scan Code 49
+leftdoublequotemark 0x2f altgr inhibit
+#
+# Scan Code 50
+rightdoublequotemark 0x30 altgr inhibit
+#
+# Scan Code 52
+mu 0x32 altgr inhibit
diff --git a/tools/ioemu/keymaps/en-gb b/tools/ioemu/keymaps/en-gb
new file mode 100644 (file)
index 0000000..b45f06c
--- /dev/null
@@ -0,0 +1,119 @@
+# generated from XKB map gb
+include common
+map 0x809
+exclam 0x02 shift
+onesuperior 0x02 altgr
+exclamdown 0x02 shift altgr
+quotedbl 0x03 shift
+twosuperior 0x03 altgr
+oneeighth 0x03 shift altgr
+sterling 0x04 shift
+threesuperior 0x04 altgr
+dollar 0x05 shift
+EuroSign 0x05 altgr
+percent 0x06 shift
+onehalf 0x06 altgr
+threeeighths 0x06 shift altgr
+asciicircum 0x07 shift
+threequarters 0x07 altgr
+fiveeighths 0x07 shift altgr
+ampersand 0x08 shift
+braceleft 0x08 altgr
+seveneighths 0x08 shift altgr
+asterisk 0x09 shift
+bracketleft 0x09 altgr
+trademark 0x09 shift altgr
+parenleft 0x0a shift
+bracketright 0x0a altgr
+plusminus 0x0a shift altgr
+parenright 0x0b shift
+braceright 0x0b altgr
+degree 0x0b shift altgr
+minus 0x0c
+underscore 0x0c shift
+backslash 0x0c altgr
+questiondown 0x0c shift altgr
+equal 0x0d
+plus 0x0d shift
+dead_cedilla 0x0d altgr
+dead_ogonek 0x0d shift altgr
+at 0x10 altgr
+Greek_OMEGA 0x10 shift altgr
+lstroke 0x11 altgr
+Lstroke 0x11 shift altgr
+paragraph 0x13 altgr
+registered 0x13 shift altgr
+tslash 0x14 altgr
+Tslash 0x14 shift altgr
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oslash 0x18 altgr
+Ooblique 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+bracketleft 0x1a
+braceleft 0x1a shift
+dead_diaeresis 0x1a altgr
+dead_abovering 0x1a shift altgr
+bracketright 0x1b
+braceright 0x1b shift
+dead_tilde 0x1b altgr
+dead_macron 0x1b shift altgr
+ae 0x1e altgr
+AE 0x1e shift altgr
+ssharp 0x1f altgr
+section 0x1f shift altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+dstroke 0x21 altgr
+ordfeminine 0x21 shift altgr
+eng 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+kra 0x25 altgr
+lstroke 0x26 altgr
+Lstroke 0x26 shift altgr
+semicolon 0x27
+colon 0x27 shift
+dead_acute 0x27 altgr
+dead_doubleacute 0x27 shift altgr
+apostrophe 0x28
+at 0x28 shift
+dead_circumflex 0x28 altgr
+dead_caron 0x28 shift altgr
+grave 0x29
+notsign 0x29 shift
+bar 0x29 altgr
+numbersign 0x2b
+asciitilde 0x2b shift
+dead_grave 0x2b altgr
+dead_breve 0x2b shift altgr
+guillemotleft 0x2c altgr
+less 0x2c shift altgr
+guillemotright 0x2d altgr
+greater 0x2d shift altgr
+cent 0x2e altgr
+copyright 0x2e shift altgr
+leftdoublequotemark 0x2f altgr
+rightdoublequotemark 0x30 altgr
+mu 0x32 altgr
+masculine 0x32 shift altgr
+comma 0x33
+less 0x33 shift
+horizconnector 0x33 altgr
+multiply 0x33 shift altgr
+period 0x34
+greater 0x34 shift
+periodcentered 0x34 altgr
+division 0x34 shift altgr
+slash 0x35
+question 0x35 shift
+dead_belowdot 0x35 altgr
+dead_abovedot 0x35 shift altgr
+backslash 0x56
+bar 0x56 shift
diff --git a/tools/ioemu/keymaps/en-us b/tools/ioemu/keymaps/en-us
new file mode 100644 (file)
index 0000000..f5784bb
--- /dev/null
@@ -0,0 +1,35 @@
+# generated from XKB map us
+include common
+map 0x409
+exclam 0x02 shift
+at 0x03 shift
+numbersign 0x04 shift
+dollar 0x05 shift
+percent 0x06 shift
+asciicircum 0x07 shift
+ampersand 0x08 shift
+asterisk 0x09 shift
+parenleft 0x0a shift
+parenright 0x0b shift
+minus 0x0c
+underscore 0x0c shift
+equal 0x0d
+plus 0x0d shift
+bracketleft 0x1a
+braceleft 0x1a shift
+bracketright 0x1b
+braceright 0x1b shift
+semicolon 0x27
+colon 0x27 shift
+apostrophe 0x28
+quotedbl 0x28 shift
+grave 0x29
+asciitilde 0x29 shift
+backslash 0x2b
+bar 0x2b shift
+comma 0x33
+less 0x33 shift
+period 0x34
+greater 0x34 shift
+slash 0x35
+question 0x35 shift
diff --git a/tools/ioemu/keymaps/es b/tools/ioemu/keymaps/es
new file mode 100644 (file)
index 0000000..0c29eec
--- /dev/null
@@ -0,0 +1,105 @@
+# generated from XKB map es
+include common
+map 0x40a
+exclam 0x02 shift
+bar 0x02 altgr
+quotedbl 0x03 shift
+at 0x03 altgr
+oneeighth 0x03 shift altgr
+periodcentered 0x04 shift
+numbersign 0x04 altgr
+sterling 0x04 shift altgr
+dollar 0x05 shift
+asciitilde 0x05 altgr
+percent 0x06 shift
+onehalf 0x06 altgr
+threeeighths 0x06 shift altgr
+ampersand 0x07 shift
+notsign 0x07 altgr
+fiveeighths 0x07 shift altgr
+slash 0x08 shift
+seveneighths 0x08 shift altgr
+parenleft 0x09 shift
+trademark 0x09 shift altgr
+parenright 0x0a shift
+plusminus 0x0a shift altgr
+equal 0x0b shift
+degree 0x0b shift altgr
+apostrophe 0x0c
+question 0x0c shift
+exclamdown 0x0d
+questiondown 0x0d shift
+Greek_OMEGA 0x10 shift altgr
+lstroke 0x11 altgr
+Lstroke 0x11 shift altgr
+EuroSign 0x12 altgr
+paragraph 0x13 altgr
+registered 0x13 shift altgr
+tslash 0x14 altgr
+Tslash 0x14 shift altgr
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oslash 0x18 altgr
+Ooblique 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+dead_grave 0x1a
+dead_circumflex 0x1a shift
+bracketleft 0x1a altgr
+dead_abovering 0x1a shift altgr
+plus 0x1b
+asterisk 0x1b shift
+bracketright 0x1b altgr
+dead_macron 0x1b shift altgr
+ae 0x1e altgr
+AE 0x1e shift altgr
+ssharp 0x1f altgr
+section 0x1f shift altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+dstroke 0x21 altgr
+eng 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+kra 0x25 altgr
+lstroke 0x26 altgr
+Lstroke 0x26 shift altgr
+ntilde 0x27
+Ntilde 0x27 shift
+dead_doubleacute 0x27 shift altgr
+dead_acute 0x28
+dead_diaeresis 0x28 shift
+braceleft 0x28 altgr
+masculine 0x29
+ordfeminine 0x29 shift
+backslash 0x29 altgr
+ccedilla 0x2b
+Ccedilla 0x2b shift
+braceright 0x2b altgr
+dead_breve 0x2b shift altgr
+guillemotleft 0x2c altgr
+less 0x56
+greater 0x56 shift
+guillemotright 0x2d altgr
+cent 0x2e altgr
+copyright 0x2e shift altgr
+leftdoublequotemark 0x2f altgr
+grave 0x2f shift altgr
+rightdoublequotemark 0x30 altgr
+mu 0x32 altgr
+comma 0x33
+semicolon 0x33 shift
+horizconnector 0x33 altgr
+multiply 0x33 shift altgr
+period 0x34
+colon 0x34 shift
+division 0x34 shift altgr
+minus 0x35
+underscore 0x35 shift
+dead_belowdot 0x35 altgr
+dead_abovedot 0x35 shift altgr
diff --git a/tools/ioemu/keymaps/et b/tools/ioemu/keymaps/et
new file mode 100644 (file)
index 0000000..b5a73fe
--- /dev/null
@@ -0,0 +1,86 @@
+map 0x00000425
+include common
+
+#
+# Top row
+#
+dead_caron 0x29
+dead_tilde 0x29 shift
+
+# 1
+exclam 0x2 shift
+
+# 2
+quotedbl 0x3 shift
+at 0x3 altgr
+
+# 3
+numbersign 0x4 shift
+sterling 0x4 altgr
+# 4
+currency 0x5 shift
+dollar 0x5 altgr
+# 5
+percent 0x6 shift
+# 6
+ampersand 0x7 shift
+# 7
+slash 0x8 shift
+braceleft 0x8 altgr
+# 8
+parenleft 0x9 shift
+bracketleft 0x9 altgr
+# 9
+parenright 0xa shift
+bracketright 0xa altgr
+# 0
+equal 0xb shift
+braceright 0xb altgr
+
+plus 0xc
+question 0xc shift
+backslash 0xc altgr
+
+acute 0xd
+dead_acute 0xd
+grave 0xd shift
+dead_grave 0xd shift
+
+#
+# QWERTY first row
+#
+EuroSign 0x12 altgr
+udiaeresis 0x1a 
+Udiaeresis 0x1a shift
+otilde 0x1b 
+Otilde 0x1b shift
+section 0x1b altgr
+
+#
+# QWERTY second row
+#
+scaron 0x1f altgr
+Scaron 0x1f altgr shift
+odiaeresis 0x27 
+Odiaeresis 0x27 shift
+adiaeresis 0x28 
+Adiaeresis 0x28 shift
+asciicircum 0x28 altgr
+apostrophe 0x2b
+asterisk 0x2b shift
+onehalf 0x2b altgr
+#
+# QWERTY third row
+#
+less 0x56 
+greater 0x56 shift
+bar 0x56 altgr
+zcaron 0x2c altgr
+Zcaron 0x2c altgr shift
+comma 0x33
+semicolon 0x33 shift
+period 0x34
+colon 0x34 shift
+minus 0x35
+underscore 0x35 shift
+
diff --git a/tools/ioemu/keymaps/fi b/tools/ioemu/keymaps/fi
new file mode 100644 (file)
index 0000000..2a4e0f0
--- /dev/null
@@ -0,0 +1,124 @@
+# generated from XKB map se_FI
+include common
+map 0x40b
+exclam 0x02 shift
+exclamdown 0x02 altgr
+onesuperior 0x02 shift altgr
+quotedbl 0x03 shift
+at 0x03 altgr
+twosuperior 0x03 shift altgr
+numbersign 0x04 shift
+sterling 0x04 altgr
+threesuperior 0x04 shift altgr
+currency 0x05 shift
+dollar 0x05 altgr
+onequarter 0x05 shift altgr
+percent 0x06 shift
+onehalf 0x06 altgr
+cent 0x06 shift altgr
+ampersand 0x07 shift
+yen 0x07 altgr
+fiveeighths 0x07 shift altgr
+slash 0x08 shift
+braceleft 0x08 altgr
+division 0x08 shift altgr
+parenleft 0x09 shift
+bracketleft 0x09 altgr
+guillemotleft 0x09 shift altgr
+parenright 0x0a shift
+bracketright 0x0a altgr
+guillemotright 0x0a shift altgr
+equal 0x0b shift
+braceright 0x0b altgr
+degree 0x0b shift altgr
+plus 0x0c
+question 0x0c shift
+backslash 0x0c altgr
+questiondown 0x0c shift altgr
+dead_acute 0x0d
+dead_grave 0x0d shift
+plusminus 0x0d altgr
+notsign 0x0d shift altgr
+at 0x10 altgr
+Greek_OMEGA 0x10 shift altgr
+lstroke 0x11 altgr
+Lstroke 0x11 shift altgr
+EuroSign 0x12 altgr
+cent 0x12 shift altgr
+registered 0x13 altgr
+thorn 0x14 altgr
+THORN 0x14 shift altgr
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oe 0x18 altgr
+OE 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+aring 0x1a
+Aring 0x1a shift
+dead_diaeresis 0x1a altgr
+dead_abovering 0x1a shift altgr
+dead_diaeresis 0x1b
+dead_circumflex 0x1b shift
+dead_tilde 0x1b altgr
+dead_caron 0x1b shift altgr
+ordfeminine 0x1e altgr
+masculine 0x1e shift altgr
+ssharp 0x1f altgr
+section 0x1f shift altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+dstroke 0x21 altgr
+ordfeminine 0x21 shift altgr
+eng 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+kra 0x25 altgr
+ampersand 0x25 shift altgr
+lstroke 0x26 altgr
+Lstroke 0x26 shift altgr
+odiaeresis 0x27
+Odiaeresis 0x27 shift
+oslash 0x27 altgr
+Ooblique 0x27 shift altgr
+adiaeresis 0x28
+Adiaeresis 0x28 shift
+ae 0x28 altgr
+AE 0x28 shift altgr
+section 0x29
+onehalf 0x29 shift
+paragraph 0x29 altgr
+threequarters 0x29 shift altgr
+apostrophe 0x2b
+asterisk 0x2b shift
+acute 0x2b altgr
+multiply 0x2b shift altgr
+guillemotleft 0x2c altgr
+less 0x2c shift altgr
+guillemotright 0x2d altgr
+greater 0x2d shift altgr
+copyright 0x2e altgr
+leftdoublequotemark 0x2f altgr
+grave 0x2f shift altgr
+rightdoublequotemark 0x30 altgr
+apostrophe 0x30 shift altgr
+mu 0x32 altgr
+masculine 0x32 shift altgr
+comma 0x33
+semicolon 0x33 shift
+dead_cedilla 0x33 altgr
+dead_ogonek 0x33 shift altgr
+period 0x34
+colon 0x34 shift
+periodcentered 0x34 altgr
+dead_abovedot 0x34 shift altgr
+minus 0x35
+underscore 0x35 shift
+hyphen 0x35 altgr
+macron 0x35 shift altgr
+nobreakspace 0x39 altgr
diff --git a/tools/ioemu/keymaps/fo b/tools/ioemu/keymaps/fo
new file mode 100644 (file)
index 0000000..83add42
--- /dev/null
@@ -0,0 +1,77 @@
+map 0x438
+include common
+
+#
+# Top row
+#
+onehalf 0x29
+section 0x29 shift
+
+# 1
+exclam 0x2 shift
+
+# 2
+quotedbl 0x3 shift
+at 0x3 altgr
+
+# 3
+numbersign 0x4 shift
+sterling 0x4 altgr
+# 4
+currency 0x5 shift
+dollar 0x5 altgr
+# 5
+percent 0x6 shift
+# 6
+ampersand 0x7 shift
+# 7
+slash 0x8 shift
+braceleft 0x8 altgr
+# 8
+parenleft 0x9 shift
+bracketleft 0x9 altgr
+# 9
+parenright 0xa shift
+bracketright 0xa altgr
+# 0
+equal 0xb shift
+braceright 0xb altgr
+
+plus 0xc
+question 0xc shift
+plusminus 0xc altgr
+
+bar 0xd altgr
+dead_acute 0xd
+
+#
+# QWERTY first row
+#
+EuroSign 0x12 altgr
+aring 0x1a
+Aring 0x1a shift
+eth 0x1b addupper
+asciitilde 0x1b altgr
+
+#
+# QWERTY second row
+#
+ae 0x27 addupper
+oslash 0x28
+Ooblique 0x28 shift
+apostrophe 0x2b
+asterisk 0x2b shift
+
+#
+# QWERTY third row
+#
+less 0x56
+greater 0x56 shift
+backslash 0x56 altgr
+comma 0x33
+semicolon 0x33 shift
+period 0x34
+colon 0x34 shift
+minus 0x35
+underscore 0x35 shift
+
diff --git a/tools/ioemu/keymaps/fr b/tools/ioemu/keymaps/fr
new file mode 100644 (file)
index 0000000..cbb4591
--- /dev/null
@@ -0,0 +1,181 @@
+include common
+map 0x40c
+#
+# Top row
+#
+twosuperior 0x29
+notsign 0x29 altgr
+
+ampersand 0x02
+1 0x02 shift
+onesuperior 0x02 altgr
+exclamdown 0x02 shift altgr
+
+eacute 0x03
+2 0x03 shift
+asciitilde 0x03 altgr
+oneeighth 0x03 shift altgr
+
+quotedbl 0x04
+3 0x04 shift
+numbersign 0x04 altgr
+
+apostrophe 0x05
+4 0x05 shift
+braceleft 0x05 altgr
+
+parenleft 0x06
+5 0x06 shift
+bracketleft 0x06 altgr
+threeeighths 0x06 shift altgr
+
+minus 0x07
+6 0x07 shift
+bar 0x07 altgr
+fiveeighths 0x07 shift altgr
+
+egrave 0x08
+7 0x08 shift
+grave 0x08 altgr
+seveneighths 0x08 shift altgr
+
+underscore 0x09
+8 0x09 shift
+backslash 0x09 altgr
+trademark 0x09 shift altgr
+
+ccedilla 0x0a
+9 0x0a shift
+asciicircum 0x0a altgr
+plusminus 0x0a shift altgr
+
+agrave 0x0b
+0 0x0b shift
+at 0x0b altgr
+
+parenright 0x0c
+degree 0x0c shift
+bracketright 0x0c altgr
+questiondown 0x0c shift altgr
+
+equal 0x0d
+plus 0x0d shift
+braceright 0x0d altgr
+dead_ogonek 0x0d shift altgr
+
+#
+# AZERTY first row
+#
+
+a 0x10 addupper
+ae 0x10 altgr
+AE 0x10 shift altgr
+
+z 0x11 addupper
+guillemotleft 0x11 altgr
+
+EuroSign 0x12 altgr
+
+paragraph 0x13 altgr
+registered 0x13 shift altgr
+
+tslash 0x14 altgr
+Tslash 0x14 shift altgr
+
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+
+oslash 0x18 altgr
+Ooblique 0x18 shift altgr
+
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+
+dead_circumflex 0x1a 
+dead_diaeresis 0x1a shift
+dead_abovering 0x1a shift altgr
+
+dollar 0x1b
+sterling 0x1b shift
+currency 0x1b altgr
+dead_macron 0x1b shift altgr
+
+#
+# AZERTY second row
+#
+q 0x1e addupper
+Greek_OMEGA 0x1e shift altgr
+
+ssharp 0x1f altgr
+
+eth 0x20 altgr
+ETH 0x20 shift altgr
+
+dstroke 0x21 altgr
+ordfeminine 0x21 shift altgr
+
+eng 0x22 altgr
+ENG 0x22 shift altgr
+
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+
+kra 0x25 altgr
+
+lstroke 0x26 altgr
+Lstroke 0x26 shift altgr
+
+m 0x27 addupper
+masculine 0x27 shift altgr
+
+ugrave 0x28
+percent 0x28 shift
+dead_caron 0x28 shift altgr
+
+asterisk 0x2b
+mu 0x2b shift
+dead_grave 0x2b altgr
+dead_breve 0x2b shift altgr
+
+#
+# AZERTY third row
+#
+less 0x56
+greater 0x56 shift
+
+w 0x2c addupper
+
+guillemotright 0x2d altgr
+
+cent 0x2e altgr
+copyright 0x2e shift altgr
+
+leftdoublequotemark 0x2f altgr
+
+rightdoublequotemark 0x30 altgr
+
+comma 0x32
+question 0x32 shift
+dead_acute 0x32 altgr
+dead_doubleacute 0x32 shift altgr
+
+semicolon 0x33
+period 0x33 shift
+horizconnector 0x33 altgr
+multiply 0x33 shift altgr
+
+colon 0x34
+slash 0x34 shift
+periodcentered 0x34 altgr
+division 0x34 shift altgr
+
+exclam 0x35
+section 0x35 shift
+dead_belowdot 0x35 altgr
+dead_abovedot 0x35 shift altgr
diff --git a/tools/ioemu/keymaps/fr-be b/tools/ioemu/keymaps/fr-be
new file mode 100644 (file)
index 0000000..92d668e
--- /dev/null
@@ -0,0 +1,140 @@
+# generated from XKB map be
+include common
+map 0x80c
+ampersand 0x02
+1 0x02 shift
+bar 0x02 altgr
+exclamdown 0x02 shift altgr
+eacute 0x03
+2 0x03 shift
+at 0x03 altgr
+oneeighth 0x03 shift altgr
+quotedbl 0x04
+3 0x04 shift
+numbersign 0x04 altgr
+sterling 0x04 shift altgr
+apostrophe 0x05
+4 0x05 shift
+onequarter 0x05 altgr
+dollar 0x05 shift altgr
+parenleft 0x06
+5 0x06 shift
+onehalf 0x06 altgr
+threeeighths 0x06 shift altgr
+section 0x07
+6 0x07 shift
+asciicircum 0x07 altgr
+fiveeighths 0x07 shift altgr
+egrave 0x08
+7 0x08 shift
+braceleft 0x08 altgr
+seveneighths 0x08 shift altgr
+exclam 0x09
+8 0x09 shift
+bracketleft 0x09 altgr
+trademark 0x09 shift altgr
+ccedilla 0x0a
+9 0x0a shift
+braceleft 0x0a altgr
+plusminus 0x0a shift altgr
+agrave 0x0b
+0 0x0b shift
+braceright 0x0b altgr
+degree 0x0b shift altgr
+parenright 0x0c
+degree 0x0c shift
+backslash 0x0c altgr
+questiondown 0x0c shift altgr
+minus 0x0d
+underscore 0x0d shift
+dead_cedilla 0x0d altgr
+dead_ogonek 0x0d shift altgr
+a 0x10 addupper
+at 0x10 altgr
+Greek_OMEGA 0x10 shift altgr
+z 0x11 addupper
+lstroke 0x11 altgr
+Lstroke 0x11 shift altgr
+EuroSign 0x12 altgr
+cent 0x12 shift altgr
+paragraph 0x13 altgr
+registered 0x13 shift altgr
+tslash 0x14 altgr
+Tslash 0x14 shift altgr
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oslash 0x18 altgr
+Ooblique 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+dead_circumflex 0x1a
+dead_diaeresis 0x1a shift
+bracketleft 0x1a altgr
+dead_abovering 0x1a shift altgr
+dollar 0x1b
+asterisk 0x1b shift
+bracketright 0x1b altgr
+dead_macron 0x1b shift altgr
+q 0x1e addupper
+ae 0x1e altgr
+AE 0x1e shift altgr
+ssharp 0x1f altgr
+section 0x1f shift altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+dstroke 0x21 altgr
+ordfeminine 0x21 shift altgr
+eng 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+kra 0x25 altgr
+ampersand 0x25 shift altgr
+lstroke 0x26 altgr
+Lstroke 0x26 shift altgr
+m 0x27 addupper
+dead_acute 0x27 altgr
+dead_doubleacute 0x27 shift altgr
+ugrave 0x28
+percent 0x28 shift
+dead_acute 0x28 altgr
+dead_caron 0x28 shift altgr
+twosuperior 0x29
+threesuperior 0x29 shift
+notsign 0x29 altgr
+mu 0x2b
+sterling 0x2b shift
+dead_grave 0x2b altgr
+dead_breve 0x2b shift altgr
+w 0x2c addupper
+guillemotleft 0x2c altgr
+less 0x2c shift altgr
+guillemotright 0x2d altgr
+greater 0x2d shift altgr
+cent 0x2e altgr
+copyright 0x2e shift altgr
+leftdoublequotemark 0x2f altgr
+grave 0x2f shift altgr
+rightdoublequotemark 0x30 altgr
+apostrophe 0x30 shift altgr
+comma 0x32
+question 0x32 shift
+dead_cedilla 0x32 altgr
+masculine 0x32 shift altgr
+semicolon 0x33
+period 0x33 shift
+horizconnector 0x33 altgr
+multiply 0x33 shift altgr
+colon 0x34
+slash 0x34 shift
+periodcentered 0x34 altgr
+division 0x34 shift altgr
+equal 0x35
+plus 0x35 shift
+dead_tilde 0x35 altgr
+dead_abovedot 0x35 shift altgr
+backslash 0x56 altgr
diff --git a/tools/ioemu/keymaps/fr-ca b/tools/ioemu/keymaps/fr-ca
new file mode 100644 (file)
index 0000000..b645208
--- /dev/null
@@ -0,0 +1,50 @@
+# Canadian French
+# By Simon Germain
+include common
+map 0xc0c
+
+backslash 0x29 altgr
+plusminus 0x2 altgr
+at 0x3 altgr
+sterling 0x4 altgr
+cent 0x5 altgr
+currency 0x6 altgr
+notsign 0x7 altgr
+bar 0x29 shift
+twosuperior 0x9 altgr
+threesuperior 0xa altgr
+onequarter 0xb altgr
+onehalf 0xc altgr
+threequarters 0xd altgr
+section 0x18 altgr
+paragraph 0x19 altgr
+bracketleft 0x1a altgr
+bracketright 0x1b altgr
+asciitilde 0x27 altgr
+braceleft 0x28 altgr
+braceright 0x2b altgr
+less 0x2b
+greater 0x2b shift
+guillemotleft 0x56
+guillemotright 0x56 shift
+degree 0x56 altgr
+mu 0x32 altgr
+eacute 0x35
+dead_acute 0x35 altgr
+dead_grave 0x28
+dead_circumflex 0x1a
+dead_circumflex 0x1a shift
+dead_cedilla 0x1b
+dead_diaeresis 0x1b shift
+exclam 0x2 shift
+quotedbl 0x3 shift
+slash 0x4 shift
+dollar 0x5 shift
+percent 0x6 shift
+question 0x7 shift
+ampersand 0x8 shift
+asterisk 0x9 shift
+parenleft 0xa shift
+parenright 0xb shift
+underscore 0xc shift
+plus 0xd shift
diff --git a/tools/ioemu/keymaps/fr-ch b/tools/ioemu/keymaps/fr-ch
new file mode 100644 (file)
index 0000000..4620d20
--- /dev/null
@@ -0,0 +1,114 @@
+# generated from XKB map fr_CH
+include common
+map 0x100c
+exclam 0x02 shift
+onesuperior 0x02 altgr
+exclamdown 0x02 shift altgr
+quotedbl 0x03 shift
+twosuperior 0x03 altgr
+oneeighth 0x03 shift altgr
+section 0x04 shift
+threesuperior 0x04 altgr
+sterling 0x04 shift altgr
+dollar 0x05 shift
+onequarter 0x05 altgr
+currency 0x05 shift altgr
+percent 0x06 shift
+onehalf 0x06 altgr
+threeeighths 0x06 shift altgr
+ampersand 0x07 shift
+threequarters 0x07 altgr
+fiveeighths 0x07 shift altgr
+slash 0x08 shift
+braceleft 0x08 altgr
+seveneighths 0x08 shift altgr
+parenleft 0x09 shift
+bracketleft 0x09 altgr
+trademark 0x09 shift altgr
+parenright 0x0a shift
+bracketright 0x0a altgr
+plusminus 0x0a shift altgr
+equal 0x0b shift
+braceright 0x0b altgr
+ssharp 0x0c
+question 0x0c shift
+backslash 0x0c altgr
+questiondown 0x0c shift altgr
+acute 0x0d
+dead_acute 0x0d
+grave 0x0d shift
+dead_grave 0x0d shift
+dead_cedilla 0x0d altgr
+dead_ogonek 0x0d shift altgr
+at 0x10 altgr
+Greek_OMEGA 0x10 shift altgr
+EuroSign 0x12 altgr
+paragraph 0x13 altgr
+registered 0x13 shift altgr
+tslash 0x14 altgr
+Tslash 0x14 shift altgr
+z 0x15 addupper
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oslash 0x18 altgr
+Ooblique 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+udiaeresis 0x1a
+Udiaeresis 0x1a shift
+dead_diaeresis 0x1a altgr
+dead_abovering 0x1a shift altgr
+plus 0x1b
+asterisk 0x1b shift
+asciitilde 0x1b altgr
+dead_tilde 0x1b altgr
+dead_macron 0x1b shift altgr
+ae 0x1e altgr
+AE 0x1e shift altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+dstroke 0x21 altgr
+ordfeminine 0x21 shift altgr
+eng 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+kra 0x25 altgr
+odiaeresis 0x27
+Odiaeresis 0x27 shift
+dead_doubleacute 0x27 altgr
+adiaeresis 0x28
+Adiaeresis 0x28 shift
+dead_caron 0x28 shift altgr
+asciicircum 0x29
+dead_circumflex 0x29
+degree 0x29 shift
+notsign 0x29 altgr
+numbersign 0x2b
+apostrophe 0x2b shift
+dead_breve 0x2b shift altgr
+y 0x2c addupper
+guillemotleft 0x2c altgr
+guillemotright 0x2d altgr
+cent 0x2e altgr
+copyright 0x2e shift altgr
+leftdoublequotemark 0x2f altgr
+rightdoublequotemark 0x30 altgr
+mu 0x32 altgr
+masculine 0x32 shift altgr
+comma 0x33
+semicolon 0x33 shift
+horizconnector 0x33 altgr
+multiply 0x33 shift altgr
+period 0x34
+colon 0x34 shift
+periodcentered 0x34 altgr
+division 0x34 shift altgr
+minus 0x35
+underscore 0x35 shift
+dead_belowdot 0x35 altgr
+dead_abovedot 0x35 shift altgr
diff --git a/tools/ioemu/keymaps/hr b/tools/ioemu/keymaps/hr
new file mode 100644 (file)
index 0000000..613aa69
--- /dev/null
@@ -0,0 +1,125 @@
+# generated from XKB map hr
+include common
+map 0x41a
+exclam 0x02 shift
+asciitilde 0x02 altgr
+dead_tilde 0x02 shift altgr
+quotedbl 0x03 shift
+dead_caron 0x03 altgr
+caron 0x03 shift altgr
+numbersign 0x04 shift
+asciicircum 0x04 altgr
+dead_circumflex 0x04 shift altgr
+dollar 0x05 shift
+dead_breve 0x05 altgr
+breve 0x05 shift altgr
+percent 0x06 shift
+degree 0x06 altgr
+dead_abovering 0x06 shift altgr
+ampersand 0x07 shift
+dead_ogonek 0x07 altgr
+ogonek 0x07 shift altgr
+slash 0x08 shift
+grave 0x08 altgr
+dead_grave 0x08 shift altgr
+parenleft 0x09 shift
+dead_abovedot 0x09 altgr
+abovedot 0x09 shift altgr
+parenright 0x0a shift
+dead_acute 0x0a altgr
+apostrophe 0x0a shift altgr
+equal 0x0b shift
+dead_doubleacute 0x0b altgr
+doubleacute 0x0b shift altgr
+apostrophe 0x0c
+question 0x0c shift
+dead_diaeresis 0x0c altgr
+diaeresis 0x0c shift altgr
+plus 0x0d
+asterisk 0x0d shift
+dead_cedilla 0x0d altgr
+cedilla 0x0d shift altgr
+backslash 0x10 altgr
+Greek_OMEGA 0x10 shift altgr
+bar 0x11 altgr
+Lstroke 0x11 shift altgr
+EuroSign 0x12 altgr
+paragraph 0x13 altgr
+registered 0x13 shift altgr
+tslash 0x14 altgr
+Tslash 0x14 shift altgr
+z 0x15 addupper
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oslash 0x18 altgr
+Ooblique 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+scaron 0x1a
+Scaron 0x1a shift
+division 0x1a altgr
+dead_abovering 0x1a shift altgr
+dstroke 0x1b
+Dstroke 0x1b shift
+multiply 0x1b altgr
+dead_macron 0x1b shift altgr
+ae 0x1e altgr
+AE 0x1e shift altgr
+ssharp 0x1f altgr
+section 0x1f shift altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+bracketleft 0x21 altgr
+ordfeminine 0x21 shift altgr
+bracketright 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+lstroke 0x25 altgr
+ampersand 0x25 shift altgr
+Lstroke 0x26 altgr
+ccaron 0x27
+Ccaron 0x27 shift
+dead_acute 0x27 altgr
+dead_doubleacute 0x27 shift altgr
+cacute 0x28
+Cacute 0x28 shift
+ssharp 0x28 altgr
+dead_caron 0x28 shift altgr
+dead_cedilla 0x29
+dead_diaeresis 0x29 shift
+notsign 0x29 altgr
+zcaron 0x2b
+Zcaron 0x2b shift
+currency 0x2b altgr
+dead_breve 0x2b shift altgr
+y 0x2c addupper
+guillemotleft 0x2c altgr
+less 0x2c shift altgr
+guillemotright 0x2d altgr
+greater 0x2d shift altgr
+cent 0x2e altgr
+copyright 0x2e shift altgr
+at 0x2f altgr
+grave 0x2f shift altgr
+braceleft 0x30 altgr
+apostrophe 0x30 shift altgr
+braceright 0x31 altgr
+section 0x32 altgr
+masculine 0x32 shift altgr
+comma 0x33
+semicolon 0x33 shift
+horizconnector 0x33 altgr
+multiply 0x33 shift altgr
+period 0x34
+colon 0x34 shift
+periodcentered 0x34 altgr
+division 0x34 shift altgr
+minus 0x35
+underscore 0x35 shift
+dead_belowdot 0x35 altgr
+dead_abovedot 0x35 shift altgr
diff --git a/tools/ioemu/keymaps/hu b/tools/ioemu/keymaps/hu
new file mode 100644 (file)
index 0000000..8aba444
--- /dev/null
@@ -0,0 +1,115 @@
+# Hungarian keyboard layout (QWERTZ)
+# Created by: The NeverGone <never@delfin.klte.hu>
+
+include common
+map 0x40e
+
+
+# AltGr keys:
+notsign 0x29 altgr
+asciitilde 0x02 altgr
+caron 0x03 altgr
+asciicircum 0x04 altgr
+breve 0x05 altgr
+degree 0x06 altgr
+ogonek 0x07 altgr
+grave 0x08 altgr
+abovedot 0x09 altgr
+acute 0x0a altgr
+doubleacute 0x0b altgr
+diaeresis 0x0c altgr
+cedilla 0x0d altgr
+backslash 0x10 altgr
+bar 0x11 altgr
+EuroSign 0x12 altgr
+Iacute 0x17 altgr
+division 0x1a altgr
+multiply 0x1b altgr
+dstroke 0x1f altgr
+Dstroke 0x20 altgr
+bracketleft 0x21 altgr
+bracketright 0x22 altgr
+iacute 0x24 altgr
+lstroke 0x25 altgr
+Lstroke 0x26 altgr
+dollar 0x27 altgr
+ssharp 0x28 altgr
+currency 0x2b altgr
+less 0x56 altgr
+greater 0x2c altgr
+numbersign 0x2d altgr
+ampersand 0x2e altgr
+at 0x2f altgr
+braceleft 0x30 altgr
+braceright 0x31 altgr
+semicolon 0x33 altgr
+asterisk 0x35 altgr
+
+
+# Shift keys:
+section 0x29 shift
+apostrophe 0x02 shift
+quotedbl 0x03 shift
+plus 0x04 shift
+exclam 0x05 shift
+percent 0x06 shift
+slash 0x07 shift
+equal 0x08 shift
+parenleft 0x09 shift
+parenright 0x0a shift
+Odiaeresis 0x0b shift
+Udiaeresis 0x0c shift
+Oacute 0x0d shift
+Z 0x15 shift
+Odoubleacute 0x1a shift
+Uacute 0x1b shift
+Eacute 0x27 shift
+Aacute 0x28 shift
+Udoubleacute 0x2b shift
+Y 0x2c shift
+question 0x33 shift
+colon 0x34 shift
+underscore 0x35 shift
+F13 0x3b shift
+F14 0x3c shift
+F15 0x3d shift
+F16 0x3e shift
+F17 0x3f shift
+F18 0x40 shift
+F19 0x41 shift
+F20 0x42 shift
+F21 0x43 shift
+F22 0x44 shift
+F23 0x57 shift
+F24 0x58 shift
+
+
+# Ctrl keys:
+F25 0x3b ctrl
+F26 0x3c ctrl
+F27 0x3d ctrl
+F28 0x3e ctrl
+F29 0x3f ctrl
+F30 0x40 ctrl
+F31 0x41 ctrl
+F32 0x42 ctrl
+F33 0x43 ctrl
+F34 0x44 ctrl
+F35 0x57 ctrl
+#NoSymbol 0x58 ctrl
+
+
+0 0x29
+odiaeresis 0x0b
+udiaeresis 0x0c
+oacute 0x0d
+z 0x15
+odoubleacute 0x1a
+uacute 0x1b
+eacute 0x27
+aacute 0x28
+udoubleacute 0x2b
+y 0x2c
+comma 0x33
+period 0x34
+minus 0x35
diff --git a/tools/ioemu/keymaps/is b/tools/ioemu/keymaps/is
new file mode 100644 (file)
index 0000000..8fde40f
--- /dev/null
@@ -0,0 +1,140 @@
+# 2004-03-16 Halldór Guðmundsson and Morten Lange 
+# Keyboard definition file for the Icelandic keyboard
+# to be used in rdesktop 1.3.x ( See rdesktop.org) 
+# generated from XKB map de, and changed manually
+# Location for example /usr/local/share/rdesktop/keymaps/is
+include common
+map 0x40f
+exclam 0x02 shift
+onesuperior 0x02 altgr
+exclamdown 0x02 shift altgr
+quotedbl 0x03 shift
+twosuperior 0x03 altgr
+oneeighth 0x03 shift altgr
+#section 0x04 shift
+numbersign 0x04 shift
+threesuperior 0x04 altgr
+sterling 0x04 shift altgr
+dollar 0x05 shift
+onequarter 0x05 altgr
+currency 0x05 shift altgr
+percent 0x06 shift
+onehalf 0x06 altgr
+threeeighths 0x06 shift altgr
+ampersand 0x07 shift
+threequarters 0x07 altgr
+fiveeighths 0x07 shift altgr
+slash 0x08 shift
+braceleft 0x08 altgr
+seveneighths 0x08 shift altgr
+parenleft 0x09 shift
+bracketleft 0x09 altgr
+trademark 0x09 shift altgr
+parenright 0x0a shift
+bracketright 0x0a altgr
+plusminus 0x0a shift altgr
+equal 0x0b shift
+braceright 0x0b altgr
+#ssharp 0x0c
+odiaeresis 0x0c
+#question 0x0c shift
+Odiaeresis 0x0c shift
+backslash 0x0c altgr
+questiondown 0x0c shift altgr
+#acute 0x0d
+minus  0x0d
+#dead_acute 0x0d
+#grave 0x0d shift
+#dead_grave 0x0d shift
+underscore 0x0d shift
+dead_cedilla 0x0d altgr
+dead_ogonek 0x0d shift altgr
+at 0x10 altgr
+Greek_OMEGA 0x10 shift altgr
+EuroSign 0x12 altgr
+paragraph 0x13 altgr
+registered 0x13 shift altgr
+tslash 0x14 altgr
+Tslash 0x14 shift altgr
+#z 0x15 addupper
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oslash 0x18 altgr
+Ooblique 0x18 shift altgr
+#thorn 0x19 altgr
+#THORN 0x19 shift altgr
+#udiaeresis 0x1a
+#Udiaeresis 0x1a shift
+#dead_diaeresis 0x1a altgr
+#dead_abovering 0x1a shift altgr
+eth 0x1a 
+ETH 0x1a shift 
+apostrophe 0x1b
+question 0x1b shift
+#plus 0x1b
+#asterisk 0x1b shift
+asciitilde 0x1b altgr
+#grave 0x1b altgr
+#dead_tilde 0x1b altgr
+#dead_macron 0x1b shift altgr
+#ae 0x1e altgr
+#AE 0x1e shift altgr
+#eth 0x20 altgr
+#eth 0x20 
+#ETH 0x20 shift altgr
+#ETH 0x20 shift 
+dstroke 0x21 altgr
+ordfeminine 0x21 shift altgr
+eng 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+kra 0x25 altgr
+#adiaeresis 0x27
+#Adiaeresis 0x27 shift
+ae 0x27 
+AE 0x27 shift 
+dead_doubleacute 0x27 altgr
+#adiaeresis 0x28
+#Adiaeresis 0x28 shift
+#dead_caron 0x28 shift altgr
+#asciicircum 0x29
+acute  0x28
+dead_acute 0x28
+#dead_circumflex 0x29
+#degree 0x29 shift
+#notsign 0x29 altgr
+plus 0x2b
+asterisk 0x2b shift
+grave 0x2b altgr
+#numbersign 0x2b
+#apostrophe 0x2b shift
+#dead_breve 0x2b shift altgr
+#y 0x2c addupper
+guillemotleft 0x2c altgr
+guillemotright 0x2d altgr
+cent 0x2e altgr
+copyright 0x2e shift altgr
+leftdoublequotemark 0x2f altgr
+rightdoublequotemark 0x30 altgr
+mu 0x32 altgr
+masculine 0x32 shift altgr
+comma 0x33
+semicolon 0x33 shift
+horizconnector 0x33 altgr
+multiply 0x33 shift altgr
+period 0x34
+colon 0x34 shift
+periodcentered 0x34 altgr
+division 0x34 shift altgr
+#minus 0x35
+#underscore 0x35 shift
+thorn 0x35 
+THORN 0x35 shift 
+dead_belowdot 0x35 altgr
+dead_abovedot 0x35 shift altgr
+
diff --git a/tools/ioemu/keymaps/it b/tools/ioemu/keymaps/it
new file mode 100644 (file)
index 0000000..00ca73a
--- /dev/null
@@ -0,0 +1,115 @@
+# generated from XKB map it
+include common
+map 0x410
+exclam 0x02 shift
+onesuperior 0x02 altgr
+exclamdown 0x02 shift altgr
+quotedbl 0x03 shift
+twosuperior 0x03 altgr
+oneeighth 0x03 shift altgr
+sterling 0x04 shift
+threesuperior 0x04 altgr
+dollar 0x05 shift
+onequarter 0x05 altgr
+percent 0x06 shift
+onehalf 0x06 altgr
+threeeighths 0x06 shift altgr
+ampersand 0x07 shift
+threequarters 0x07 altgr
+fiveeighths 0x07 shift altgr
+slash 0x08 shift
+braceleft 0x08 altgr
+seveneighths 0x08 shift altgr
+parenleft 0x09 shift
+trademark 0x09 shift altgr
+parenright 0x0a shift
+plusminus 0x0a shift altgr
+equal 0x0b shift
+braceright 0x0b altgr
+degree 0x0b shift altgr
+apostrophe 0x0c
+question 0x0c shift
+grave 0x0c altgr
+questiondown 0x0c shift altgr
+igrave 0x0d
+asciicircum 0x0d shift
+asciitilde 0x0d altgr
+dead_ogonek 0x0d shift altgr
+at 0x10 altgr
+Greek_OMEGA 0x10 shift altgr
+lstroke 0x11 altgr
+Lstroke 0x11 shift altgr
+EuroSign 0x12 altgr
+cent 0x12 shift altgr
+paragraph 0x13 altgr
+registered 0x13 shift altgr
+tslash 0x14 altgr
+Tslash 0x14 shift altgr
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oslash 0x18 altgr
+Ooblique 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+egrave 0x1a
+eacute 0x1a shift
+bracketleft 0x1a altgr
+dead_abovering 0x1a shift altgr
+plus 0x1b
+asterisk 0x1b shift
+bracketright 0x1b altgr
+dead_macron 0x1b shift altgr
+ae 0x1e altgr
+AE 0x1e shift altgr
+ssharp 0x1f altgr
+section 0x1f shift altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+dstroke 0x21 altgr
+ordfeminine 0x21 shift altgr
+eng 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+kra 0x25 altgr
+lstroke 0x26 altgr
+Lstroke 0x26 shift altgr
+ograve 0x27
+ccedilla 0x27 shift
+at 0x27 altgr
+dead_doubleacute 0x27 shift altgr
+agrave 0x28
+degree 0x28 shift
+numbersign 0x28 altgr
+backslash 0x29
+bar 0x29 shift
+notsign 0x29 altgr
+ugrave 0x2b
+section 0x2b shift
+dead_grave 0x2b altgr
+dead_breve 0x2b shift altgr
+guillemotleft 0x2c altgr
+guillemotright 0x2d altgr
+cent 0x2e altgr
+copyright 0x2e shift altgr
+leftdoublequotemark 0x2f altgr
+grave 0x2f shift altgr
+rightdoublequotemark 0x30 altgr
+mu 0x32 altgr
+masculine 0x32 shift altgr
+comma 0x33
+semicolon 0x33 shift
+horizconnector 0x33 altgr
+multiply 0x33 shift altgr
+period 0x34
+colon 0x34 shift
+periodcentered 0x34 altgr
+division 0x34 shift altgr
+minus 0x35
+underscore 0x35 shift
+dead_belowdot 0x35 altgr
+dead_abovedot 0x35 shift altgr
diff --git a/tools/ioemu/keymaps/ja b/tools/ioemu/keymaps/ja
new file mode 100644 (file)
index 0000000..8fd0b9e
--- /dev/null
@@ -0,0 +1,104 @@
+# generated from XKB map jp106
+include common
+map 0x411
+exclam 0x02 shift
+kana_NU 0x02 altgr
+quotedbl 0x03 shift
+kana_FU 0x03 altgr
+numbersign 0x04 shift
+kana_A 0x04 altgr
+kana_a 0x04 shift altgr
+dollar 0x05 shift
+kana_U 0x05 altgr
+kana_u 0x05 shift altgr
+percent 0x06 shift
+kana_E 0x06 altgr
+kana_e 0x06 shift altgr
+ampersand 0x07 shift
+kana_O 0x07 altgr
+kana_o 0x07 shift altgr
+apostrophe 0x08 shift
+kana_YA 0x08 altgr
+kana_ya 0x08 shift altgr
+parenleft 0x09 shift
+kana_YU 0x09 altgr
+kana_yu 0x09 shift altgr
+parenright 0x0a shift
+kana_YO 0x0a altgr
+kana_yo 0x0a shift altgr
+asciitilde 0x0b shift
+kana_WA 0x0b altgr
+kana_WO 0x0b shift altgr
+minus 0x0c
+equal 0x0c shift
+kana_HO 0x0c altgr
+asciicircum 0x0d
+asciitilde 0x0d shift
+kana_HE 0x0d altgr
+kana_TA 0x10 altgr
+kana_TE 0x11 altgr
+kana_I 0x12 altgr
+kana_i 0x12 shift altgr
+kana_SU 0x13 altgr
+kana_KA 0x14 altgr
+kana_N 0x15 altgr
+kana_NA 0x16 altgr
+kana_NI 0x17 altgr
+kana_RA 0x18 altgr
+kana_SE 0x19 altgr
+at 0x1a
+grave 0x1a shift
+voicedsound 0x1a altgr
+bracketleft 0x1b
+braceleft 0x1b shift
+semivoicedsound 0x1b altgr
+kana_openingbracket 0x1b shift altgr
+kana_CHI 0x1e altgr
+kana_TO 0x1f altgr
+kana_SHI 0x20 altgr
+kana_HA 0x21 altgr
+kana_KI 0x22 altgr
+kana_KU 0x23 altgr
+kana_MA 0x24 altgr
+kana_NO 0x25 altgr
+kana_RI 0x26 altgr
+semicolon 0x27
+plus 0x27 shift
+kana_RE 0x27 altgr
+colon 0x28
+asterisk 0x28 shift
+kana_KE 0x28 altgr
+Zenkaku_Hankaku 0x29
+bracketright 0x2b
+braceright 0x2b shift
+kana_MU 0x2b altgr
+kana_closingbracket 0x2b shift altgr
+kana_TSU 0x2c altgr
+kana_tsu 0x2c shift altgr
+kana_SA 0x2d altgr
+kana_SO 0x2e altgr
+kana_HI 0x2f altgr
+kana_KO 0x30 altgr
+kana_MI 0x31 altgr
+kana_MO 0x32 altgr
+comma 0x33
+less 0x33 shift
+kana_NE 0x33 altgr
+kana_comma 0x33 shift altgr
+period 0x34
+greater 0x34 shift
+kana_RU 0x34 altgr
+kana_fullstop 0x34 shift altgr
+slash 0x35
+question 0x35 shift
+kana_ME 0x35 altgr
+kana_conjunctive 0x35 shift altgr
+Eisu_toggle 0x3a shift
+Execute 0x54 shift
+Kanji 0x70
+backslash 0x73
+bar 0x7d shift
+underscore 0x73 shift
+Henkan_Mode 0x79
+Katakana 0x70
+Muhenkan 0x7b
diff --git a/tools/ioemu/keymaps/lt b/tools/ioemu/keymaps/lt
new file mode 100644 (file)
index 0000000..3d9d619
--- /dev/null
@@ -0,0 +1,57 @@
+# generated from XKB map lt
+include common
+map 0x427
+exclam 0x02 shift
+aogonek 0x02 altgr
+Aogonek 0x02 shift altgr
+at 0x03 shift
+ccaron 0x03 altgr
+Ccaron 0x03 shift altgr
+numbersign 0x04 shift
+eogonek 0x04 altgr
+Eogonek 0x04 shift altgr
+dollar 0x05 shift
+eabovedot 0x05 altgr
+Eabovedot 0x05 shift altgr
+percent 0x06 shift
+iogonek 0x06 altgr
+Iogonek 0x06 shift altgr
+asciicircum 0x07 shift
+scaron 0x07 altgr
+Scaron 0x07 shift altgr
+ampersand 0x08 shift
+uogonek 0x08 altgr
+Uogonek 0x08 shift altgr
+asterisk 0x09 shift
+umacron 0x09 altgr
+Umacron 0x09 shift altgr
+parenleft 0x0a shift
+doublelowquotemark 0x0a altgr
+parenright 0x0b shift
+leftdoublequotemark 0x0b altgr
+minus 0x0c
+underscore 0x0c shift
+equal 0x0d
+plus 0x0d shift
+zcaron 0x0d altgr
+Zcaron 0x0d shift altgr
+bracketleft 0x1a
+braceleft 0x1a shift
+bracketright 0x1b
+braceright 0x1b shift
+semicolon 0x27
+colon 0x27 shift
+apostrophe 0x28
+quotedbl 0x28 shift
+grave 0x29
+asciitilde 0x29 shift
+backslash 0x2b
+bar 0x2b shift
+comma 0x33
+less 0x33 shift
+period 0x34
+greater 0x34 shift
+slash 0x35
+question 0x35 shift
+endash 0x56
+EuroSign 0x56 shift
diff --git a/tools/ioemu/keymaps/lv b/tools/ioemu/keymaps/lv
new file mode 100644 (file)
index 0000000..1d91727
--- /dev/null
@@ -0,0 +1,128 @@
+# generated from XKB map lv
+include common
+map 0x426
+exclam 0x02 shift
+onesuperior 0x02 altgr
+exclamdown 0x02 shift altgr
+at 0x03 shift
+twosuperior 0x03 altgr
+oneeighth 0x03 shift altgr
+numbersign 0x04 shift
+threesuperior 0x04 altgr
+sterling 0x04 shift altgr
+dollar 0x05 shift
+EuroSign 0x05 altgr
+cent 0x05 shift altgr
+percent 0x06 shift
+onehalf 0x06 altgr
+threeeighths 0x06 shift altgr
+asciicircum 0x07 shift
+threequarters 0x07 altgr
+fiveeighths 0x07 shift altgr
+ampersand 0x08 shift
+braceleft 0x08 altgr
+seveneighths 0x08 shift altgr
+asterisk 0x09 shift
+bracketleft 0x09 altgr
+trademark 0x09 shift altgr
+parenleft 0x0a shift
+bracketright 0x0a altgr
+plusminus 0x0a shift altgr
+parenright 0x0b shift
+braceright 0x0b altgr
+degree 0x0b shift altgr
+minus 0x0c
+underscore 0x0c shift
+backslash 0x0c altgr
+questiondown 0x0c shift altgr
+equal 0x0d
+plus 0x0d shift
+dead_cedilla 0x0d altgr
+dead_ogonek 0x0d shift altgr
+at 0x10 altgr
+Greek_OMEGA 0x10 shift altgr
+lstroke 0x11 altgr
+Lstroke 0x11 shift altgr
+emacron 0x12 altgr
+Emacron 0x12 shift altgr
+rcedilla 0x13 altgr
+Rcedilla 0x13 shift altgr
+tslash 0x14 altgr
+Tslash 0x14 shift altgr
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+umacron 0x16 altgr
+Umacron 0x16 shift altgr
+imacron 0x17 altgr
+Imacron 0x17 shift altgr
+omacron 0x18 altgr
+Omacron 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+bracketleft 0x1a
+braceleft 0x1a shift
+dead_diaeresis 0x1a altgr
+dead_abovering 0x1a shift altgr
+bracketright 0x1b
+braceright 0x1b shift
+dead_tilde 0x1b altgr
+dead_macron 0x1b shift altgr
+ISO_Next_Group 0x1c shift
+amacron 0x1e altgr
+Amacron 0x1e shift altgr
+scaron 0x1f altgr
+Scaron 0x1f shift altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+dstroke 0x21 altgr
+ordfeminine 0x21 shift altgr
+gcedilla 0x22 altgr
+Gcedilla 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+kcedilla 0x25 altgr
+Kcedilla 0x25 shift altgr
+lcedilla 0x26 altgr
+Lcedilla 0x26 shift altgr
+semicolon 0x27
+colon 0x27 shift
+dead_acute 0x27 altgr
+dead_doubleacute 0x27 shift altgr
+apostrophe 0x28
+quotedbl 0x28 shift
+leftdoublequotemark 0x28 altgr
+doublelowquotemark 0x28 shift altgr
+grave 0x29
+asciitilde 0x29 shift
+notsign 0x29 altgr
+backslash 0x2b
+bar 0x2b shift
+dead_grave 0x2b altgr
+dead_breve 0x2b shift altgr
+zcaron 0x2c altgr
+Zcaron 0x2c shift altgr
+guillemotright 0x2d altgr
+greater 0x2d shift altgr
+ccaron 0x2e altgr
+Ccaron 0x2e shift altgr
+leftdoublequotemark 0x2f altgr
+grave 0x2f shift altgr
+rightdoublequotemark 0x30 altgr
+apostrophe 0x30 shift altgr
+ncedilla 0x31 altgr
+Ncedilla 0x31 shift altgr
+mu 0x32 altgr
+masculine 0x32 shift altgr
+comma 0x33
+less 0x33 shift
+horizconnector 0x33 altgr
+multiply 0x33 shift altgr
+period 0x34
+greater 0x34 shift
+periodcentered 0x34 altgr
+division 0x34 shift altgr
+slash 0x35
+question 0x35 shift
+dead_belowdot 0x35 altgr
+dead_abovedot 0x35 shift altgr
+nobreakspace 0x39 altgr
diff --git a/tools/ioemu/keymaps/mk b/tools/ioemu/keymaps/mk
new file mode 100644 (file)
index 0000000..18c1504
--- /dev/null
@@ -0,0 +1,101 @@
+# generated from XKB map mk
+include common
+map 0x42f
+exclam 0x02 shift
+at 0x03 shift
+doublelowquotemark 0x03 shift altgr
+numbersign 0x04 shift
+leftdoublequotemark 0x04 shift altgr
+dollar 0x05 shift
+percent 0x06 shift
+asciicircum 0x07 shift
+ampersand 0x08 shift
+asterisk 0x09 shift
+parenleft 0x0a shift
+parenright 0x0b shift
+minus 0x0c
+underscore 0x0c shift
+equal 0x0d
+plus 0x0d shift
+Cyrillic_lje 0x10 altgr
+Cyrillic_LJE 0x10 shift altgr
+Cyrillic_nje 0x11 altgr
+Cyrillic_NJE 0x11 shift altgr
+Cyrillic_ie 0x12 altgr
+Cyrillic_IE 0x12 shift altgr
+Cyrillic_er 0x13 altgr
+Cyrillic_ER 0x13 shift altgr
+Cyrillic_te 0x14 altgr
+Cyrillic_TE 0x14 shift altgr
+Macedonia_dse 0x15 altgr
+Macedonia_DSE 0x15 shift altgr
+Cyrillic_u 0x16 altgr
+Cyrillic_U 0x16 shift altgr
+Cyrillic_i 0x17 altgr
+Cyrillic_I 0x17 shift altgr
+Cyrillic_o 0x18 altgr
+Cyrillic_O 0x18 shift altgr
+Cyrillic_pe 0x19 altgr
+Cyrillic_PE 0x19 shift altgr
+bracketleft 0x1a
+braceleft 0x1a shift
+Cyrillic_sha 0x1a altgr
+Cyrillic_SHA 0x1a shift altgr
+bracketright 0x1b
+braceright 0x1b shift
+Macedonia_gje 0x1b altgr
+Macedonia_GJE 0x1b shift altgr
+Cyrillic_a 0x1e altgr
+Cyrillic_A 0x1e shift altgr
+Cyrillic_es 0x1f altgr
+Cyrillic_ES 0x1f shift altgr
+Cyrillic_de 0x20 altgr
+Cyrillic_DE 0x20 shift altgr
+Cyrillic_ef 0x21 altgr
+Cyrillic_EF 0x21 shift altgr
+Cyrillic_ghe 0x22 altgr
+Cyrillic_GHE 0x22 shift altgr
+Cyrillic_ha 0x23 altgr
+Cyrillic_HA 0x23 shift altgr
+Cyrillic_je 0x24 altgr
+Cyrillic_JE 0x24 shift altgr
+Cyrillic_ka 0x25 altgr
+Cyrillic_KA 0x25 shift altgr
+Cyrillic_el 0x26 altgr
+Cyrillic_EL 0x26 shift altgr
+semicolon 0x27
+colon 0x27 shift
+Cyrillic_che 0x27 altgr
+Cyrillic_CHE 0x27 shift altgr
+apostrophe 0x28
+quotedbl 0x28 shift
+Macedonia_kje 0x28 altgr
+Macedonia_KJE 0x28 shift altgr
+grave 0x29
+asciitilde 0x29 shift
+backslash 0x2b
+bar 0x2b shift
+Cyrillic_zhe 0x2b altgr
+Cyrillic_ZHE 0x2b shift altgr
+Cyrillic_ze 0x2c altgr
+Cyrillic_ZE 0x2c shift altgr
+Cyrillic_dzhe 0x2d altgr
+Cyrillic_DZHE 0x2d shift altgr
+Cyrillic_tse 0x2e altgr
+Cyrillic_TSE 0x2e shift altgr
+Cyrillic_ve 0x2f altgr
+Cyrillic_VE 0x2f shift altgr
+Cyrillic_be 0x30 altgr
+Cyrillic_BE 0x30 shift altgr
+Cyrillic_en 0x31 altgr
+Cyrillic_EN 0x31 shift altgr
+Cyrillic_em 0x32 altgr
+Cyrillic_EM 0x32 shift altgr
+comma 0x33
+less 0x33 shift
+semicolon 0x33 shift altgr
+period 0x34
+greater 0x34 shift
+colon 0x34 shift altgr
+slash 0x35
+question 0x35 shift
diff --git a/tools/ioemu/keymaps/modifiers b/tools/ioemu/keymaps/modifiers
new file mode 100644 (file)
index 0000000..d8b019f
--- /dev/null
@@ -0,0 +1,17 @@
+Shift_R 0x36
+Shift_L 0x2a
+
+Alt_R 0xb8
+Mode_switch 0xb8
+Alt_L 0x38
+
+Control_R 0x9d
+Control_L 0x1d
+
+# Translate Super to Windows keys. 
+# This is hardcoded. See documentation for details. 
+Super_R 0xdb
+Super_L 0xdc
+
+# Translate Menu to the Windows Application key. 
+Menu 0xdd
diff --git a/tools/ioemu/keymaps/nl b/tools/ioemu/keymaps/nl
new file mode 100644 (file)
index 0000000..bc823bd
--- /dev/null
@@ -0,0 +1,60 @@
+# Dutch (Netherlands)
+include common
+map 0x413
+
+exclam 0x02 shift
+onesuperior 0x02 altgr
+quotebl 0x03 shift
+twosuperior 0x03 altgr
+numbersign 0x04 shift
+threesuperior 0x04 altgr
+dollar 0x05 shift
+onequarter 0x05 altgr
+percent 0x06 shift
+onehalf 0x06 altgr
+ampersand 0x07 shift
+threequarters 0x07 altgr
+underscore 0x08 shift
+sterling 0x08 altgr
+parenleft 0x09 shift
+braceleft 0x09 altgr
+parenright 0x0a shift
+braceright 0x0a altgr
+apostrophe 0x0b shift
+slash 0x0c
+question 0x0c shift
+backslash 0x0c altgr
+degree 0x0d
+dead_tilde 0x0d shift
+dead_cedilla 0x0d altgr
+EuroSign 0x12 altgr
+paragraph 0x13 altgr
+dead_diaeresis 0x1a
+dead_circumflex 0x1a shift
+asterisk 0x1b
+bar 0x1b shift
+ssharp 0x1f altgr
+plus 0x27
+plusminus 0x27 shift
+dead_acute 0x28
+dead_grave 0x28 shift
+at 0x29
+section 0x29 shift
+notsign 0x29 altgr
+less 0x2b
+greater 0x2b shift
+guillemotleft 0x2c altgr
+guillemotright 0x2d altgr
+copyright 0x2e altgr 
+mu 0x32 altgr
+comma 0x33
+semicolon 0x33 shift
+period 0x34
+colon 0x34 shift
+periodcentered 0x34 altgr
+hyphen 0x35
+equal 0x35 shift
+bracketright 0x56
+bracketleft 0x56 shift
+brokenbar 0x56 altgr
+
diff --git a/tools/ioemu/keymaps/nl-be b/tools/ioemu/keymaps/nl-be
new file mode 100644 (file)
index 0000000..34fc881
--- /dev/null
@@ -0,0 +1,3 @@
+# Dutch (Belgium)
+map 0x813
+include common
diff --git a/tools/ioemu/keymaps/no b/tools/ioemu/keymaps/no
new file mode 100644 (file)
index 0000000..40a6479
--- /dev/null
@@ -0,0 +1,119 @@
+# generated from XKB map no
+include common
+map 0x414
+exclam 0x02 shift
+exclamdown 0x02 altgr
+onesuperior 0x02 shift altgr
+quotedbl 0x03 shift
+at 0x03 altgr
+twosuperior 0x03 shift altgr
+numbersign 0x04 shift
+sterling 0x04 altgr
+threesuperior 0x04 shift altgr
+currency 0x05 shift
+dollar 0x05 altgr
+onequarter 0x05 shift altgr
+percent 0x06 shift
+onehalf 0x06 altgr
+cent 0x06 shift altgr
+ampersand 0x07 shift
+yen 0x07 altgr
+fiveeighths 0x07 shift altgr
+slash 0x08 shift
+braceleft 0x08 altgr
+division 0x08 shift altgr
+parenleft 0x09 shift
+bracketleft 0x09 altgr
+guillemotleft 0x09 shift altgr
+parenright 0x0a shift
+bracketright 0x0a altgr
+guillemotright 0x0a shift altgr
+equal 0x0b shift
+braceright 0x0b altgr
+degree 0x0b shift altgr
+plus 0x0c
+question 0x0c shift
+plusminus 0x0c altgr
+questiondown 0x0c shift altgr
+backslash 0x0d
+dead_grave 0x0d shift
+dead_acute 0x0d altgr
+notsign 0x0d shift altgr
+Greek_OMEGA 0x10 shift altgr
+lstroke 0x11 altgr
+Lstroke 0x11 shift altgr
+EuroSign 0x12 altgr
+cent 0x12 shift altgr
+registered 0x13 altgr
+thorn 0x14 altgr
+THORN 0x14 shift altgr
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oe 0x18 altgr
+OE 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+aring 0x1a
+Aring 0x1a shift
+dead_diaeresis 0x1a altgr
+dead_abovering 0x1a shift altgr
+dead_diaeresis 0x1b
+dead_circumflex 0x1b shift
+asciicircum 0x01b shift
+dead_tilde 0x1b altgr
+asciitilde 0x1b altgr
+dead_caron 0x1b shift altgr
+ordfeminine 0x1e altgr
+masculine 0x1e shift altgr
+ssharp 0x1f altgr
+section 0x1f shift altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+dstroke 0x21 altgr
+ordfeminine 0x21 shift altgr
+eng 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+kra 0x25 altgr
+lstroke 0x26 altgr
+Lstroke 0x26 shift altgr
+oslash 0x27
+Ooblique 0x27 shift
+dead_doubleacute 0x27 shift altgr
+ae 0x28
+AE 0x28 shift
+dead_caron 0x28 shift altgr
+bar 0x29
+section 0x29 shift
+brokenbar 0x29 altgr
+paragraph 0x29 shift altgr
+apostrophe 0x2b
+asterisk 0x2b shift
+multiply 0x2b shift altgr
+guillemotleft 0x2c altgr
+guillemotright 0x2d altgr
+copyright 0x2e altgr
+leftdoublequotemark 0x2f altgr
+rightdoublequotemark 0x30 altgr
+mu 0x32 altgr
+masculine 0x32 shift altgr
+comma 0x33
+semicolon 0x33 shift
+dead_cedilla 0x33 altgr
+dead_ogonek 0x33 shift altgr
+period 0x34
+colon 0x34 shift
+periodcentered 0x34 altgr
+dead_abovedot 0x34 shift altgr
+minus 0x35
+underscore 0x35 shift
+hyphen 0x35 altgr
+macron 0x35 shift altgr
+nobreakspace 0x39 altgr
+onehalf 0x56 altgr
+threequarters 0x56 shift altgr
diff --git a/tools/ioemu/keymaps/pl b/tools/ioemu/keymaps/pl
new file mode 100644 (file)
index 0000000..09c600d
--- /dev/null
@@ -0,0 +1,122 @@
+# generated from XKB map pl
+include common
+map 0x415
+exclam 0x02 shift
+onesuperior 0x02 altgr
+exclamdown 0x02 shift altgr
+at 0x03 shift
+twosuperior 0x03 altgr
+oneeighth 0x03 shift altgr
+numbersign 0x04 shift
+threesuperior 0x04 altgr
+sterling 0x04 shift altgr
+dollar 0x05 shift
+onequarter 0x05 altgr
+percent 0x06 shift
+onehalf 0x06 altgr
+threeeighths 0x06 shift altgr
+asciicircum 0x07 shift
+threequarters 0x07 altgr
+fiveeighths 0x07 shift altgr
+ampersand 0x08 shift
+braceleft 0x08 altgr
+seveneighths 0x08 shift altgr
+asterisk 0x09 shift
+bracketleft 0x09 altgr
+trademark 0x09 shift altgr
+parenleft 0x0a shift
+bracketright 0x0a altgr
+plusminus 0x0a shift altgr
+parenright 0x0b shift
+braceright 0x0b altgr
+degree 0x0b shift altgr
+minus 0x0c
+underscore 0x0c shift
+backslash 0x0c altgr
+questiondown 0x0c shift altgr
+equal 0x0d
+plus 0x0d shift
+dead_cedilla 0x0d altgr
+dead_ogonek 0x0d shift altgr
+Greek_OMEGA 0x10 shift altgr
+lstroke 0x11 altgr
+Lstroke 0x11 shift altgr
+eogonek 0x12 altgr
+Eogonek 0x12 shift altgr
+paragraph 0x13 altgr
+registered 0x13 shift altgr
+tslash 0x14 altgr
+Tslash 0x14 shift altgr
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+EuroSign 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oacute 0x18 altgr
+Oacute 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+bracketleft 0x1a
+braceleft 0x1a shift
+dead_diaeresis 0x1a altgr
+dead_abovering 0x1a shift altgr
+bracketright 0x1b
+braceright 0x1b shift
+dead_tilde 0x1b altgr
+dead_macron 0x1b shift altgr
+aogonek 0x1e altgr
+Aogonek 0x1e shift altgr
+sacute 0x1f altgr
+Sacute 0x1f shift altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+dstroke 0x21 altgr
+ordfeminine 0x21 shift altgr
+eng 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+kra 0x25 altgr
+lstroke 0x26 altgr
+Lstroke 0x26 shift altgr
+semicolon 0x27
+colon 0x27 shift
+dead_acute 0x27 altgr
+dead_doubleacute 0x27 shift altgr
+apostrophe 0x28
+quotedbl 0x28 shift
+dead_circumflex 0x28 altgr
+dead_caron 0x28 shift altgr
+grave 0x29
+asciitilde 0x29 shift
+notsign 0x29 altgr
+backslash 0x2b
+bar 0x2b shift
+dead_grave 0x2b altgr
+dead_breve 0x2b shift altgr
+zabovedot 0x2c altgr
+Zabovedot 0x2c shift altgr
+zacute 0x2d altgr
+Zacute 0x2d shift altgr
+cacute 0x2e altgr
+Cacute 0x2e shift altgr
+leftdoublequotemark 0x2f altgr
+grave 0x2f shift altgr
+rightdoublequotemark 0x30 altgr
+nacute 0x31 altgr
+Nacute 0x31 shift altgr
+mu 0x32 altgr
+masculine 0x32 shift altgr
+comma 0x33
+less 0x33 shift
+horizconnector 0x33 altgr
+multiply 0x33 shift altgr
+period 0x34
+greater 0x34 shift
+periodcentered 0x34 altgr
+division 0x34 shift altgr
+slash 0x35
+question 0x35 shift
+dead_belowdot 0x35 altgr
+dead_abovedot 0x35 shift altgr
diff --git a/tools/ioemu/keymaps/pt b/tools/ioemu/keymaps/pt
new file mode 100644 (file)
index 0000000..c6941f6
--- /dev/null
@@ -0,0 +1,113 @@
+# generated from XKB map pt
+include common
+map 0x816
+exclam 0x02 shift
+onesuperior 0x02 altgr
+exclamdown 0x02 shift altgr
+quotedbl 0x03 shift
+at 0x03 altgr
+oneeighth 0x03 shift altgr
+numbersign 0x04 shift
+sterling 0x04 altgr
+dollar 0x05 shift
+section 0x05 altgr
+percent 0x06 shift
+onehalf 0x06 altgr
+threeeighths 0x06 shift altgr
+ampersand 0x07 shift
+threequarters 0x07 altgr
+fiveeighths 0x07 shift altgr
+slash 0x08 shift
+braceleft 0x08 altgr
+seveneighths 0x08 shift altgr
+parenleft 0x09 shift
+bracketleft 0x09 altgr
+trademark 0x09 shift altgr
+parenright 0x0a shift
+bracketright 0x0a altgr
+plusminus 0x0a shift altgr
+equal 0x0b shift
+braceright 0x0b altgr
+degree 0x0b shift altgr
+apostrophe 0x0c
+question 0x0c shift
+backslash 0x0c altgr
+questiondown 0x0c shift altgr
+guillemotleft 0x0d
+guillemotright 0x0d shift
+dead_cedilla 0x0d altgr
+dead_ogonek 0x0d shift altgr
+Greek_OMEGA 0x10 shift altgr
+lstroke 0x11 altgr
+Lstroke 0x11 shift altgr
+EuroSign 0x12 altgr
+cent 0x12 shift altgr
+paragraph 0x13 altgr
+registered 0x13 shift altgr
+tslash 0x14 altgr
+Tslash 0x14 shift altgr
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oslash 0x18 altgr
+Ooblique 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+plus 0x1a
+asterisk 0x1a shift
+dead_diaeresis 0x1a altgr
+dead_abovering 0x1a shift altgr
+dead_acute 0x1b
+dead_grave 0x1b shift
+dead_tilde 0x1b altgr
+dead_macron 0x1b shift altgr
+ae 0x1e altgr
+AE 0x1e shift altgr
+ssharp 0x1f altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+dstroke 0x21 altgr
+ordfeminine 0x21 shift altgr
+eng 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+kra 0x25 altgr
+lstroke 0x26 altgr
+Lstroke 0x26 shift altgr
+ccedilla 0x27
+Ccedilla 0x27 shift
+dead_doubleacute 0x27 shift altgr
+masculine 0x28
+ordfeminine 0x28 shift
+dead_circumflex 0x28 altgr
+dead_caron 0x28 shift altgr
+backslash 0x29
+bar 0x29 shift
+notsign 0x29 altgr
+dead_tilde 0x2b
+dead_circumflex 0x2b shift
+dead_breve 0x2b shift altgr
+less 0x56
+greater 0x56 shift
+cent 0x2e altgr
+copyright 0x2e shift altgr
+leftdoublequotemark 0x2f altgr
+grave 0x2f shift altgr
+rightdoublequotemark 0x30 altgr
+mu 0x32 altgr
+comma 0x33
+semicolon 0x33 shift
+horizconnector 0x33 altgr
+multiply 0x33 shift altgr
+period 0x34
+colon 0x34 shift
+periodcentered 0x34 altgr
+division 0x34 shift altgr
+minus 0x35
+underscore 0x35 shift
+dead_belowdot 0x35 altgr
+dead_abovedot 0x35 shift altgr
diff --git a/tools/ioemu/keymaps/pt-br b/tools/ioemu/keymaps/pt-br
new file mode 100644 (file)
index 0000000..54bafc5
--- /dev/null
@@ -0,0 +1,69 @@
+# generated from XKB map br
+include common
+map 0x416
+exclam 0x02 shift
+onesuperior 0x02 altgr
+exclamdown 0x02 shift altgr
+at 0x03 shift
+twosuperior 0x03 altgr
+onehalf 0x03 shift altgr
+numbersign 0x04 shift
+threesuperior 0x04 altgr
+threequarters 0x04 shift altgr
+dollar 0x05 shift
+sterling 0x05 altgr
+onequarter 0x05 shift altgr
+percent 0x06 shift
+cent 0x06 altgr
+dead_diaeresis 0x07 shift
+notsign 0x07 altgr
+diaeresis 0x07 shift altgr
+ampersand 0x08 shift
+braceleft 0x08 altgr
+asterisk 0x09 shift
+bracketleft 0x09 altgr
+parenleft 0x0a shift
+bracketright 0x0a altgr
+parenright 0x0b shift
+braceright 0x0b altgr
+minus 0x0c
+underscore 0x0c shift
+backslash 0x0c altgr
+equal 0x0d
+plus 0x0d shift
+section 0x0d altgr
+EuroSign 0x12 altgr
+registered 0x13 altgr
+dead_acute 0x1a
+dead_grave 0x1a shift
+acute 0x1a altgr
+grave 0x1a shift altgr
+bracketleft 0x1b
+braceleft 0x1b shift
+ordfeminine 0x1b altgr
+ccedilla 0x27
+Ccedilla 0x27 shift
+dead_tilde 0x28
+dead_circumflex 0x28 shift
+asciitilde 0x28 altgr
+asciicircum 0x28 shift altgr
+apostrophe 0x29
+quotedbl 0x29 shift
+bracketright 0x2b
+braceright 0x2b shift
+masculine 0x2b altgr
+copyright 0x2e altgr
+mu 0x32 altgr
+comma 0x33
+less 0x33 shift
+period 0x34
+greater 0x34 shift
+semicolon 0x35
+colon 0x35 shift
+comma 0x53 numlock
+backslash 0x56
+bar 0x56 shift
+slash 0x73
+question 0x73 shift
+degree 0x73 altgr
+KP_Decimal 0x34
diff --git a/tools/ioemu/keymaps/ru b/tools/ioemu/keymaps/ru
new file mode 100644 (file)
index 0000000..b3e7d24
--- /dev/null
@@ -0,0 +1,109 @@
+# generated from XKB map ru
+include common
+map 0x419
+exclam 0x02 shift
+at 0x03 shift
+quotedbl 0x03 shift altgr
+numbersign 0x04 shift
+dollar 0x05 shift
+asterisk 0x05 shift altgr
+percent 0x06 shift
+colon 0x06 shift altgr
+asciicircum 0x07 shift
+comma 0x07 shift altgr
+ampersand 0x08 shift
+period 0x08 shift altgr
+asterisk 0x09 shift
+semicolon 0x09 shift altgr
+parenleft 0x0a shift
+parenright 0x0b shift
+minus 0x0c
+underscore 0x0c shift
+equal 0x0d
+plus 0x0d shift
+Cyrillic_shorti 0x10 altgr
+Cyrillic_SHORTI 0x10 shift altgr
+Cyrillic_tse 0x11 altgr
+Cyrillic_TSE 0x11 shift altgr
+Cyrillic_u 0x12 altgr
+Cyrillic_U 0x12 shift altgr
+Cyrillic_ka 0x13 altgr
+Cyrillic_KA 0x13 shift altgr
+Cyrillic_ie 0x14 altgr
+Cyrillic_IE 0x14 shift altgr
+Cyrillic_en 0x15 altgr
+Cyrillic_EN 0x15 shift altgr
+Cyrillic_ghe 0x16 altgr
+Cyrillic_GHE 0x16 shift altgr
+Cyrillic_sha 0x17 altgr
+Cyrillic_SHA 0x17 shift altgr
+Cyrillic_shcha 0x18 altgr
+Cyrillic_SHCHA 0x18 shift altgr
+Cyrillic_ze 0x19 altgr
+Cyrillic_ZE 0x19 shift altgr
+bracketleft 0x1a
+braceleft 0x1a shift
+Cyrillic_ha 0x1a altgr
+Cyrillic_HA 0x1a shift altgr
+bracketright 0x1b
+braceright 0x1b shift
+Cyrillic_hardsign 0x1b altgr
+Cyrillic_HARDSIGN 0x1b shift altgr
+Cyrillic_ef 0x1e altgr
+Cyrillic_EF 0x1e shift altgr
+Cyrillic_yeru 0x1f altgr
+Cyrillic_YERU 0x1f shift altgr
+Cyrillic_ve 0x20 altgr
+Cyrillic_VE 0x20 shift altgr
+Cyrillic_a 0x21 altgr
+Cyrillic_A 0x21 shift altgr
+Cyrillic_pe 0x22 altgr
+Cyrillic_PE 0x22 shift altgr
+Cyrillic_er 0x23 altgr
+Cyrillic_ER 0x23 shift altgr
+Cyrillic_o 0x24 altgr
+Cyrillic_O 0x24 shift altgr
+Cyrillic_el 0x25 altgr
+Cyrillic_EL 0x25 shift altgr
+Cyrillic_de 0x26 altgr
+Cyrillic_DE 0x26 shift altgr
+semicolon 0x27
+colon 0x27 shift
+Cyrillic_zhe 0x27 altgr
+Cyrillic_ZHE 0x27 shift altgr
+apostrophe 0x28
+quotedbl 0x28 shift
+Cyrillic_e 0x28 altgr
+Cyrillic_E 0x28 shift altgr
+grave 0x29
+asciitilde 0x29 shift
+Cyrillic_io 0x29 altgr
+Cyrillic_IO 0x29 shift altgr
+backslash 0x2b
+bar 0x2b shift
+Cyrillic_ya 0x2c altgr
+Cyrillic_YA 0x2c shift altgr
+Cyrillic_che 0x2d altgr
+Cyrillic_CHE 0x2d shift altgr
+Cyrillic_es 0x2e altgr
+Cyrillic_ES 0x2e shift altgr
+Cyrillic_em 0x2f altgr
+Cyrillic_EM 0x2f shift altgr
+Cyrillic_i 0x30 altgr
+Cyrillic_I 0x30 shift altgr
+Cyrillic_te 0x31 altgr
+Cyrillic_TE 0x31 shift altgr
+Cyrillic_softsign 0x32 altgr
+Cyrillic_SOFTSIGN 0x32 shift altgr
+comma 0x33
+less 0x33 shift
+Cyrillic_be 0x33 altgr
+Cyrillic_BE 0x33 shift altgr
+period 0x34
+greater 0x34 shift
+Cyrillic_yu 0x34 altgr
+Cyrillic_YU 0x34 shift altgr
+slash 0x35
+question 0x35 shift
+slash 0x56 altgr
+bar 0x56 shift altgr
diff --git a/tools/ioemu/keymaps/sl b/tools/ioemu/keymaps/sl
new file mode 100644 (file)
index 0000000..56835a9
--- /dev/null
@@ -0,0 +1,110 @@
+# generated from XKB map sl
+include common
+map 0x424
+exclam 0x02 shift
+asciitilde 0x02 altgr
+dead_tilde 0x02 shift altgr
+quotedbl 0x03 shift
+dead_caron 0x03 altgr
+caron 0x03 shift altgr
+numbersign 0x04 shift
+asciicircum 0x04 altgr
+dead_circumflex 0x04 shift altgr
+dollar 0x05 shift
+dead_breve 0x05 altgr
+breve 0x05 shift altgr
+percent 0x06 shift
+degree 0x06 altgr
+dead_abovering 0x06 shift altgr
+ampersand 0x07 shift
+dead_ogonek 0x07 altgr
+ogonek 0x07 shift altgr
+slash 0x08 shift
+grave 0x08 altgr
+dead_grave 0x08 shift altgr
+parenleft 0x09 shift
+dead_abovedot 0x09 altgr
+abovedot 0x09 shift altgr
+parenright 0x0a shift
+dead_acute 0x0a altgr
+equal 0x0b shift
+dead_doubleacute 0x0b altgr
+doubleacute 0x0b shift altgr
+apostrophe 0x0c
+question 0x0c shift
+dead_diaeresis 0x0c altgr
+diaeresis 0x0c shift altgr
+plus 0x0d
+asterisk 0x0d shift
+dead_cedilla 0x0d altgr
+cedilla 0x0d shift altgr
+backslash 0x10 altgr
+Greek_OMEGA 0x10 shift altgr
+bar 0x11 altgr
+Lstroke 0x11 shift altgr
+EuroSign 0x12 altgr
+paragraph 0x13 altgr
+registered 0x13 shift altgr
+tslash 0x14 altgr
+Tslash 0x14 shift altgr
+z 0x15 addupper
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+rightarrow 0x17 altgr
+idotless 0x17 shift altgr
+oslash 0x18 altgr
+Ooblique 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+scaron 0x1a
+Scaron 0x1a shift
+division 0x1a altgr
+dstroke 0x1b
+Dstroke 0x1b shift
+multiply 0x1b altgr
+dead_macron 0x1b shift altgr
+ae 0x1e altgr
+AE 0x1e shift altgr
+ssharp 0x1f altgr
+section 0x1f shift altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+bracketleft 0x21 altgr
+ordfeminine 0x21 shift altgr
+bracketright 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+lstroke 0x25 altgr
+Lstroke 0x26 altgr
+ccaron 0x27
+Ccaron 0x27 shift
+cacute 0x28
+Cacute 0x28 shift
+ssharp 0x28 altgr
+dead_cedilla 0x29
+notsign 0x29 altgr
+zcaron 0x2b
+Zcaron 0x2b shift
+currency 0x2b altgr
+y 0x2c addupper
+guillemotleft 0x2c altgr
+guillemotright 0x2d altgr
+cent 0x2e altgr
+copyright 0x2e shift altgr
+at 0x2f altgr
+braceleft 0x30 altgr
+braceright 0x31 altgr
+section 0x32 altgr
+masculine 0x32 shift altgr
+comma 0x33
+semicolon 0x33 shift
+horizconnector 0x33 altgr
+period 0x34
+colon 0x34 shift
+periodcentered 0x34 altgr
+minus 0x35
+underscore 0x35 shift
+dead_belowdot 0x35 altgr
diff --git a/tools/ioemu/keymaps/sv b/tools/ioemu/keymaps/sv
new file mode 100644 (file)
index 0000000..736d637
--- /dev/null
@@ -0,0 +1,82 @@
+map 0x0000041d
+include common
+
+#
+# Top row
+#
+section 0x29
+onehalf 0x29 shift
+
+# 1
+exclam 0x2 shift
+
+# 2
+quotedbl 0x3 shift
+at 0x3 altgr
+
+# 3
+numbersign 0x4 shift
+sterling 0x4 altgr
+# 4
+currency 0x5 shift
+dollar 0x5 altgr
+# 5
+percent 0x6 shift
+# 6
+ampersand 0x7 shift
+# 7
+slash 0x8 shift
+braceleft 0x8 altgr
+# 8
+parenleft 0x9 shift
+bracketleft 0x9 altgr
+# 9
+parenright 0xa shift
+bracketright 0xa altgr
+# 0
+equal 0xb shift
+braceright 0xb altgr
+
+plus 0xc
+question 0xc shift
+backslash 0xc altgr
+
+acute 0xd
+dead_acute 0xd
+grave 0xd shift
+dead_grave 0xd shift
+
+#
+# QWERTY first row
+#
+EuroSign 0x12 altgr
+aring 0x1a 
+Aring 0x1a shift
+dead_diaeresis 0x1b 
+dead_circumflex 0x1b shift
+dead_tilde 0x1b altgr
+
+#
+# QWERTY second row
+#
+odiaeresis 0x27 
+Odiaeresis 0x27 shift
+adiaeresis 0x28 
+Adiaeresis 0x28 shift
+apostrophe 0x2b
+asterisk 0x2b shift
+
+#
+# QWERTY third row
+#
+less 0x56
+greater 0x56 shift
+bar 0x56 altgr
+mu 0x32 altgr
+comma 0x33
+semicolon 0x33 shift
+period 0x34
+colon 0x34 shift
+minus 0x35
+underscore 0x35 shift
+
diff --git a/tools/ioemu/keymaps/th b/tools/ioemu/keymaps/th
new file mode 100644 (file)
index 0000000..b65b6da
--- /dev/null
@@ -0,0 +1,131 @@
+# generated from XKB map th
+include common
+map 0x41e
+exclam 0x02 shift
+Thai_lakkhangyao 0x02 altgr
+plus 0x02 shift altgr
+at 0x03 shift
+slash 0x03 altgr
+Thai_leknung 0x03 shift altgr
+numbersign 0x04 shift
+minus 0x04 altgr
+Thai_leksong 0x04 shift altgr
+dollar 0x05 shift
+Thai_phosamphao 0x05 altgr
+Thai_leksam 0x05 shift altgr
+percent 0x06 shift
+Thai_thothung 0x06 altgr
+Thai_leksi 0x06 shift altgr
+asciicircum 0x07 shift
+Thai_sarau 0x07 altgr
+Thai_sarauu 0x07 shift altgr
+ampersand 0x08 shift
+Thai_saraue 0x08 altgr
+Thai_baht 0x08 shift altgr
+asterisk 0x09 shift
+Thai_khokhwai 0x09 altgr
+Thai_lekha 0x09 shift altgr
+parenleft 0x0a shift
+Thai_totao 0x0a altgr
+Thai_lekhok 0x0a shift altgr
+parenright 0x0b shift
+Thai_chochan 0x0b altgr
+Thai_lekchet 0x0b shift altgr
+minus 0x0c
+underscore 0x0c shift
+Thai_khokhai 0x0c altgr
+Thai_lekpaet 0x0c shift altgr
+equal 0x0d
+plus 0x0d shift
+Thai_chochang 0x0d altgr
+Thai_lekkao 0x0d shift altgr
+Thai_maiyamok 0x10 altgr
+Thai_leksun 0x10 shift altgr
+Thai_saraaimaimalai 0x11 altgr
+quotedbl 0x11 shift altgr
+Thai_saraam 0x12 altgr
+Thai_dochada 0x12 shift altgr
+Thai_phophan 0x13 altgr
+Thai_thonangmontho 0x13 shift altgr
+Thai_saraa 0x14 altgr
+Thai_thothong 0x14 shift altgr
+Thai_maihanakat 0x15 altgr
+Thai_nikhahit 0x15 shift altgr
+Thai_saraii 0x16 altgr
+Thai_maitri 0x16 shift altgr
+Thai_rorua 0x17 altgr
+Thai_nonen 0x17 shift altgr
+Thai_nonu 0x18 altgr
+Thai_paiyannoi 0x18 shift altgr
+Thai_yoyak 0x19 altgr
+Thai_yoying 0x19 shift altgr
+bracketleft 0x1a
+braceleft 0x1a shift
+Thai_bobaimai 0x1a altgr
+Thai_thothan 0x1a shift altgr
+bracketright 0x1b
+braceright 0x1b shift
+Thai_loling 0x1b altgr
+comma 0x1b shift altgr
+Thai_fofan 0x1e altgr
+Thai_ru 0x1e shift altgr
+Thai_hohip 0x1f altgr
+Thai_khorakhang 0x1f shift altgr
+Thai_kokai 0x20 altgr
+Thai_topatak 0x20 shift altgr
+Thai_dodek 0x21 altgr
+Thai_sarao 0x21 shift altgr
+Thai_sarae 0x22 altgr
+Thai_chochoe 0x22 shift altgr
+Thai_maitho 0x23 altgr
+Thai_maitaikhu 0x23 shift altgr
+Thai_maiek 0x24 altgr
+Thai_maichattawa 0x24 shift altgr
+Thai_saraaa 0x25 altgr
+Thai_sorusi 0x25 shift altgr
+Thai_sosua 0x26 altgr
+Thai_sosala 0x26 shift altgr
+semicolon 0x27
+colon 0x27 shift
+Thai_wowaen 0x27 altgr
+Thai_soso 0x27 shift altgr
+apostrophe 0x28
+quotedbl 0x28 shift
+Thai_ngongu 0x28 altgr
+period 0x28 shift altgr
+grave 0x29
+asciitilde 0x29 shift
+underscore 0x29 altgr
+percent 0x29 shift altgr
+ISO_First_Group 0x2a shift
+backslash 0x2b
+bar 0x2b shift
+Thai_khokhuat 0x2b altgr
+Thai_khokhon 0x2b shift altgr
+Thai_phophung 0x2c altgr
+parenleft 0x2c shift altgr
+Thai_popla 0x2d altgr
+parenright 0x2d shift altgr
+Thai_saraae 0x2e altgr
+Thai_choching 0x2e shift altgr
+Thai_oang 0x2f altgr
+Thai_honokhuk 0x2f shift altgr
+Thai_sarai 0x30 altgr
+Thai_phinthu 0x30 shift altgr
+Thai_sarauee 0x31 altgr
+Thai_thanthakhat 0x31 shift altgr
+Thai_thothahan 0x32 altgr
+question 0x32 shift altgr
+comma 0x33
+less 0x33 shift
+Thai_moma 0x33 altgr
+Thai_thophuthao 0x33 shift altgr
+period 0x34
+greater 0x34 shift
+Thai_saraaimaimuan 0x34 altgr
+Thai_lochula 0x34 shift altgr
+slash 0x35
+question 0x35 shift
+Thai_fofa 0x35 altgr
+Thai_lu 0x35 shift altgr
+ISO_Last_Group 0x36 shift
diff --git a/tools/ioemu/keymaps/tr b/tools/ioemu/keymaps/tr
new file mode 100644 (file)
index 0000000..5650e1e
--- /dev/null
@@ -0,0 +1,123 @@
+# generated from XKB map tr
+include common
+map 0x41f
+exclam 0x02 shift
+onesuperior 0x02 altgr
+exclamdown 0x02 shift altgr
+apostrophe 0x03 shift
+at 0x03 altgr
+oneeighth 0x03 shift altgr
+dead_circumflex 0x04 shift
+numbersign 0x04 altgr
+sterling 0x04 shift altgr
+plus 0x05 shift
+dollar 0x05 altgr
+percent 0x06 shift
+onehalf 0x06 altgr
+threeeighths 0x06 shift altgr
+ampersand 0x07 shift
+asciicircum 0x07 altgr
+fiveeighths 0x07 shift altgr
+slash 0x08 shift
+braceleft 0x08 altgr
+seveneighths 0x08 shift altgr
+parenleft 0x09 shift
+bracketleft 0x09 altgr
+trademark 0x09 shift altgr
+parenright 0x0a shift
+bracketright 0x0a altgr
+plusminus 0x0a shift altgr
+equal 0x0b shift
+braceright 0x0b altgr
+degree 0x0b shift altgr
+asterisk 0x0c
+question 0x0c shift
+backslash 0x0c altgr
+questiondown 0x0c shift altgr
+minus 0x0d
+underscore 0x0d shift
+dead_cedilla 0x0d altgr
+dead_ogonek 0x0d shift altgr
+at 0x10 altgr
+Greek_OMEGA 0x10 shift altgr
+lstroke 0x11 altgr
+Lstroke 0x11 shift altgr
+EuroSign 0x12 altgr
+paragraph 0x13 altgr
+registered 0x13 shift altgr
+tslash 0x14 altgr
+Tslash 0x14 shift altgr
+leftarrow 0x15 altgr
+yen 0x15 shift altgr
+downarrow 0x16 altgr
+uparrow 0x16 shift altgr
+idotless 0x17
+I 0x17 shift
+rightarrow 0x17 altgr
+oslash 0x18 altgr
+Ooblique 0x18 shift altgr
+thorn 0x19 altgr
+THORN 0x19 shift altgr
+gbreve 0x1a
+Gbreve 0x1a shift
+dead_diaeresis 0x1a altgr
+dead_abovering 0x1a shift altgr
+udiaeresis 0x1b
+Udiaeresis 0x1b shift
+asciitilde 0x1b altgr
+dead_macron 0x1b shift altgr
+ae 0x1e altgr
+AE 0x1e shift altgr
+ssharp 0x1f altgr
+section 0x1f shift altgr
+eth 0x20 altgr
+ETH 0x20 shift altgr
+dstroke 0x21 altgr
+ordfeminine 0x21 shift altgr
+eng 0x22 altgr
+ENG 0x22 shift altgr
+hstroke 0x23 altgr
+Hstroke 0x23 shift altgr
+kra 0x25 altgr
+ampersand 0x25 shift altgr
+lstroke 0x26 altgr
+Lstroke 0x26 shift altgr
+scedilla 0x27
+Scedilla 0x27 shift
+dead_acute 0x27 altgr
+dead_doubleacute 0x27 shift altgr
+i 0x28
+Iabovedot 0x28 shift
+dead_circumflex 0x28 altgr
+dead_caron 0x28 shift altgr
+backslash 0x29
+quotedbl 0x29 shift
+asciitilde 0x29 altgr
+comma 0x2b
+semicolon 0x2b shift
+bar 0x2b altgr
+dead_breve 0x2b shift altgr
+guillemotleft 0x2c altgr
+less 0x2c shift altgr
+guillemotright 0x2d altgr
+greater 0x2d shift altgr
+cent 0x2e altgr
+copyright 0x2e shift altgr
+leftdoublequotemark 0x2f altgr
+grave 0x2f shift altgr
+rightdoublequotemark 0x30 altgr
+apostrophe 0x30 shift altgr
+mu 0x32 altgr
+masculine 0x32 shift altgr
+odiaeresis 0x33
+Odiaeresis 0x33 shift
+less 0x33 altgr
+multiply 0x33 shift altgr
+ccedilla 0x34
+Ccedilla 0x34 shift
+greater 0x34 altgr
+division 0x34 shift altgr
+period 0x35
+colon 0x35 shift
+dead_belowdot 0x35 altgr
+dead_abovedot 0x35 shift altgr
diff --git a/tools/ioemu/main.c b/tools/ioemu/main.c
new file mode 100644 (file)
index 0000000..d745aed
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+ *  qemu user main
+ * 
+ *  Copyright (c) 2003 Fabrice Bellard
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "qemu.h"
+
+#define DEBUG_LOGFILE "/tmp/qemu.log"
+
+#ifdef __APPLE__
+#include <crt_externs.h>
+# define environ  (*_NSGetEnviron())
+#endif
+
+static const char *interp_prefix = CONFIG_QEMU_PREFIX;
+
+#if defined(__i386__) && !defined(CONFIG_STATIC)
+/* Force usage of an ELF interpreter even if it is an ELF shared
+   object ! */
+const char interp[] __attribute__((section(".interp"))) = "/lib/ld-linux.so.2";
+#endif
+
+/* for recent libc, we add these dummy symbols which are not declared
+   when generating a linked object (bug in ld ?) */
+#if (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)) && !defined(CONFIG_STATIC)
+long __preinit_array_start[0];
+long __preinit_array_end[0];
+long __init_array_start[0];
+long __init_array_end[0];
+long __fini_array_start[0];
+long __fini_array_end[0];
+#endif
+
+/* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
+   we allocate a bigger stack. Need a better solution, for example
+   by remapping the process stack directly at the right place */
+unsigned long x86_stack_size = 512 * 1024;
+
+void gemu_log(const char *fmt, ...)
+{
+    va_list ap;
+
+    va_start(ap, fmt);
+    vfprintf(stderr, fmt, ap);
+    va_end(ap);
+}
+/* timers for rdtsc */
+
+#if defined(__i386__)
+
+int64_t cpu_get_real_ticks(void)
+{
+    int64_t val;
+    asm volatile ("rdtsc" : "=A" (val));
+    return val;
+}
+
+#elif defined(__x86_64__)
+
+int64_t cpu_get_real_ticks(void)
+{
+    uint32_t low,high;
+    int64_t val;
+    asm volatile("rdtsc" : "=a" (low), "=d" (high));
+    val = high;
+    val <<= 32;
+    val |= low;
+    return val;
+}
+
+#else
+
+static uint64_t emu_time;
+
+int64_t cpu_get_real_ticks(void)
+{
+    return emu_time++;
+}
+
+#endif
+
+#ifdef TARGET_I386
+/***********************************************************/
+/* CPUX86 core interface */
+
+uint64_t cpu_get_tsc(CPUX86State *env)
+{
+    return cpu_get_real_ticks();
+}
+
+void cpu_loop()
+{
+}
+#endif
+
+void usage(void)
+{
+    printf("qemu-" TARGET_ARCH " version " QEMU_VERSION ", Copyright (c) 2003-2004 Fabrice Bellard\n"
+           "usage: qemu-" TARGET_ARCH " [-h] [-d opts] [-L path] [-s size] program [arguments...]\n"
+           "Linux CPU emulator (compiled for %s emulation)\n"
+           "\n"
+           "-h           print this help\n"
+           "-L path      set the elf interpreter prefix (default=%s)\n"
+           "-s size      set the stack size in bytes (default=%ld)\n"
+           "\n"
+           "debug options:\n"
+#ifdef USE_CODE_COPY
+           "-no-code-copy   disable code copy acceleration\n"
+#endif
+           "-l options   activate log (logfile=%s)\n"
+           "-p xen port number\n",
+           "-d xen domain id\n",
+           TARGET_ARCH,
+           interp_prefix, 
+           x86_stack_size,
+           DEBUG_LOGFILE);
+    _exit(1);
+}
+
+/* XXX: currently only used for async signals (see signal.c) */
+CPUState *global_env;
+/* used only if single thread */
+CPUState *cpu_single_env = NULL;
+
+/* used to free thread contexts */
+TaskState *first_task_state;
+
+int main(int argc, char **argv)
+{
+    const char *filename;
+    struct target_pt_regs regs1, *regs = &regs1;
+    struct image_info info1, *info = &info1;
+    TaskState ts1, *ts = &ts1;
+    CPUState *env;
+    int optind;
+    const char *r;
+    
+    if (argc <= 1)
+        usage();
+
+    /* init debug */
+    cpu_set_log_filename(DEBUG_LOGFILE);
+    cpu_set_log(0);
+
+    optind = 1;
+    for(;;) {
+        if (optind >= argc)
+            break;
+        r = argv[optind];
+        if (r[0] != '-')
+            break;
+        optind++;
+        r++;
+        if (!strcmp(r, "-")) {
+            break;
+        } else if (!strcmp(r, "l")) {
+            int mask;
+            CPULogItem *item;
+
+           if (optind >= argc)
+               break;
+            
+           r = argv[optind++];
+            mask = cpu_str_to_log_mask(r);
+            if (!mask) {
+                printf("Log items (comma separated):\n");
+                for(item = cpu_log_items; item->mask != 0; item++) {
+                    printf("%-10s %s\n", item->name, item->help);
+                }
+                exit(1);
+            }
+            cpu_set_log(mask);
+        } else if (!strcmp(r, "s")) {
+            r = argv[optind++];
+            x86_stack_size = strtol(r, (char **)&r, 0);
+            if (x86_stack_size <= 0)
+                usage();
+            if (*r == 'M')
+                x86_stack_size *= 1024 * 1024;
+            else if (*r == 'k' || *r == 'K')
+                x86_stack_size *= 1024;
+        } else if (!strcmp(r, "L")) {
+            interp_prefix = argv[optind++];
+        } else if (!strcmp(r, "p")) {
+            qemu_host_page_size = atoi(argv[optind++]);
+            if (qemu_host_page_size == 0 ||
+                (qemu_host_page_size & (qemu_host_page_size - 1)) != 0) {
+                fprintf(stderr, "page size must be a power of two\n");
+                exit(1);
+            }
+        } else 
+#ifdef USE_CODE_COPY
+        if (!strcmp(r, "no-code-copy")) {
+            code_copy_enabled = 0;
+        } else 
+#endif
+        {
+            usage();
+        }
+    }
+    if (optind >= argc)
+        usage();
+    filename = argv[optind];
+
+    /* Zero out regs */
+    memset(regs, 0, sizeof(struct target_pt_regs));
+
+    /* Zero out image_info */
+    memset(info, 0, sizeof(struct image_info));
+
+    /* Scan interp_prefix dir for replacement files. */
+    init_paths(interp_prefix);
+
+    /* NOTE: we need to init the CPU at this stage to get
+       qemu_host_page_size */
+    env = cpu_init();
+
+    global_env = env;
+
+    /* build Task State */
+    memset(ts, 0, sizeof(TaskState));
+    env->opaque = ts;
+    ts->used = 1;
+    env->user_mode_only = 1;
+
+    cpu_loop(env);
+    /* never exits */
+    return 0;
+}
diff --git a/tools/ioemu/memory/Makefile b/tools/ioemu/memory/Makefile
deleted file mode 100644 (file)
index eb9be7d..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-TOPDIR= ..
-CXXFLAGS=-I. -I../include -I..
-OBJS= memory.o misc_mem.o
-
-all: libmemory.a
-
-libmemory.a: $(OBJS)
-       $(AR) $(ARFLAGS) $@ $(OBJS)
-
-include $(TOPDIR)/mk/helix.mk
-
-install:: all
diff --git a/tools/ioemu/memory/memory.cc b/tools/ioemu/memory/memory.cc
deleted file mode 100644 (file)
index 286c9cc..0000000
+++ /dev/null
@@ -1,450 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: memory.cc,v 1.27 2003/03/02 23:59:12 cbothamy Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2001  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-
-
-
-
-
-#include "bochs.h"
-#define LOG_THIS BX_MEM_THIS
-
-#if BX_PROVIDE_CPU_MEMORY
-
-  void BX_CPP_AttrRegparmN(3)
-BX_MEM_C::writePhysicalPage(BX_CPU_C *cpu, dma_addr_t addr, unsigned len, void *data)
-{
-  Bit8u *data_ptr;
-  Bit32u a20addr;
-
-  // Note: accesses should always be contained within a single page now.
-
-#if BX_IODEBUG_SUPPORT
-  bx_iodebug_c::mem_write(cpu, addr, len, data);
-#endif
-  if (addr+len > this->dma_limit)
-          BX_PANIC(("address too large: %lx > %lx", addr+len, this->dma_limit));
-
-  a20addr = A20ADDR(addr);
-  BX_INSTR_PHY_WRITE(cpu->which_cpu(), a20addr, len);
-
-#if BX_DEBUGGER
-  // (mch) Check for physical write break points, TODO
-  // (bbd) Each breakpoint should have an associated CPU#, TODO
-  for (int i = 0; i < num_write_watchpoints; i++)
-        if (write_watchpoint[i] == a20addr) {
-             BX_CPU(0)->watchpoint = a20addr;
-              BX_CPU(0)->break_point = BREAK_POINT_WRITE;
-              break;
-        }
-#endif
-
-#if BX_SupportICache
-  if (a20addr < BX_MEM_THIS len)
-    cpu->iCache.decWriteStamp(cpu, a20addr);
-#endif
-
-  if ( a20addr <= BX_MEM_THIS len ) {
-    // all of data is within limits of physical memory
-    if ( (a20addr & 0xfff80000) != 0x00080000 ) {
-      if (len == 4) {
-        WriteHostDWordToLittleEndian(&vector[a20addr], *(Bit32u*)data);
-        BX_DBG_DIRTY_PAGE(a20addr >> 12);
-        return;
-        }
-      if (len == 2) {
-        WriteHostWordToLittleEndian(&vector[a20addr], *(Bit16u*)data);
-        BX_DBG_DIRTY_PAGE(a20addr >> 12);
-        return;
-        }
-      if (len == 1) {
-        * ((Bit8u *) (&vector[a20addr])) = * (Bit8u *) data;
-        BX_DBG_DIRTY_PAGE(a20addr >> 12);
-        return;
-        }
-      // len == other, just fall thru to special cases handling
-      }
-
-#ifdef BX_LITTLE_ENDIAN
-  data_ptr = (Bit8u *) data;
-#else // BX_BIG_ENDIAN
-  data_ptr = (Bit8u *) data + (len - 1);
-#endif
-
-write_one:
-    if ( (a20addr & 0xfff80000) != 0x00080000 ) {
-      // addr *not* in range 00080000 .. 000FFFFF
-      vector[a20addr] = *data_ptr;
-      BX_DBG_DIRTY_PAGE(a20addr >> 12);
-inc_one:
-      if (len == 1) return;
-      len--;
-      a20addr++;
-#ifdef BX_LITTLE_ENDIAN
-      data_ptr++;
-#else // BX_BIG_ENDIAN
-      data_ptr--;
-#endif
-      goto write_one;
-      }
-
-    // addr in range 00080000 .. 000FFFFF
-
-    if (a20addr <= 0x0009ffff) {
-      // regular memory 80000 .. 9FFFF
-      vector[a20addr] = *data_ptr;
-      BX_DBG_DIRTY_PAGE(a20addr >> 12);
-      goto inc_one;
-      }
-    if (a20addr <= 0x000bffff) {
-      // VGA memory A0000 .. BFFFF
-      DEV_vga_mem_write(a20addr, *data_ptr);
-      BX_DBG_DIRTY_PAGE(a20addr >> 12);
-      BX_DBG_UCMEM_REPORT(a20addr, 1, BX_WRITE, *data_ptr); // obsolete
-      goto inc_one;
-      }
-    // adapter ROM     C0000 .. DFFFF
-    // ROM BIOS memory E0000 .. FFFFF
-    // (ignore write)
-    //BX_INFO(("ROM lock %08x: len=%u",
-    //  (unsigned) a20addr, (unsigned) len));
-#if BX_PCI_SUPPORT == 0
-#if BX_SHADOW_RAM
-    // Write it since its in shadow RAM
-    vector[a20addr] = *data_ptr;
-    BX_DBG_DIRTY_PAGE(a20addr >> 12);
-#else
-    // ignore write to ROM
-#endif
-#else
-    // Write Based on 440fx Programming
-    if (bx_options.Oi440FXSupport->get () &&
-        ((a20addr >= 0xC0000) && (a20addr <= 0xFFFFF))) {
-      switch (DEV_pci_wr_memtype(a20addr & 0xFC000)) {
-        case 0x1:   // Writes to ShadowRAM
-//        BX_INFO(("Writing to ShadowRAM %08x, len %u ! ", (unsigned) a20addr, (unsigned) len));
-          shadow[a20addr - 0xc0000] = *data_ptr;
-          BX_DBG_DIRTY_PAGE(a20addr >> 12);
-          goto inc_one;
-
-        case 0x0:   // Writes to ROM, Inhibit
-          BX_DEBUG(("Write to ROM ignored: address %08x, data %02x", (unsigned) a20addr, *data_ptr));
-          goto inc_one;
-        default:
-          BX_PANIC(("writePhysicalPage: default case"));
-          goto inc_one;
-        }
-      }
-#endif
-    goto inc_one;
-    }
-
-  else {
-    // some or all of data is outside limits of physical memory
-    unsigned i;
-
-#ifdef BX_LITTLE_ENDIAN
-  data_ptr = (Bit8u *) data;
-#else // BX_BIG_ENDIAN
-  data_ptr = (Bit8u *) data + (len - 1);
-#endif
-
-
-#if BX_SUPPORT_VBE
-    // Check VBE LFB support
-    
-    if ((a20addr >= VBE_DISPI_LFB_PHYSICAL_ADDRESS) &&
-        (a20addr <  (VBE_DISPI_LFB_PHYSICAL_ADDRESS +  VBE_DISPI_TOTAL_VIDEO_MEMORY_BYTES)))
-    {
-      for (i = 0; i < len; i++) {
-        
-        //if (a20addr < BX_MEM_THIS len) {
-          //vector[a20addr] = *data_ptr;
-          //BX_DBG_DIRTY_PAGE(a20addr >> 12);
-          DEV_vga_mem_write(a20addr, *data_ptr);
-        //  }
-        
-        // otherwise ignore byte, since it overruns memory
-        addr++;
-        a20addr = (addr);
-#ifdef BX_LITTLE_ENDIAN
-        data_ptr++;
-#else // BX_BIG_ENDIAN
-        data_ptr--;
-#endif
-      }
-      return;
-    }
-    
-#endif    
-
-#if BX_SUPPORT_APIC
-    bx_generic_apic_c *local_apic = &cpu->local_apic;
-    bx_generic_apic_c *ioapic = bx_devices.ioapic;
-    if (local_apic->is_selected (a20addr, len)) {
-      local_apic->write (a20addr, (Bit32u *)data, len);
-      return;
-    } else if (ioapic->is_selected (a20addr, len)) {
-      ioapic->write (a20addr, (Bit32u *)data, len);
-      return;
-    }
-    else 
-#endif
-    for (i = 0; i < len; i++) {
-      if (a20addr < BX_MEM_THIS len) {
-        vector[a20addr] = *data_ptr;
-        BX_DBG_DIRTY_PAGE(a20addr >> 12);
-        }
-      // otherwise ignore byte, since it overruns memory
-      addr++;
-      a20addr = (addr);
-#ifdef BX_LITTLE_ENDIAN
-      data_ptr++;
-#else // BX_BIG_ENDIAN
-      data_ptr--;
-#endif
-      }
-    return;
-    }
-}
-
-
-  void BX_CPP_AttrRegparmN(3)
-BX_MEM_C::readPhysicalPage(BX_CPU_C *cpu, dma_addr_t addr, unsigned len, void *data)
-{
-  Bit8u *data_ptr;
-  Bit32u a20addr;
-
-#if BX_IODEBUG_SUPPORT
-  bx_iodebug_c::mem_read(cpu, addr, len, data);
-#endif
-  
-  if (addr+len > this->dma_limit)
-          BX_PANIC(("address too large: %lx > %lx", addr+len, this->dma_limit));
-
-  a20addr = A20ADDR(addr);
-  BX_INSTR_PHY_READ(cpu->which_cpu(), a20addr, len);
-
-#if BX_DEBUGGER
-  // (mch) Check for physical read break points, TODO
-  // (bbd) Each breakpoint should have an associated CPU#, TODO
-  for (int i = 0; i < num_read_watchpoints; i++)
-        if (read_watchpoint[i] == a20addr) {
-             BX_CPU(0)->watchpoint = a20addr;
-              BX_CPU(0)->break_point = BREAK_POINT_READ;
-              break;
-        }
-#endif
-
-  if ( (a20addr + len) <= BX_MEM_THIS len ) {
-    // all of data is within limits of physical memory
-    if ( (a20addr & 0xfff80000) != 0x00080000 ) {
-      if (len == 4) {
-        ReadHostDWordFromLittleEndian(&vector[a20addr], * (Bit32u*) data);
-        return;
-        }
-      if (len == 2) {
-        ReadHostWordFromLittleEndian(&vector[a20addr], * (Bit16u*) data);
-        return;
-        }
-      if (len == 1) {
-        * (Bit8u *) data =  * ((Bit8u *) (&vector[a20addr]));
-        return;
-        }
-      // len == 3 case can just fall thru to special cases handling
-      }
-
-
-#ifdef BX_LITTLE_ENDIAN
-    data_ptr = (Bit8u *) data;
-#else // BX_BIG_ENDIAN
-    data_ptr = (Bit8u *) data + (len - 1);
-#endif
-
-
-
-read_one:
-    if ( (a20addr & 0xfff80000) != 0x00080000 ) {
-      // addr *not* in range 00080000 .. 000FFFFF
-      *data_ptr = vector[a20addr];
-inc_one:
-      if (len == 1) return;
-      len--;
-      a20addr++;
-#ifdef BX_LITTLE_ENDIAN
-      data_ptr++;
-#else // BX_BIG_ENDIAN
-      data_ptr--;
-#endif
-      goto read_one;
-      }
-
-    // addr in range 00080000 .. 000FFFFF
-#if BX_PCI_SUPPORT == 0
-    if ((a20addr <= 0x0009ffff) || (a20addr >= 0x000c0000) ) {
-      // regular memory 80000 .. 9FFFF, C0000 .. F0000
-      *data_ptr = vector[a20addr];
-      goto inc_one;
-      }
-    // VGA memory A0000 .. BFFFF
-    *data_ptr = DEV_vga_mem_read(a20addr);
-    BX_DBG_UCMEM_REPORT(a20addr, 1, BX_READ, *data_ptr); // obsolete
-    goto inc_one;
-#else   // #if BX_PCI_SUPPORT == 0
-    if (a20addr <= 0x0009ffff) {
-      *data_ptr = vector[a20addr];
-      goto inc_one;
-      }
-    if (a20addr <= 0x000BFFFF) {
-      // VGA memory A0000 .. BFFFF
-      *data_ptr = DEV_vga_mem_read(a20addr);
-      BX_DBG_UCMEM_REPORT(a20addr, 1, BX_READ, *data_ptr);
-      goto inc_one;
-      }
-
-    // a20addr in C0000 .. FFFFF
-    if (!bx_options.Oi440FXSupport->get ()) {
-      *data_ptr = vector[a20addr];
-      goto inc_one;
-      }
-    else {
-      switch (DEV_pci_rd_memtype(a20addr & 0xFC000)) {
-        case 0x1:   // Read from ShadowRAM
-          *data_ptr = shadow[a20addr - 0xc0000];
-          BX_INFO(("Reading from ShadowRAM %08x, Data %02x ", (unsigned) a20addr, *data_ptr));
-          goto inc_one;
-
-        case 0x0:   // Read from ROM
-          *data_ptr = vector[a20addr];
-          //BX_INFO(("Reading from ROM %08x, Data %02x  ", (unsigned) a20addr, *data_ptr));
-          goto inc_one;
-        default:
-          BX_PANIC(("::readPhysicalPage: default case"));
-        }
-      }
-    goto inc_one;
-#endif  // #if BX_PCI_SUPPORT == 0
-    }
-  else {
-    // some or all of data is outside limits of physical memory
-    unsigned i;
-
-#ifdef BX_LITTLE_ENDIAN
-    data_ptr = (Bit8u *) data;
-#else // BX_BIG_ENDIAN
-    data_ptr = (Bit8u *) data + (len - 1);
-#endif
-
-#if BX_SUPPORT_VBE
-    // Check VBE LFB support
-    
-    if ((a20addr >= VBE_DISPI_LFB_PHYSICAL_ADDRESS) &&
-        (a20addr <  (VBE_DISPI_LFB_PHYSICAL_ADDRESS +  VBE_DISPI_TOTAL_VIDEO_MEMORY_BYTES)))
-    {
-      for (i = 0; i < len; i++) {
-        
-        //if (a20addr < BX_MEM_THIS len) {
-          //vector[a20addr] = *data_ptr;
-          //BX_DBG_DIRTY_PAGE(a20addr >> 12);
-          *data_ptr = DEV_vga_mem_read(a20addr);
-        //  }
-        
-        // otherwise ignore byte, since it overruns memory
-        addr++;
-        a20addr = (addr);
-#ifdef BX_LITTLE_ENDIAN
-        data_ptr++;
-#else // BX_BIG_ENDIAN
-        data_ptr--;
-#endif
-      }
-      return;
-    }
-    
-#endif    
-
-
-#if BX_SUPPORT_APIC
-    bx_generic_apic_c *local_apic = &cpu->local_apic;
-    bx_generic_apic_c *ioapic = bx_devices.ioapic;
-    if (local_apic->is_selected (addr, len)) {
-      local_apic->read (addr, data, len);
-      return;
-    } else if (ioapic->is_selected (addr, len)) {
-      ioapic->read (addr, data, len);
-      return;
-    }
-#endif
-    for (i = 0; i < len; i++) {
-#if BX_PCI_SUPPORT == 0
-      if (a20addr < BX_MEM_THIS len)
-        *data_ptr = vector[a20addr];
-      else
-        *data_ptr = 0xff;
-#else   // BX_PCI_SUPPORT == 0
-      if (a20addr < BX_MEM_THIS len) {
-        if ((a20addr >= 0x000C0000) && (a20addr <= 0x000FFFFF)) {
-          if (!bx_options.Oi440FXSupport->get ())
-            *data_ptr = vector[a20addr];
-          else {
-            switch (DEV_pci_rd_memtype(a20addr & 0xFC000)) {
-              case 0x0:   // Read from ROM
-                *data_ptr = vector[a20addr];
-                //BX_INFO(("Reading from ROM %08x, Data %02x ", (unsigned) a20addr, *data_ptr));
-                break;
-
-              case 0x1:   // Read from Shadow RAM
-                *data_ptr = shadow[a20addr - 0xc0000];
-                BX_INFO(("Reading from ShadowRAM %08x, Data %02x  ", (unsigned) a20addr, *data_ptr));
-                break;
-              default:
-                BX_PANIC(("readPhysicalPage: default case"));
-              } // Switch
-            }
-          }
-        else {
-          *data_ptr = vector[a20addr];
-          BX_INFO(("Reading from Norm %08x, Data %02x  ", (unsigned) a20addr, *data_ptr));
-          }
-        }
-      else 
-        *data_ptr = 0xff;
-#endif  // BX_PCI_SUPPORT == 0
-      addr++;
-      a20addr = (addr);
-#ifdef BX_LITTLE_ENDIAN
-      data_ptr++;
-#else // BX_BIG_ENDIAN
-      data_ptr--;
-#endif
-      }
-    return;
-    }
-}
-
-#endif // #if BX_PROVIDE_CPU_MEMORY
diff --git a/tools/ioemu/memory/memory.h b/tools/ioemu/memory/memory.h
deleted file mode 100644 (file)
index cc58699..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: memory.h,v 1.16 2003/08/05 13:19:35 cbothamy Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2001  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-
-#define BX_USE_MEM_SMF 0
-
-#if BX_USE_MEM_SMF
-// if static member functions on, then there is only one memory
-#  define BX_MEM_SMF  static
-#  define BX_MEM_THIS BX_MEM(0)->
-#else
-#  define BX_MEM_SMF
-#  define BX_MEM_THIS this->
-#endif
-
-#if defined(__i386__)
-typedef Bit32u dma_addr_t;
-#elif defined(__x86_64__)
-typedef Bit64u dma_addr_t;
-#endif
-
-// alignment of memory vector, must be a power of 2
-#define BX_MEM_VECTOR_ALIGN 4096
-
-class BOCHSAPI BX_MEM_C : public logfunctions {
-
-public:
-  Bit8u   *actual_vector;
-  Bit8u   *vector;  // aligned correctly
-  size_t  len;
-  size_t  dma_limit;
-  size_t  megabytes;  // (len in Megabytes)
-#if BX_PCI_SUPPORT
-  Bit8u   shadow[4*16*4096]; // 256k of memory
-#endif
-#if BX_DEBUGGER
-  unsigned char dbg_dirty_pages[(BX_MAX_DIRTY_PAGE_TABLE_MEGS * 1024 * 1024) / 4096];
-  Bit32u dbg_count_dirty_pages () {
-    return (BX_MAX_DIRTY_PAGE_TABLE_MEGS * 1024 * 1024) / 4096;
-  }
-#endif
-  unsigned long *page_array;   /* for get_pfn_list() */
-
-  BX_MEM_C(void);
-  //BX_MEM_C(size_t memsize);
-  ~BX_MEM_C(void);
-  BX_MEM_SMF void    alloc_vector_aligned (size_t bytes, size_t alignment) BX_CPP_AttrRegparmN(2);
-  BX_MEM_SMF void    init_memory(int memsize);
-  BX_MEM_SMF void    readPhysicalPage(BX_CPU_C *cpu, dma_addr_t addr,
-                                      unsigned len, void *data) BX_CPP_AttrRegparmN(3);
-  BX_MEM_SMF void    writePhysicalPage(BX_CPU_C *cpu, dma_addr_t addr,
-                                       unsigned len, void *data) BX_CPP_AttrRegparmN(3);
-  BX_MEM_SMF void    load_ROM(const char *path, Bit32u romaddress, Bit8u type);
-  BX_MEM_SMF Bit32u  get_memory_in_k(void);
-#if BX_PCI_SUPPORT
-  BX_MEM_SMF Bit8u*  pci_fetch_ptr(Bit32u addr) BX_CPP_AttrRegparmN(1);
-#endif
-  BX_MEM_SMF bx_bool dbg_fetch_mem(Bit32u addr, unsigned len, Bit8u *buf);
-  BX_MEM_SMF bx_bool dbg_set_mem(Bit32u addr, unsigned len, Bit8u *buf);
-  BX_MEM_SMF bx_bool dbg_crc32(
-    unsigned long (*f)(unsigned char *buf, int len),
-    Bit32u addr1, Bit32u addr2, Bit32u *crc);
-  BX_MEM_SMF Bit8u * getHostMemAddr(BX_CPU_C *cpu, Bit32u a20Addr, unsigned op) BX_CPP_AttrRegparmN(3);
-  };
-
-#if BX_PROVIDE_CPU_MEMORY==1
-
-#if BX_SMP_PROCESSORS==1
-BOCHSAPI extern BX_MEM_C    bx_mem;
-#else
-BOCHSAPI extern BX_MEM_C    *bx_mem_array[BX_ADDRESS_SPACES];
-#endif  /* BX_SMP_PROCESSORS */
-
-#endif  /* BX_PROVIDE_CPU_MEMORY==1 */
-
-#if BX_DEBUGGER
-#  define BX_DBG_DIRTY_PAGE(page) BX_MEM(0)->dbg_dirty_pages[page] = 1;
-#else
-#  define BX_DBG_DIRTY_PAGE(page)
-#endif
diff --git a/tools/ioemu/memory/misc_mem.cc b/tools/ioemu/memory/misc_mem.cc
deleted file mode 100644 (file)
index 5d2b678..0000000
+++ /dev/null
@@ -1,440 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id: misc_mem.cc,v 1.41 2003/09/10 16:34:56 vruppert Exp $
-/////////////////////////////////////////////////////////////////////////
-//
-//  Copyright (C) 2002  MandrakeSoft S.A.
-//
-//    MandrakeSoft S.A.
-//    43, rue d'Aboukir
-//    75002 Paris - France
-//    http://www.linux-mandrake.com/
-//    http://www.mandrakesoft.com/
-//
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2 of the License, or (at your option) any later version.
-//
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
-//
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-
-
-
-
-
-
-#include "bochs.h"
-#ifdef BX_USE_VMX
-extern "C" {
-#include <sys/mman.h>
-}
-#endif
-
-#define LOG_THIS BX_MEM(0)->
-
-#if BX_PROVIDE_CPU_MEMORY
-  Bit32u
-BX_MEM_C::get_memory_in_k(void)
-{
-  return(BX_MEM_THIS megabytes * 1024);
-}
-#endif // #if BX_PROVIDE_CPU_MEMORY
-
-
-#if BX_PROVIDE_CPU_MEMORY
-  // BX_MEM_C constructor
-BX_MEM_C::BX_MEM_C(void)
-{
-  char mem[6];
-  snprintf(mem, 6, "MEM%d", BX_SIM_ID);
-  put(mem);
-  settype(MEMLOG);
-
-  vector = NULL;
-  actual_vector = NULL;
-  len    = 0;
-  megabytes = 0;
-}
-#endif // #if BX_PROVIDE_CPU_MEMORY
-
-
-
-#if BX_PROVIDE_CPU_MEMORY
-void BX_CPP_AttrRegparmN(2)
-BX_MEM_C::alloc_vector_aligned (size_t bytes, size_t alignment)
-{
-  if (actual_vector != NULL) {
-    BX_INFO (("freeing existing memory vector"));
-    delete [] actual_vector;
-    actual_vector = NULL;
-    vector = NULL;
-  }
-  Bit64u test_mask = alignment - 1;
-  actual_vector = new Bit8u [bytes+test_mask];
-  // round address forward to nearest multiple of alignment.  Alignment 
-  // MUST BE a power of two for this to work.
-  unsigned long masked = ((unsigned long)(actual_vector + test_mask)) & ~test_mask;
-  vector = (Bit8u *)masked;
-  // sanity check: no lost bits during pointer conversion
-  BX_ASSERT (sizeof(masked) >= sizeof(vector));
-  // sanity check: after realignment, everything fits in allocated space
-  BX_ASSERT (vector+bytes <= actual_vector+bytes+test_mask);
-  BX_INFO (("allocated memory at %p. after alignment, vector=%p", 
-       actual_vector, vector));
-}
-#endif
-
-// We can't use this because alloc_vector_aligned uses BX_INFO, but the object does not yet exists
-/*
-#if BX_PROVIDE_CPU_MEMORY
-  // BX_MEM_C constructor
-
-BX_MEM_C::BX_MEM_C(size_t memsize)
-{
-  char mem[6];
-  snprintf(mem, 6, "MEM%d", BX_SIM_ID);
-  put(mem);
-  settype(MEMLOG);
-
-  vector = NULL;
-  actual_vector = NULL;
-  alloc_vector_aligned (memsize, BX_MEM_VECTOR_ALIGN);
-  len    = memsize;
-  megabytes = len / (1024*1024);
-}
-#endif // #if BX_PROVIDE_CPU_MEMORY
-*/
-
-
-#if BX_PROVIDE_CPU_MEMORY
-// BX_MEM_C destructor
-BX_MEM_C::~BX_MEM_C(void)
-{
-  if (this-> vector != NULL) {
-    delete [] actual_vector;
-    actual_vector = NULL;
-    vector = NULL;
-    }
-  else {
-    BX_DEBUG(("(%u)   memory not freed as it wasn't allocated!", BX_SIM_ID));
-    }
-}
-#endif // #if BX_PROVIDE_CPU_MEMORY
-
-
-#if BX_PROVIDE_CPU_MEMORY
-  void
-BX_MEM_C::init_memory(int memsize)
-{
-  BX_DEBUG(("Init $Id: misc_mem.cc,v 1.41 2003/09/10 16:34:56 vruppert Exp $"));
-  // you can pass 0 if memory has been allocated already through
-  // the constructor, or the desired size of memory if it hasn't
-  // BX_INFO(("%.2fMB", (float)(BX_MEM_THIS megabytes) ));
-
-#ifndef BX_USE_VMX
-  if (BX_MEM_THIS vector == NULL) {
-    // memory not already allocated, do now...
-    alloc_vector_aligned (memsize, BX_MEM_VECTOR_ALIGN);
-#endif
-    BX_MEM_THIS len    = memsize;
-    BX_MEM_THIS megabytes = memsize / (1024*1024);
-    BX_INFO(("%.2fMB", (float)(BX_MEM_THIS megabytes) ));
-#ifndef BX_USE_VMX
-    }
-#endif
-
-#if BX_DEBUGGER
-  if (megabytes > BX_MAX_DIRTY_PAGE_TABLE_MEGS) {
-    BX_INFO(("Error: memory larger than dirty page table can handle"));
-    BX_PANIC(("Error: increase BX_MAX_DIRTY_PAGE_TABLE_MEGS"));
-    }
-#endif
-
-    unsigned long nr_pages = megabytes * (1024 * 1024/getpagesize());
-
-    if ( (page_array = (unsigned long *) 
-                 malloc(nr_pages * sizeof(unsigned long))) == NULL)
-    {
-        BX_ERROR(("Could not allocate memory"));
-               return;
-    }
-
-    if ( xc_get_pfn_list(xc_handle, domid, page_array, nr_pages) != nr_pages )
-    {
-        BX_ERROR(("Could not get the page frame list"));
-               return;
-    }
-
-#define PAGE_SHIFT 12
-#define PAGE_SIZE  (1 << PAGE_SHIFT)
-
-    if ((vector = (Bit8u *) xc_map_foreign_batch(xc_handle, domid,
-                                                 PROT_READ|PROT_WRITE,
-                                                 page_array,
-                                                 nr_pages - 1)) == 0) {
-        BX_ERROR(("Could not map guest physical"));
-        return;
-    }
-
-    BX_MEM_THIS dma_limit = (nr_pages - 1) << PAGE_SHIFT;
-    BX_INFO(("DMA limit: %lx", BX_MEM_THIS dma_limit));
-
-    shared_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE, 
-                                       PROT_READ|PROT_WRITE, 
-                                       page_array[nr_pages - 1]);
-}
-#endif // #if BX_PROVIDE_CPU_MEMORY
-
-
-#if BX_PROVIDE_CPU_MEMORY
-  void
-  // Values for type :
-  // 0 : System Bios
-  // 1 : VGA Bios
-  // 2 : Optional ROM Bios
-BX_MEM_C::load_ROM(const char *path, Bit32u romaddress, Bit8u type)
-{
-  struct stat stat_buf;
-  int fd, ret;
-  unsigned long size, offset;
-
-  if (*path == '\0') {
-    if (type == 2) {
-      BX_PANIC(( "ROM: Optional BIOS image undefined."));
-      }
-    else if (type == 1) {
-      BX_PANIC(( "ROM: VGA BIOS image undefined."));
-      }
-    else {
-      BX_PANIC(( "ROM: System BIOS image undefined."));
-      }
-    return;
-    }
-  // read in ROM BIOS image file
-  fd = open(path, O_RDONLY
-#ifdef O_BINARY
-            | O_BINARY
-#endif
-           );
-  if (fd < 0) {
-    if (type < 2) {
-      BX_PANIC(( "ROM: couldn't open ROM image file '%s'.", path));
-      }
-    else {
-      BX_ERROR(( "ROM: couldn't open ROM image file '%s'.", path));
-      }
-    return;
-    }
-  ret = fstat(fd, &stat_buf);
-  if (ret) {
-    if (type < 2) {
-      BX_PANIC(( "ROM: couldn't stat ROM image file '%s'.", path));
-      }
-    else {
-      BX_ERROR(( "ROM: couldn't stat ROM image file '%s'.", path));
-      }
-    return;
-    }
-
-  size = stat_buf.st_size;
-
-  if ( (romaddress + size) > BX_MEM_THIS len ) {
-    BX_PANIC(( "ROM: ROM address range > physical memsize!"));
-    return;
-    }
-
-  offset = 0;
-  while (size > 0) {
-    ret = read(fd, (bx_ptr_t) &BX_MEM_THIS vector[romaddress + offset], size);
-    if (ret <= 0) {
-      BX_PANIC(( "ROM: read failed on BIOS image: '%s'",path));
-      }
-    size -= ret;
-    offset += ret;
-    }
-  close(fd);
-  BX_INFO(("rom at 0x%05x/%u ('%s')",
-                       (unsigned) romaddress,
-                       (unsigned) stat_buf.st_size,
-                       path
-               ));
-}
-#endif // #if BX_PROVIDE_CPU_MEMORY
-
-#if BX_PCI_SUPPORT
-  Bit8u* BX_CPP_AttrRegparmN(1)
-BX_MEM_C::pci_fetch_ptr(Bit32u addr)
-{
-  if (bx_options.Oi440FXSupport->get ()) {
-    switch (DEV_pci_rd_memtype (addr)) {
-      case 0x1:   // Read from ShadowRAM
-        return (&BX_MEM_THIS shadow[addr - 0xc0000]);
-
-      case 0x0:   // Read from ROM
-        return (&BX_MEM_THIS vector[addr]);
-      default:
-        BX_PANIC(("pci_fetch_ptr(): default case"));
-        return(0);
-      }
-    }
-  else
-    return (&BX_MEM_THIS vector[addr]);
-}
-#endif
-
-
-#if ( BX_DEBUGGER || BX_DISASM || BX_GDBSTUB)
-  bx_bool
-BX_MEM_C::dbg_fetch_mem(Bit32u addr, unsigned len, Bit8u *buf)
-{
-  if ( (addr + len) > this->len ) {
-    BX_INFO(("dbg_fetch_mem out of range. 0x%x > 0x%x",
-      addr+len, this->len));
-    return(0); // error, beyond limits of memory
-    }
-  for (; len>0; len--) {
-    if ( (addr & 0xfffe0000) == 0x000a0000 ) {
-      *buf = DEV_vga_mem_read(addr);
-      }
-    else {
-#if BX_PCI_SUPPORT == 0
-      *buf = vector[addr];
-#else
-      if ( bx_options.Oi440FXSupport->get () &&
-          ((addr >= 0x000C0000) && (addr <= 0x000FFFFF)) ) {
-        switch (DEV_pci_rd_memtype (addr)) {
-          case 0x1:  // Fetch from ShadowRAM
-            *buf = shadow[addr - 0xc0000];
-//          BX_INFO(("Fetching from ShadowRAM %06x, len %u !", (unsigned)addr, (unsigned)len));
-            break;
-
-          case 0x0:  // Fetch from ROM
-            *buf = vector[addr];
-//          BX_INFO(("Fetching from ROM %06x, Data %02x ", (unsigned)addr, *buf));
-            break;
-          default:
-            BX_PANIC(("dbg_fetch_mem: default case"));
-          }
-        }
-      else
-        *buf = vector[addr];
-#endif  // #if BX_PCI_SUPPORT == 0
-      }
-    buf++;
-    addr++;
-    }
-  return(1);
-}
-#endif
-
-#if BX_DEBUGGER || BX_GDBSTUB
-  bx_bool
-BX_MEM_C::dbg_set_mem(Bit32u addr, unsigned len, Bit8u *buf)
-{
-  if ( (addr + len) > this->len ) {
-    return(0); // error, beyond limits of memory
-    }
-  for (; len>0; len--) {
-    if ( (addr & 0xfffe0000) == 0x000a0000 ) {
-      DEV_vga_mem_write(addr, *buf);
-      }
-    else
-      vector[addr] = *buf;
-    buf++;
-    addr++;
-    }
-  return(1);
-}
-#endif
-
-  bx_bool
-BX_MEM_C::dbg_crc32(unsigned long (*f)(unsigned char *buf, int len),
-    Bit32u addr1, Bit32u addr2, Bit32u *crc)
-{
-  unsigned len;
-
-  *crc = 0;
-  if (addr1 > addr2)
-    return(0);
-
-  if (addr2 >= this->len) {
-    return(0); // error, specified address past last phy mem addr
-    }
-  
-  len = 1 + addr2 - addr1;
-  *crc = f(vector + addr1, len);
-
-  return(1);
-}
-
-
-  Bit8u * BX_CPP_AttrRegparmN(3)
-BX_MEM_C::getHostMemAddr(BX_CPU_C *cpu, Bit32u a20Addr, unsigned op)
-  // Return a host address corresponding to the guest physical memory
-  // address (with A20 already applied), given that the calling
-  // code will perform an 'op' operation.  This address will be
-  // used for direct access to guest memory as an acceleration by
-  // a few instructions, like REP {MOV, INS, OUTS, etc}.
-  // Values of 'op' are { BX_READ, BX_WRITE, BX_RW }.
-
-  // The other assumption is that the calling code _only_ accesses memory
-  // directly within the page that encompasses the address requested.
-{
-  if ( a20Addr >= BX_MEM_THIS len )
-    return(NULL); // Error, requested addr is out of bounds.
-  if (op == BX_READ) {
-    if ( (a20Addr > 0x9ffff) && (a20Addr < 0xc0000) )
-      return(NULL); // Vetoed!  Mem mapped IO (VGA)
-#if !BX_PCI_SUPPORT
-    return( (Bit8u *) & vector[a20Addr] );
-#else
-    else if ( (a20Addr < 0xa0000) || (a20Addr > 0xfffff)
-              || (!bx_options.Oi440FXSupport->get ()) )
-      return( (Bit8u *) & vector[a20Addr] );
-    else {
-      switch (DEV_pci_rd_memtype (a20Addr)) {
-        case 0x0:   // Read from ROM
-          return ( (Bit8u *) & vector[a20Addr]);
-        case 0x1:   // Read from ShadowRAM
-          return( (Bit8u *) & shadow[a20Addr - 0xc0000]);
-        default:
-          BX_PANIC(("getHostMemAddr(): default case"));
-          return(0);
-        }
-      }
-#endif
-    }
-  else { // op == {BX_WRITE, BX_RW}
-    Bit8u *retAddr;
-
-    if ( (a20Addr < 0xa0000) || (a20Addr > 0xfffff) ) {
-      retAddr = (Bit8u *) & vector[a20Addr];
-      }
-#if !BX_PCI_SUPPORT
-    else
-      return(NULL); // Vetoed!  Mem mapped IO (VGA) and ROMs
-#else
-    else if ( (a20Addr < 0xc0000) || (!bx_options.Oi440FXSupport->get ()) )
-      return(NULL); // Vetoed!  Mem mapped IO (VGA) and ROMs
-    else if (DEV_pci_wr_memtype (a20Addr) == 1) {
-      // Write to ShadowRAM
-      retAddr = (Bit8u *) & shadow[a20Addr - 0xc0000];
-      }
-    else
-      return(NULL); // Vetoed!  ROMs
-#endif
-
-#if BX_SupportICache
-    cpu->iCache.decWriteStamp(cpu, a20Addr);
-#endif
-
-    return(retAddr);
-    }
-}
diff --git a/tools/ioemu/mk/helix.mk b/tools/ioemu/mk/helix.mk
deleted file mode 100644 (file)
index e18eb34..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-CXXFLAGS += -O2  -I../../../tools/libxc -I../../../xen/include/public
-clean:
-       $(RM) -f *.o *~ lib*.a device-model
-
-install::
-       
diff --git a/tools/ioemu/monitor.c b/tools/ioemu/monitor.c
new file mode 100644 (file)
index 0000000..dec25fe
--- /dev/null
@@ -0,0 +1,282 @@
+/*
+ * QEMU monitor
+ * 
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+#include <dirent.h>
+
+//#define DEBUG
+//#define DEBUG_COMPLETION
+
+#ifndef offsetof
+#define offsetof(type, field) ((size_t) &((type *)0)->field)
+#endif
+
+/*
+ * Supported types:
+ * 
+ * 'F'          filename
+ * 'B'          block device name
+ * 's'          string (accept optional quote)
+ * 'i'          integer
+ * '/'          optional gdb-like print format (like "/10x")
+ *
+ * '?'          optional type (for 'F', 's' and 'i')
+ *
+ */
+
+typedef struct term_cmd_t {
+    const char *name;
+    const char *args_type;
+    void (*handler)();
+    const char *params;
+    const char *help;
+} term_cmd_t;
+
+static CharDriverState *monitor_hd;
+
+static term_cmd_t term_cmds[];
+static term_cmd_t info_cmds[];
+
+static char term_outbuf[1024];
+static int term_outbuf_index;
+
+static void monitor_start_input(void);
+
+void term_flush(void)
+{
+    if (term_outbuf_index > 0) {
+       if(monitor_hd)
+        qemu_chr_write(monitor_hd, term_outbuf, term_outbuf_index);
+       else
+           fwrite(term_outbuf, term_outbuf_index, 1, stderr);
+        term_outbuf_index = 0;
+    }
+}
+
+/* flush at every end of line or if the buffer is full */
+void term_puts(const char *str)
+{
+    int c;
+    for(;;) {
+        c = *str++;
+        if (c == '\0')
+            break;
+        term_outbuf[term_outbuf_index++] = c;
+        if (term_outbuf_index >= sizeof(term_outbuf) ||
+            c == '\n')
+            term_flush();
+    }
+}
+
+void term_vprintf(const char *fmt, va_list ap)
+{
+    char buf[4096];
+    vsnprintf(buf, sizeof(buf), fmt, ap);
+    term_puts(buf);
+}
+
+void term_printf(const char *fmt, ...)
+{
+    va_list ap;
+    va_start(ap, fmt);
+    term_vprintf(fmt, ap);
+    va_end(ap);
+}
+
+static int compare_cmd(const char *name, const char *list)
+{
+    const char *p, *pstart;
+    int len;
+    len = strlen(name);
+    p = list;
+    for(;;) {
+        pstart = p;
+        p = strchr(p, '|');
+        if (!p)
+            p = pstart + strlen(pstart);
+        if ((p - pstart) == len && !memcmp(pstart, name, len))
+            return 1;
+        if (*p == '\0')
+            break;
+        p++;
+    }
+    return 0;
+}
+
+static void do_quit(void)
+{
+    extern int domid;
+    extern FILE* logfile;
+    char destroy_cmd[20];
+    sprintf(destroy_cmd, "xm destroy %d", domid);
+    if (system(destroy_cmd) == -1)
+        fprintf(logfile, "%s failed.!\n", destroy_cmd);
+    exit(0);
+}
+
+static term_cmd_t term_cmds[] = {
+    { "q|quit", "", do_quit,
+      "", "quit the emulator" },
+    { NULL, NULL, }, 
+};
+
+#define MAX_ARGS 16
+
+static void monitor_handle_command(const char *cmdline)
+{
+    const char *p, *pstart, *typestr;
+    char *q;
+    int c, nb_args, len, i;
+    term_cmd_t *cmd;
+    char cmdname[256];
+    void *str_allocated[MAX_ARGS];
+    void *args[MAX_ARGS];
+
+#ifdef DEBUG
+    term_printf("command='%s'\n", cmdline);
+#endif
+    
+    /* extract the command name */
+    p = cmdline;
+    q = cmdname;
+    while (isspace(*p))
+        p++;
+    if (*p == '\0')
+        return;
+    pstart = p;
+    while (*p != '\0' && *p != '/' && !isspace(*p))
+        p++;
+    len = p - pstart;
+    if (len > sizeof(cmdname) - 1)
+        len = sizeof(cmdname) - 1;
+    memcpy(cmdname, pstart, len);
+    cmdname[len] = '\0';
+    
+    /* find the command */
+    for(cmd = term_cmds; cmd->name != NULL; cmd++) {
+        if (compare_cmd(cmdname, cmd->name)) 
+            goto found;
+    }
+    term_printf("unknown command: '%s'\n", cmdname);
+    return;
+ found:
+
+    for(i = 0; i < MAX_ARGS; i++)
+        str_allocated[i] = NULL;
+    
+    /* parse the parameters */
+    typestr = cmd->args_type;
+    nb_args = 0;
+    for(;;) {
+        c = *typestr;
+        if (c == '\0')
+            break;
+        typestr++;
+        switch(c) {
+        /* TODO: add more commands we need here to support vmx device model */
+        case 'F':
+        case 'B':
+        case 's':
+        case '/':
+        case 'i':
+        case '-':
+        default:
+            term_printf("%s: unknown type '%c', we only support quit command now.\n", cmdname, c);
+            goto fail;
+        }
+    }
+    /* check that all arguments were parsed */
+    while (isspace(*p))
+        p++;
+    if (*p != '\0') {
+        term_printf("%s: extraneous characters at the end of line\n", 
+                    cmdname);
+        goto fail;
+    }
+
+    switch(nb_args) {
+    case 0:
+        cmd->handler();
+        break;
+    case 1:
+        cmd->handler(args[0]);
+        break;
+    case 2:
+        cmd->handler(args[0], args[1]);
+        break;
+    case 3:
+        cmd->handler(args[0], args[1], args[2]);
+        break;
+    case 4:
+        cmd->handler(args[0], args[1], args[2], args[3]);
+        break;
+    case 5:
+        cmd->handler(args[0], args[1], args[2], args[3], args[4]);
+        break;
+    case 6:
+        cmd->handler(args[0], args[1], args[2], args[3], args[4], args[5]);
+        break;
+    default:
+        term_printf("unsupported number of arguments: %d\n", nb_args);
+        goto fail;
+    }
+ fail:
+    for(i = 0; i < MAX_ARGS; i++)
+        qemu_free(str_allocated[i]);
+    return;
+}
+
+static int term_can_read(void *opaque)
+{
+    return 128;
+}
+
+static void term_read(void *opaque, const uint8_t *buf, int size)
+{
+    int i;
+    for(i = 0; i < size; i++)
+        readline_handle_byte(buf[i]);
+}
+
+static void monitor_start_input(void);
+
+static void monitor_handle_command1(void *opaque, const char *cmdline)
+{
+    monitor_handle_command(cmdline);
+    monitor_start_input();
+}
+
+static void monitor_start_input(void)
+{
+    readline_start("(VTXen) ", 0, monitor_handle_command1, NULL);
+}
+
+void monitor_init(CharDriverState *hd, int show_banner)
+{
+    monitor_hd = hd;
+    if (show_banner) {
+        term_printf("VMX device model. type 'q' to exit\n");
+    }
+    qemu_chr_add_read_handler(hd, term_can_read, term_read, NULL);
+    monitor_start_input();
+}
diff --git a/tools/ioemu/osdep.c b/tools/ioemu/osdep.c
new file mode 100644 (file)
index 0000000..087a5c2
--- /dev/null
@@ -0,0 +1,499 @@
+/*
+ * QEMU low level functions
+ * 
+ * Copyright (c) 2003 Fabrice Bellard
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "cpu.h"
+
+#if defined(__i386__) && !defined(CONFIG_SOFTMMU) && !defined(CONFIG_USER_ONLY)
+
+#include <sys/mman.h>
+#include <sys/ipc.h>
+
+/* When not using soft mmu, libc independant functions are needed for
+   the CPU core because it needs to use alternates stacks and
+   libc/thread incompatibles settings */
+
+#include <linux/unistd.h>
+
+#define QEMU_SYSCALL0(name) \
+{ \
+long __res; \
+__asm__ volatile ("int $0x80" \
+       : "=a" (__res) \
+       : "0" (__NR_##name)); \
+return __res; \
+}
+
+#define QEMU_SYSCALL1(name,arg1) \
+{ \
+long __res; \
+__asm__ volatile ("int $0x80" \
+       : "=a" (__res) \
+       : "0" (__NR_##name),"b" ((long)(arg1))); \
+return __res; \
+}
+
+#define QEMU_SYSCALL2(name,arg1,arg2) \
+{ \
+long __res; \
+__asm__ volatile ("int $0x80" \
+       : "=a" (__res) \
+       : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2))); \
+return __res; \
+}
+
+#define QEMU_SYSCALL3(name,arg1,arg2,arg3) \
+{ \
+long __res; \
+__asm__ volatile ("int $0x80" \
+       : "=a" (__res) \
+       : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
+                 "d" ((long)(arg3))); \
+return __res; \
+}
+
+#define QEMU_SYSCALL4(name,arg1,arg2,arg3,arg4) \
+{ \
+long __res; \
+__asm__ volatile ("int $0x80" \
+       : "=a" (__res) \
+       : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
+         "d" ((long)(arg3)),"S" ((long)(arg4))); \
+return __res; \
+} 
+
+#define QEMU_SYSCALL5(name,arg1,arg2,arg3,arg4,arg5) \
+{ \
+long __res; \
+__asm__ volatile ("int $0x80" \
+       : "=a" (__res) \
+       : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
+         "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5))); \
+return __res; \
+}
+
+#define QEMU_SYSCALL6(name,arg1,arg2,arg3,arg4,arg5,arg6) \
+{ \
+long __res; \
+__asm__ volatile ("push %%ebp ; movl %%eax,%%ebp ; movl %1,%%eax ; int $0x80 ; pop %%ebp" \
+       : "=a" (__res) \
+       : "i" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
+         "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5)), \
+         "0" ((long)(arg6))); \
+return __res; \
+}
+
+int qemu_write(int fd, const void *buf, size_t n)
+{
+    QEMU_SYSCALL3(write, fd, buf, n);
+}
+
+
+
+/****************************************************************/
+/* shmat replacement */
+
+int qemu_ipc(int call, unsigned long first, 
+            unsigned long second, unsigned long third, 
+            void *ptr, unsigned long fifth)
+{
+    QEMU_SYSCALL6(ipc, call, first, second, third, ptr, fifth);
+}
+
+#define SHMAT 21
+
+/* we must define shmat so that a specific address will be used when
+   mapping the X11 ximage */
+void *shmat(int shmid, const void *shmaddr, int shmflg)
+{
+    void *ptr;
+    int ret;
+    /* we give an address in the right memory area */
+    if (!shmaddr)
+        shmaddr = get_mmap_addr(8192 * 1024);
+    ret = qemu_ipc(SHMAT, shmid, shmflg, (unsigned long)&ptr, (void *)shmaddr, 0);
+    if (ret < 0)
+        return NULL;
+    return ptr;
+}
+
+/****************************************************************/
+/* sigaction bypassing the threads */
+
+static int kernel_sigaction(int signum, const struct qemu_sigaction *act, 
+                            struct qemu_sigaction *oldact, 
+                            int sigsetsize)
+{
+    QEMU_SYSCALL4(rt_sigaction, signum, act, oldact, sigsetsize);
+}
+
+int qemu_sigaction(int signum, const struct qemu_sigaction *act, 
+                   struct qemu_sigaction *oldact)
+{
+    return kernel_sigaction(signum, act, oldact, 8);
+}
+
+/****************************************************************/
+/* memory allocation */
+
+//#define DEBUG_MALLOC
+
+#define MALLOC_BASE       0xab000000
+#define PHYS_RAM_BASE     0xac000000
+
+#define MALLOC_ALIGN      16
+#define BLOCK_HEADER_SIZE 16
+
+typedef struct MemoryBlock {
+    struct MemoryBlock *next;
+    unsigned long size; /* size of block, including header */
+} MemoryBlock;
+
+static MemoryBlock *first_free_block;
+static unsigned long malloc_addr = MALLOC_BASE;
+
+static void *malloc_get_space(size_t size)
+{
+    void *ptr;
+    size = TARGET_PAGE_ALIGN(size);
+    ptr = mmap((void *)malloc_addr, size, 
+               PROT_WRITE | PROT_READ, 
+               MAP_PRIVATE | MAP_FIXED | MAP_ANON, -1, 0);
+    if (ptr == MAP_FAILED)
+        return NULL;
+    malloc_addr += size;
+    return ptr;
+}
+
+void *qemu_malloc(size_t size)
+{
+    MemoryBlock *mb, *mb1, **pmb;
+    void *ptr;
+    size_t size1, area_size;
+    
+    if (size == 0)
+        return NULL;
+
+    size = (size + BLOCK_HEADER_SIZE + MALLOC_ALIGN - 1) & ~(MALLOC_ALIGN - 1);
+    pmb = &first_free_block;
+    for(;;) {
+        mb = *pmb;
+        if (mb == NULL)
+            break;
+        if (size <= mb->size)
+            goto found;
+        pmb = &mb->next;
+    }
+    /* no big enough blocks found: get new space */
+    area_size = TARGET_PAGE_ALIGN(size);
+    mb = malloc_get_space(area_size);
+    if (!mb)
+        return NULL;
+    size1 = area_size - size;
+    if (size1 > 0) {
+        /* create a new free block */
+        mb1 = (MemoryBlock *)((uint8_t *)mb + size);
+        mb1->next = NULL;
+        mb1->size = size1;
+        *pmb = mb1;
+    }
+    goto the_end;
+ found:
+    /* a free block was found: use it */
+    size1 = mb->size - size;
+    if (size1 > 0) {
+        /* create a new free block */
+        mb1 = (MemoryBlock *)((uint8_t *)mb + size);
+        mb1->next = mb->next;
+        mb1->size = size1;
+        *pmb = mb1;
+    } else {
+        /* suppress the first block */
+        *pmb = mb->next;
+    }
+ the_end:
+    mb->size = size;
+    mb->next = NULL;
+    ptr = ((uint8_t *)mb + BLOCK_HEADER_SIZE);
+#ifdef DEBUG_MALLOC
+    qemu_printf("malloc: size=0x%x ptr=0x%lx\n", size, (unsigned long)ptr);
+#endif
+    return ptr;
+}
+
+void qemu_free(void *ptr)
+{
+    MemoryBlock *mb;
+
+    if (!ptr)
+        return;
+    mb = (MemoryBlock *)((uint8_t *)ptr - BLOCK_HEADER_SIZE);
+    mb->next = first_free_block;
+    first_free_block = mb;
+}
+
+/****************************************************************/
+/* virtual memory allocation */
+
+unsigned long mmap_addr = PHYS_RAM_BASE;
+
+void *get_mmap_addr(unsigned long size)
+{
+    unsigned long addr;
+    addr = mmap_addr;
+    mmap_addr += ((size + 4095) & ~4095) + 4096;
+    return (void *)addr;
+}
+
+#else
+
+int qemu_write(int fd, const void *buf, size_t n)
+{
+    int ret;
+    ret = write(fd, buf, n);
+    if (ret < 0)
+        return -errno;
+    else
+        return ret;
+}
+
+void *get_mmap_addr(unsigned long size)
+{
+    return NULL;
+}
+
+void qemu_free(void *ptr)
+{
+    free(ptr);
+}
+
+void *qemu_malloc(size_t size)
+{
+    return malloc(size);
+}
+
+#endif
+
+void *qemu_mallocz(size_t size)
+{
+    void *ptr;
+    ptr = qemu_malloc(size);
+    if (!ptr)
+        return NULL;
+    memset(ptr, 0, size);
+    return ptr;
+}
+
+char *qemu_strdup(const char *str)
+{
+    char *ptr;
+    ptr = qemu_malloc(strlen(str) + 1);
+    if (!ptr)
+        return NULL;
+    strcpy(ptr, str);
+    return ptr;
+}
+
+/****************************************************************/
+/* printf support */
+
+static inline int qemu_isdigit(int c)
+{
+    return c >= '0' && c <= '9';
+}
+
+#define OUTCHAR(c)     (buflen > 0? (--buflen, *buf++ = (c)): 0)
+
+/* from BSD ppp sources */
+int qemu_vsnprintf(char *buf, int buflen, const char *fmt, va_list args)
+{
+    int c, i, n;
+    int width, prec, fillch;
+    int base, len, neg;
+    unsigned long val = 0;
+    const char *f;
+    char *str, *buf0;
+    char num[32];
+    static const char hexchars[] = "0123456789abcdef";
+
+    buf0 = buf;
+    --buflen;
+    while (buflen > 0) {
+       for (f = fmt; *f != '%' && *f != 0; ++f)
+           ;
+       if (f > fmt) {
+           len = f - fmt;
+           if (len > buflen)
+               len = buflen;
+           memcpy(buf, fmt, len);
+           buf += len;
+           buflen -= len;
+           fmt = f;
+       }
+       if (*fmt == 0)
+           break;
+       c = *++fmt;
+       width = prec = 0;
+       fillch = ' ';
+       if (c == '0') {
+           fillch = '0';
+           c = *++fmt;
+       }
+       if (c == '*') {
+           width = va_arg(args, int);
+           c = *++fmt;
+       } else {
+           while (qemu_isdigit(c)) {
+               width = width * 10 + c - '0';
+               c = *++fmt;
+           }
+       }
+       if (c == '.') {
+           c = *++fmt;
+           if (c == '*') {
+               prec = va_arg(args, int);
+               c = *++fmt;
+           } else {
+               while (qemu_isdigit(c)) {
+                   prec = prec * 10 + c - '0';
+                   c = *++fmt;
+               }
+           }
+       }
+        /* modifiers */
+        switch(c) {
+        case 'l':
+            c = *++fmt;
+            break;
+        default:
+            break;
+        }
+        str = 0;
+       base = 0;
+       neg = 0;
+       ++fmt;
+       switch (c) {
+       case 'd':
+           i = va_arg(args, int);
+           if (i < 0) {
+               neg = 1;
+               val = -i;
+           } else
+               val = i;
+           base = 10;
+           break;
+       case 'o':
+           val = va_arg(args, unsigned int);
+           base = 8;
+           break;
+       case 'x':
+       case 'X':
+           val = va_arg(args, unsigned int);
+           base = 16;
+           break;
+       case 'p':
+           val = (unsigned long) va_arg(args, void *);
+           base = 16;
+           neg = 2;
+           break;
+       case 's':
+           str = va_arg(args, char *);
+           break;
+       case 'c':
+           num[0] = va_arg(args, int);
+           num[1] = 0;
+           str = num;
+           break;
+       default:
+           *buf++ = '%';
+           if (c != '%')
+               --fmt;          /* so %z outputs %z etc. */
+           --buflen;
+           continue;
+       }
+       if (base != 0) {
+           str = num + sizeof(num);
+           *--str = 0;
+           while (str > num + neg) {
+               *--str = hexchars[val % base];
+               val = val / base;
+               if (--prec <= 0 && val == 0)
+                   break;
+           }
+           switch (neg) {
+           case 1:
+               *--str = '-';
+               break;
+           case 2:
+               *--str = 'x';
+               *--str = '0';
+               break;
+           }
+           len = num + sizeof(num) - 1 - str;
+       } else {
+           len = strlen(str);
+           if (prec > 0 && len > prec)
+               len = prec;
+       }
+       if (width > 0) {
+           if (width > buflen)
+               width = buflen;
+           if ((n = width - len) > 0) {
+               buflen -= n;
+               for (; n > 0; --n)
+                   *buf++ = fillch;
+           }
+       }
+       if (len > buflen)
+           len = buflen;
+       memcpy(buf, str, len);
+       buf += len;
+       buflen -= len;
+    }
+    *buf = 0;
+    return buf - buf0;
+}
+
+void qemu_vprintf(const char *fmt, va_list ap)
+{
+    char buf[1024];
+    int len;
+    
+    len = qemu_vsnprintf(buf, sizeof(buf), fmt, ap);
+    qemu_write(1, buf, len);
+}
+
+void qemu_printf(const char *fmt, ...)
+{
+    va_list ap;
+    va_start(ap, fmt);
+    qemu_vprintf(fmt, ap);
+    va_end(ap);
+}
+
diff --git a/tools/ioemu/osdep.h b/tools/ioemu/osdep.h
new file mode 100644 (file)
index 0000000..f1d1820
--- /dev/null
@@ -0,0 +1,50 @@
+#ifndef QEMU_OSDEP_H
+#define QEMU_OSDEP_H
+
+#include <stdarg.h>
+
+int qemu_vsnprintf(char *buf, int buflen, const char *fmt, va_list args);
+void qemu_vprintf(const char *fmt, va_list ap);
+void qemu_printf(const char *fmt, ...);
+
+void *qemu_malloc(size_t size);
+void *qemu_mallocz(size_t size);
+void qemu_free(void *ptr);
+char *qemu_strdup(const char *str);
+
+void *get_mmap_addr(unsigned long size);
+
+/* specific kludges for OS compatibility (should be moved elsewhere) */
+#if defined(__i386__) && !defined(CONFIG_SOFTMMU) && !defined(CONFIG_USER_ONLY)
+
+/* disabled pthread version of longjmp which prevent us from using an
+   alternative signal stack */
+extern void __longjmp(jmp_buf env, int val);
+#define longjmp __longjmp
+
+#include <signal.h>
+
+/* NOTE: it works only because the glibc sigset_t is >= kernel sigset_t */
+struct qemu_sigaction {
+    union {
+        void (*_sa_handler)(int);
+        void (*_sa_sigaction)(int, struct siginfo *, void *);
+    } _u;
+    unsigned long sa_flags;
+    void (*sa_restorer)(void);
+    sigset_t sa_mask;          /* mask last for extensibility */
+};
+
+int qemu_sigaction(int signum, const struct qemu_sigaction *act, 
+                   struct qemu_sigaction *oldact);
+
+#undef sigaction
+#undef sa_handler
+#undef sa_sigaction
+#define sigaction qemu_sigaction
+#define sa_handler     _u._sa_handler
+#define sa_sigaction   _u._sa_sigaction
+
+#endif
+
+#endif
diff --git a/tools/ioemu/path.c b/tools/ioemu/path.c
new file mode 100644 (file)
index 0000000..7680970
--- /dev/null
@@ -0,0 +1,147 @@
+/* Code to mangle pathnames into those matching a given prefix.
+   eg. open("/lib/foo.so") => open("/usr/gnemul/i386-linux/lib/foo.so");
+
+   The assumption is that this area does not change.
+*/
+#include <sys/types.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+#include "qemu.h"
+
+struct pathelem
+{
+    /* Name of this, eg. lib */
+    char *name;
+    /* Full path name, eg. /usr/gnemul/x86-linux/lib. */
+    char *pathname;
+    struct pathelem *parent;
+    /* Children */
+    unsigned int num_entries;
+    struct pathelem *entries[0];
+};
+
+static struct pathelem *base;
+
+/* First N chars of S1 match S2, and S2 is N chars long. */
+static int strneq(const char *s1, unsigned int n, const char *s2)
+{
+    unsigned int i;
+
+    for (i = 0; i < n; i++)
+       if (s1[i] != s2[i])
+           return 0;
+    return s2[i] == 0;
+}
+
+static struct pathelem *add_entry(struct pathelem *root, const char *name);
+
+static struct pathelem *new_entry(const char *root,
+                                 struct pathelem *parent,
+                                 const char *name)
+{
+    struct pathelem *new = malloc(sizeof(*new));
+    new->name = strdup(name);
+    asprintf(&new->pathname, "%s/%s", root, name);
+    new->num_entries = 0;
+    return new;
+}
+
+#define streq(a,b) (strcmp((a), (b)) == 0)
+
+static struct pathelem *add_dir_maybe(struct pathelem *path)
+{
+    DIR *dir;
+
+    if ((dir = opendir(path->pathname)) != NULL) {
+       struct dirent *dirent;
+
+       while ((dirent = readdir(dir)) != NULL) {
+           if (!streq(dirent->d_name,".") && !streq(dirent->d_name,"..")){
+               path = add_entry(path, dirent->d_name);
+           }
+       }
+        closedir(dir);
+    }
+    return path;
+}
+
+static struct pathelem *add_entry(struct pathelem *root, const char *name)
+{
+    root->num_entries++;
+
+    root = realloc(root, sizeof(*root)
+                  + sizeof(root->entries[0])*root->num_entries);
+
+    root->entries[root->num_entries-1] = new_entry(root->pathname, root, name);
+    root->entries[root->num_entries-1]
+       = add_dir_maybe(root->entries[root->num_entries-1]);
+    return root;
+}
+
+/* This needs to be done after tree is stabalized (ie. no more reallocs!). */
+static void set_parents(struct pathelem *child, struct pathelem *parent)
+{
+    unsigned int i;
+
+    child->parent = parent;
+    for (i = 0; i < child->num_entries; i++)
+       set_parents(child->entries[i], child);
+}
+
+void init_paths(const char *prefix)
+{
+    if (prefix[0] != '/' ||
+        prefix[0] == '\0' ||
+        !strcmp(prefix, "/"))
+        return;
+
+    base = new_entry("", NULL, prefix+1);
+    base = add_dir_maybe(base);
+    if (base->num_entries == 0) {
+        free (base);
+        base = NULL;
+    } else {
+        set_parents(base, base);
+    }
+}
+
+/* FIXME: Doesn't handle DIR/.. where DIR is not in emulated dir. */
+static const char *
+follow_path(const struct pathelem *cursor, const char *name)
+{
+    unsigned int i, namelen;
+
+    name += strspn(name, "/");
+    namelen = strcspn(name, "/");
+
+    if (namelen == 0)
+       return cursor->pathname;
+
+    if (strneq(name, namelen, ".."))
+       return follow_path(cursor->parent, name + namelen);
+
+    if (strneq(name, namelen, "."))
+       return follow_path(cursor, name + namelen);
+
+    for (i = 0; i < cursor->num_entries; i++)
+       if (strneq(name, namelen, cursor->entries[i]->name))
+           return follow_path(cursor->entries[i], name + namelen);
+
+    /* Not found */
+    return NULL;
+}
+
+/* Look for path in emulation dir, otherwise return name. */
+const char *path(const char *name)
+{
+    /* Only do absolute paths: quick and dirty, but should mostly be OK.
+       Could do relative by tracking cwd. */
+    if (!base || name[0] != '/')
+       return name;
+
+    return follow_path(base, name) ?: name;
+}
diff --git a/tools/ioemu/pc-bios/Makefile b/tools/ioemu/pc-bios/Makefile
new file mode 100644 (file)
index 0000000..7ae0ff0
--- /dev/null
@@ -0,0 +1,24 @@
+#
+# NOTE: only compilable with x86 cross compile tools
+#
+include ../config-host.mak
+
+DEFINES=
+
+TARGETS=
+ifeq ($(ARCH),i386)
+TARGETS+=linux_boot.bin
+endif
+
+all: $(TARGETS)
+
+linux_boot.bin: linux_boot.o
+       ld --oformat binary -Ttext 0 -o $@ $<
+       chmod a-x $@
+
+%.o: %.S
+       $(CC) $(DEFINES) -c -o $@ $<
+
+clean:
+       rm -f $(TARGETS) *.o *~
+
diff --git a/tools/ioemu/pc-bios/README b/tools/ioemu/pc-bios/README
new file mode 100644 (file)
index 0000000..a10a9f0
--- /dev/null
@@ -0,0 +1,13 @@
+- The PC BIOS comes from the Bochs project
+  (http://bochs.sourceforge.net/). A patch from bios.diff was applied.
+
+- The VGA BIOS and the Cirrus VGA BIOS come from the LGPL VGA bios
+  project (http://www.nongnu.org/vgabios/).
+
+- The PowerPC Open Hack'Ware Open Firmware Compatible BIOS is
+  available at http://site.voila.fr/jmayer/OpenHackWare/index.htm.
+
+- Proll is a GPL'd boot PROM for Sparc JavaStations
+  (http://people.redhat.com/zaitcev/linux/).
+  Applying proll.patch allows circumventing some bugs and enables
+  faster kernel load through a hack.
diff --git a/tools/ioemu/pc-bios/bios.bin b/tools/ioemu/pc-bios/bios.bin
new file mode 100644 (file)
index 0000000..fe9816e
Binary files /dev/null and b/tools/ioemu/pc-bios/bios.bin differ
diff --git a/tools/ioemu/pc-bios/bios.diff b/tools/ioemu/pc-bios/bios.diff
new file mode 100644 (file)
index 0000000..7850769
--- /dev/null
@@ -0,0 +1,162 @@
+Index: rombios.c
+===================================================================
+RCS file: /cvsroot/bochs/bochs/bios/rombios.c,v
+retrieving revision 1.110
+diff -u -w -r1.110 rombios.c
+--- rombios.c  31 May 2004 13:11:27 -0000      1.110
++++ rombios.c  7 Oct 2004 21:23:50 -0000
+@@ -137,6 +137,7 @@
+ #define DEBUG_INT16        0
+ #define DEBUG_INT1A        0
+ #define DEBUG_INT74        0
++#define DEBUG_APM          0
+ #define BX_CPU           3
+ #define BX_USE_PS2_MOUSE 1
+@@ -145,6 +146,7 @@
+ #define BX_SUPPORT_FLOPPY 1
+ #define BX_FLOPPY_ON_CNT 37   // 2 seconds
+ #define BX_PCIBIOS       1
++#define BX_APM           1
+ #define BX_USE_ATADRV    1
+ #define BX_ELTORITO_BOOT 1
+@@ -230,17 +232,6 @@
+   out dx,ax
+ MEND
+-MACRO HALT2
+-  ;; the HALT macro is called with the line number of the HALT call.
+-  ;; The line number is then sent to the PANIC_PORT, causing Bochs/Plex
+-  ;; to print a BX_PANIC message.  This will normally halt the simulation
+-  ;; with a message such as "BIOS panic at rombios.c, line 4091".
+-  ;; However, users can choose to make panics non-fatal and continue.
+-  mov dx,#PANIC_PORT2
+-  mov ax,#?1
+-  out dx,ax
+-MEND
+-
+ MACRO JMP_AP
+   db 0xea
+   dw ?2
+@@ -1543,15 +1534,12 @@
+     }
+   if (action & BIOS_PRINTF_HALT) {
+-    // freeze in a busy loop.  If I do a HLT instruction, then in versions
+-    // 1.3.pre1 and earlier, it will panic without ever updating the VGA
+-    // display, so the panic message will not be visible.  By waiting
+-    // forever, you are certain to see the panic message on screen.
+-    // After a few more versions have passed, we can turn this back into
+-    // a halt or something.
+-    // do {} while (1);
++    // freeze in a busy loop.  
+ ASM_START
+-    HALT2(__LINE__)
++    cli
++ halt2_loop:
++    hlt
++    jmp halt2_loop
+ ASM_END
+     }
+ }
+@@ -5412,8 +5400,8 @@
+         case 0x03: SET_BL( 0x06 ); break;
+         }
+-      DI = 0xefc7;
+-      ES = 0xf000;
++      DI = read_word(0x00, 0x1e*4); // INT vector 0x1E
++      ES = read_word(0x00, 0x1e*4+2);
+       goto int13_success;
+       break;
+@@ -6984,8 +6972,8 @@
+         }
+       /* set es & di to point to 11 byte diskette param table in ROM */
+-      DI = 0xefc7;
+-      ES = 0xf000;
++      DI = read_word(0x00, 0x1e*4); // INT vector 0x1E
++      ES = read_word(0x00, 0x1e*4+2);
+       CLEAR_CF(); // success
+       /* disk status not changed upon success */
+       return;
+@@ -7880,7 +7868,7 @@
+   mov  al, #0x02
+   out  #0x0a, al   ;; clear DMA-1 channel 2 mask bit
+-  SET_INT_VECTOR(0x1E, #0xF000, #diskette_param_table)
++  SET_INT_VECTOR(0x1E, #0xF000, #diskette_param_table2)
+   SET_INT_VECTOR(0x40, #0xF000, #int13_diskette)
+   SET_INT_VECTOR(0x0E, #0xF000, #int0e_handler) ;; IRQ 6
+@@ -8344,6 +8332,19 @@
+   pop   ax
+   iret
++
++;--------------------
++#if BX_APM
++use32 386
++#define APM_PROT32
++#include "apmbios.S"
++use16 386
++
++#define APM_REAL
++#include "apmbios.S"
++
++#endif
++
+ ;--------------------
+ #if BX_PCIBIOS
+ use32 386
+@@ -9515,6 +9516,26 @@
+   pop  ds
+   iret
++diskette_param_table2:
++;;  New diskette parameter table adding 3 parameters from IBM
++;;  Since no provisions are made for multiple drive types, most
++;;  values in this table are ignored.  I set parameters for 1.44M
++;;  floppy here
++db  0xAF
++db  0x02 ;; head load time 0000001, DMA used
++db  0x25
++db  0x02
++db    18
++db  0x1B
++db  0xFF
++db  0x6C
++db  0xF6
++db  0x0F
++db  0x08
++db    79 ;; maximum track
++db     0 ;; data transfer rate
++db     4 ;; drive type in cmos
++
+ .org 0xf045 ; INT 10 Functions 0-Fh Entry Point
+   HALT(__LINE__)
+   iret
+@@ -9560,6 +9581,10 @@
+ .org 0xf859 ; INT 15h System Services Entry Point
+ int15_handler:
+   pushf
++#if BX_APM
++  cmp ah, #0x53
++  je apm_call
++#endif
+   push  ds
+   push  es
+   pushad
+@@ -9570,6 +9595,10 @@
+   popf
+   //JMPL(iret_modify_cf)
+   jmp iret_modify_cf
++#if BX_APM
++apm_call:
++  jmp _apmreal_entry
++#endif
+ ;; Protected mode IDT descriptor
+ ;;
diff --git a/tools/ioemu/pc-bios/linux_boot.S b/tools/ioemu/pc-bios/linux_boot.S
new file mode 100644 (file)
index 0000000..22fcd4b
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * QEMU Boot sector to launch a preloaded Linux kernel
+ * Copyright (c) 2004 Fabrice Bellard
+ */
+
+#define LOAD_SEG 0x9000
+        
+.code16        
+.text
+       .globl  _start
+
+_start:
+        cli
+        cld
+        mov $LOAD_SEG, %ax
+        mov %ax, %ds
+        mov %ax, %es
+        mov %ax, %fs
+        mov %ax, %gs
+        mov %ax, %ss
+        mov $0x8ffe, %sp
+        ljmp $LOAD_SEG + 0x20, $0
+
+1:              
+        .fill 510 - (1b - _start), 1, 0
+
+        /* boot sector signature */
+        .byte 0x55
+        .byte 0xaa
diff --git a/tools/ioemu/pc-bios/linux_boot.bin b/tools/ioemu/pc-bios/linux_boot.bin
new file mode 100644 (file)
index 0000000..80f7b5f
Binary files /dev/null and b/tools/ioemu/pc-bios/linux_boot.bin differ
diff --git a/tools/ioemu/pc-bios/ppc_rom.bin b/tools/ioemu/pc-bios/ppc_rom.bin
new file mode 100644 (file)
index 0000000..d882dee
Binary files /dev/null and b/tools/ioemu/pc-bios/ppc_rom.bin differ
diff --git a/tools/ioemu/pc-bios/proll.bin b/tools/ioemu/pc-bios/proll.bin
new file mode 100644 (file)
index 0000000..0489cc2
Binary files /dev/null and b/tools/ioemu/pc-bios/proll.bin differ
diff --git a/tools/ioemu/pc-bios/proll.patch b/tools/ioemu/pc-bios/proll.patch
new file mode 100644 (file)
index 0000000..b0860e2
--- /dev/null
@@ -0,0 +1,50 @@
+diff -ru proll_18.orig/mrcoffee/main.c proll_18/mrcoffee/main.c
+--- proll_18.orig/mrcoffee/main.c      2002-09-13 16:16:59.000000000 +0200
++++ proll_18/mrcoffee/main.c   2004-09-26 11:52:23.000000000 +0200
+@@ -101,6 +101,7 @@
+       le_probe();
+       init_net();
++#ifdef ORIG
+ #if 0 /* RARP */
+       if (rarp() != 0) fatal();
+       /* printrarp(); */
+@@ -117,13 +118,20 @@
+       xtoa(myipaddr, fname, 8);
+       if (load(boot_rec.bp_siaddr, fname) != 0) fatal();
+ #endif
++#endif
+       romvec = init_openprom(bb.nbanks, bb.bankv, hiphybas);
+       printk("Memory used: virt 0x%x:0x%x[%dK] iomap 0x%x:0x%x\n",
+           PROLBASE, (int)cmem.curp, ((unsigned) cmem.curp - PROLBASE)/1024,
+           (int)cio.start, (int)cio.curp);
++#ifdef ORIG
+       set_timeout(5);  while (!chk_timeout()) { }  /* P3: let me read */
++#else
++      printk("loading kernel:");
++      i = ld_bypass(0x20000000);
++      printk(" done, size %d\n", i);
++#endif
+       {
+               void (*entry)(void *, int) = (void (*)(void*, int)) LOADBASE;
+diff -ru proll_18.orig/mrcoffee/openprom.c proll_18/mrcoffee/openprom.c
+--- proll_18.orig/mrcoffee/openprom.c  2002-09-13 16:17:03.000000000 +0200
++++ proll_18/mrcoffee/openprom.c       2004-09-21 21:27:16.000000000 +0200
+@@ -144,10 +144,14 @@
+ };
+ static int cpu_nctx = NCTX_SWIFT;
++static int cpu_cache_line_size = 0x20;
++static int cpu_cache_nlines = 0x200;
+ static struct property propv_cpu[] = {
+       {"name",        "STP1012PGA", sizeof("STP1012PGA") },
+       {"device_type", "cpu", 4 },
+       {"mmu-nctx",    (char*)&cpu_nctx, sizeof(int)},
++      {"cache-line-size",     (char*)&cpu_cache_line_size, sizeof(int)},
++      {"cache-nlines",        (char*)&cpu_cache_nlines, sizeof(int)},
+       {NULL, NULL, -1}
+ };
diff --git a/tools/ioemu/pc-bios/vgabios-cirrus.bin b/tools/ioemu/pc-bios/vgabios-cirrus.bin
new file mode 100644 (file)
index 0000000..4e3c829
Binary files /dev/null and b/tools/ioemu/pc-bios/vgabios-cirrus.bin differ
diff --git a/tools/ioemu/pc-bios/vgabios.bin b/tools/ioemu/pc-bios/vgabios.bin
new file mode 100644 (file)
index 0000000..ed31b12
Binary files /dev/null and b/tools/ioemu/pc-bios/vgabios.bin differ
diff --git a/tools/ioemu/qemu-binfmt-conf.sh b/tools/ioemu/qemu-binfmt-conf.sh
new file mode 100644 (file)
index 0000000..e5acc47
--- /dev/null
@@ -0,0 +1,34 @@
+#!/bin/sh
+# enable automatic i386/ARM/SPARC/PPC program execution by the kernel
+
+# load the binfmt_misc module
+/sbin/modprobe binfmt_misc
+
+# probe cpu type
+cpu=`uname -m`
+case "$cpu" in
+  i386|i486|i586|i686|i86pc|BePC)
+    cpu="i386"
+  ;;
+  "Power Macintosh"|ppc|ppc64)
+    cpu="ppc"
+  ;;
+  armv4l)
+    cpu="arm"
+  ;;
+esac
+
+# register the interpreter for each cpu except for the native one
+if [ $cpu != "i386" ] ; then
+    echo ':i386:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfb\xff\xff\xff:/usr/local/bin/qemu-i386:' > /proc/sys/fs/binfmt_misc/register
+    echo ':i486:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfb\xff\xff\xff:/usr/local/bin/qemu-i386:' > /proc/sys/fs/binfmt_misc/register
+fi
+if [ $cpu != "arm" ] ; then
+    echo   ':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfb\xff\xff\xff:/usr/local/bin/qemu-arm:' > /proc/sys/fs/binfmt_misc/register
+fi
+if [ $cpu != "sparc" ] ; then
+    echo   ':sparc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfb\xff\xff\xff:/usr/local/bin/qemu-sparc:' > /proc/sys/fs/binfmt_misc/register
+fi
+if [ $cpu != "ppc" ] ; then
+    echo   ':ppc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfb\xff\xff\xff:/usr/local/bin/qemu-ppc:' > /proc/sys/fs/binfmt_misc/register
+fi
diff --git a/tools/ioemu/qemu-doc.html b/tools/ioemu/qemu-doc.html
new file mode 100644 (file)
index 0000000..2192530
--- /dev/null
@@ -0,0 +1,1793 @@
+<HTML>
+<HEAD>
+<!-- Created by texi2html 1.56k from qemu-doc.texi on 19 May 2005 -->
+
+<TITLE>QEMU CPU Emulator User Documentation</TITLE>
+</HEAD>
+<BODY>
+<H1>QEMU CPU Emulator User Documentation</H1>
+<P>
+<P><HR><P>
+<H1>Table of Contents</H1>
+<UL>
+<LI><A NAME="TOC1" HREF="qemu-doc.html#SEC1">1. Introduction</A>
+<UL>
+<LI><A NAME="TOC2" HREF="qemu-doc.html#SEC2">1.1 Features</A>
+</UL>
+<LI><A NAME="TOC3" HREF="qemu-doc.html#SEC3">2. Installation</A>
+<UL>
+<LI><A NAME="TOC4" HREF="qemu-doc.html#SEC4">2.1 Linux</A>
+<LI><A NAME="TOC5" HREF="qemu-doc.html#SEC5">2.2 Windows</A>
+<LI><A NAME="TOC6" HREF="qemu-doc.html#SEC6">2.3 Mac OS X</A>
+</UL>
+<LI><A NAME="TOC7" HREF="qemu-doc.html#SEC7">3. QEMU PC System emulator invocation</A>
+<UL>
+<LI><A NAME="TOC8" HREF="qemu-doc.html#SEC8">3.1 Introduction</A>
+<LI><A NAME="TOC9" HREF="qemu-doc.html#SEC9">3.2 Quick Start</A>
+<LI><A NAME="TOC10" HREF="qemu-doc.html#SEC10">3.3 Invocation</A>
+<LI><A NAME="TOC11" HREF="qemu-doc.html#SEC11">3.4 Keys</A>
+<LI><A NAME="TOC12" HREF="qemu-doc.html#SEC12">3.5 QEMU Monitor</A>
+<UL>
+<LI><A NAME="TOC13" HREF="qemu-doc.html#SEC13">3.5.1 Commands</A>
+<LI><A NAME="TOC14" HREF="qemu-doc.html#SEC14">3.5.2 Integer expressions</A>
+</UL>
+<LI><A NAME="TOC15" HREF="qemu-doc.html#SEC15">3.6 Disk Images</A>
+<UL>
+<LI><A NAME="TOC16" HREF="qemu-doc.html#SEC16">3.6.1 Raw disk images</A>
+<LI><A NAME="TOC17" HREF="qemu-doc.html#SEC17">3.6.2 Snapshot mode</A>
+<LI><A NAME="TOC18" HREF="qemu-doc.html#SEC18">3.6.3 Copy On Write disk images</A>
+<LI><A NAME="TOC19" HREF="qemu-doc.html#SEC19">3.6.4 Convert VMware disk images to raw disk images</A>
+</UL>
+<LI><A NAME="TOC20" HREF="qemu-doc.html#SEC20">3.7 Network emulation</A>
+<UL>
+<LI><A NAME="TOC21" HREF="qemu-doc.html#SEC21">3.7.1 Using tun/tap network interface</A>
+<LI><A NAME="TOC22" HREF="qemu-doc.html#SEC22">3.7.2 Using the user mode network stack</A>
+</UL>
+<LI><A NAME="TOC23" HREF="qemu-doc.html#SEC23">3.8 Direct Linux Boot</A>
+<LI><A NAME="TOC24" HREF="qemu-doc.html#SEC24">3.9 Linux Kernel Compilation</A>
+<LI><A NAME="TOC25" HREF="qemu-doc.html#SEC25">3.10 GDB usage</A>
+<LI><A NAME="TOC26" HREF="qemu-doc.html#SEC26">3.11 Target OS specific information</A>
+<UL>
+<LI><A NAME="TOC27" HREF="qemu-doc.html#SEC27">3.11.1 Linux</A>
+<LI><A NAME="TOC28" HREF="qemu-doc.html#SEC28">3.11.2 Windows</A>
+<UL>
+<LI><A NAME="TOC29" HREF="qemu-doc.html#SEC29">3.11.2.1 SVGA graphic modes support</A>
+<LI><A NAME="TOC30" HREF="qemu-doc.html#SEC30">3.11.2.2 CPU usage reduction</A>
+<LI><A NAME="TOC31" HREF="qemu-doc.html#SEC31">3.11.2.3 Windows 2000 disk full problems</A>
+<LI><A NAME="TOC32" HREF="qemu-doc.html#SEC32">3.11.2.4 Windows XP security problems</A>
+</UL>
+<LI><A NAME="TOC33" HREF="qemu-doc.html#SEC33">3.11.3 MS-DOS and FreeDOS</A>
+<UL>
+<LI><A NAME="TOC34" HREF="qemu-doc.html#SEC34">3.11.3.1 CPU usage reduction</A>
+</UL>
+</UL>
+</UL>
+<LI><A NAME="TOC35" HREF="qemu-doc.html#SEC35">4. QEMU PowerPC System emulator invocation</A>
+<LI><A NAME="TOC36" HREF="qemu-doc.html#SEC36">5. QEMU User space emulator invocation</A>
+<UL>
+<LI><A NAME="TOC37" HREF="qemu-doc.html#SEC37">5.1 Quick Start</A>
+<LI><A NAME="TOC38" HREF="qemu-doc.html#SEC38">5.2 Wine launch</A>
+<LI><A NAME="TOC39" HREF="qemu-doc.html#SEC39">5.3 Command line options</A>
+</UL>
+<LI><A NAME="TOC40" HREF="qemu-doc.html#SEC40">6. Compilation from the sources</A>
+<UL>
+<LI><A NAME="TOC41" HREF="qemu-doc.html#SEC41">6.1 Linux/BSD</A>
+<LI><A NAME="TOC42" HREF="qemu-doc.html#SEC42">6.2 Windows</A>
+<LI><A NAME="TOC43" HREF="qemu-doc.html#SEC43">6.3 Cross compilation for Windows with Linux</A>
+<LI><A NAME="TOC44" HREF="qemu-doc.html#SEC44">6.4 Mac OS X</A>
+</UL>
+</UL>
+<P><HR><P>
+
+<P>
+QEMU CPU Emulator User Documentation
+
+
+
+
+<H1><A NAME="SEC1" HREF="qemu-doc.html#TOC1">1. Introduction</A></H1>
+
+
+
+<H2><A NAME="SEC2" HREF="qemu-doc.html#TOC2">1.1 Features</A></H2>
+
+<P>
+QEMU is a FAST! processor emulator using dynamic translation to
+achieve good emulation speed.
+
+
+<P>
+QEMU has two operating modes:
+
+
+
+<UL>
+
+<LI>
+
+Full system emulation. In this mode, QEMU emulates a full system (for
+example a PC), including a processor and various peripherials. It can
+be used to launch different Operating Systems without rebooting the
+PC or to debug system code.
+
+<LI>
+
+User mode emulation (Linux host only). In this mode, QEMU can launch
+Linux processes compiled for one CPU on another CPU. It can be used to
+launch the Wine Windows API emulator (<A HREF="http://www.winehq.org">http://www.winehq.org</A>) or
+to ease cross-compilation and cross-debugging.
+
+</UL>
+
+<P>
+As QEMU requires no host kernel driver to run, it is very safe and
+easy to use.
+
+
+<P>
+For system emulation, the following hardware targets are supported:
+
+<UL>
+<LI>PC (x86 processor)
+
+<LI>PREP (PowerPC processor)
+
+<LI>PowerMac (PowerPC processor, in progress)
+
+</UL>
+
+<P>
+For user emulation, x86, PowerPC, ARM, and SPARC CPUs are supported.
+
+
+
+
+<H1><A NAME="SEC3" HREF="qemu-doc.html#TOC3">2. Installation</A></H1>
+
+<P>
+If you want to compile QEMU yourself, see section <A HREF="qemu-doc.html#SEC40">6. Compilation from the sources</A>.
+
+
+
+
+<H2><A NAME="SEC4" HREF="qemu-doc.html#TOC4">2.1 Linux</A></H2>
+
+<P>
+Download the binary distribution (<TT>`qemu-XXX-i386.tar.gz'</TT>) and
+untar it as root in <TT>`/'</TT>:
+
+
+
+<PRE>
+su
+cd /
+tar zxvf /tmp/qemu-XXX-i386.tar.gz
+</PRE>
+
+
+
+<H2><A NAME="SEC5" HREF="qemu-doc.html#TOC5">2.2 Windows</A></H2>
+
+<P>
+Download the experimental binary installer at
+<A HREF="http://www.freeoszoo.org/download.php">http://www.freeoszoo.org/download.php</A>.
+
+
+
+
+<H2><A NAME="SEC6" HREF="qemu-doc.html#TOC6">2.3 Mac OS X</A></H2>
+
+<P>
+Download the experimental binary installer at
+<A HREF="http://www.freeoszoo.org/download.php">http://www.freeoszoo.org/download.php</A>.
+
+
+
+
+<H1><A NAME="SEC7" HREF="qemu-doc.html#TOC7">3. QEMU PC System emulator invocation</A></H1>
+
+
+
+<H2><A NAME="SEC8" HREF="qemu-doc.html#TOC8">3.1 Introduction</A></H2>
+
+<P>
+The QEMU System emulator simulates a complete PC.
+
+
+<P>
+In order to meet specific user needs, two versions of QEMU are
+available:
+
+
+
+<OL>
+
+<LI>
+
+<CODE>qemu-fast</CODE> uses the host Memory Management Unit (MMU) to
+simulate the x86 MMU. It is <EM>fast</EM> but has limitations because
+the whole 4 GB address space cannot be used and some memory mapped
+peripherials cannot be emulated accurately yet. Therefore, a specific
+guest Linux kernel can be used (See section <A HREF="qemu-doc.html#SEC24">3.9 Linux Kernel Compilation</A>) as guest
+OS. 
+
+Moreover there is no separation between the host and target address
+spaces, so it offers no security (the target OS can modify the
+<CODE>qemu-fast</CODE> code by writing at the right addresses).
+
+<LI>
+
+<CODE>qemu</CODE> uses a software MMU. It is about <EM>two times slower</EM>
+but gives a more accurate emulation and a complete separation between
+the host and target address spaces.
+
+</OL>
+
+<P>
+QEMU emulates the following PC peripherials:
+
+
+
+<UL>
+<LI>
+
+i440FX host PCI bridge and PIIX3 PCI to ISA bridge
+<LI>
+
+Cirrus CLGD 5446 PCI VGA card or dummy VGA card with Bochs VESA
+extensions (hardware level, including all non standard modes).
+<LI>
+
+PS/2 mouse and keyboard
+<LI>
+
+2 PCI IDE interfaces with hard disk and CD-ROM support
+<LI>
+
+Floppy disk
+<LI>
+
+NE2000 PCI network adapters
+<LI>
+
+Serial ports
+<LI>
+
+Soundblaster 16 card
+</UL>
+
+<P>
+QEMU uses the PC BIOS from the Bochs project and the Plex86/Bochs LGPL
+VGA BIOS.
+
+
+
+
+<H2><A NAME="SEC9" HREF="qemu-doc.html#TOC9">3.2 Quick Start</A></H2>
+
+<P>
+Download and uncompress the linux image (<TT>`linux.img'</TT>) and type:
+
+
+
+<PRE>
+qemu linux.img
+</PRE>
+
+<P>
+Linux should boot and give you a prompt.
+
+
+
+
+<H2><A NAME="SEC10" HREF="qemu-doc.html#TOC10">3.3 Invocation</A></H2>
+
+
+<PRE>
+usage: qemu [options] [disk_image]
+</PRE>
+
+<P>
+<VAR>disk_image</VAR> is a raw hard disk image for IDE hard disk 0.
+
+
+<P>
+General options:
+<DL COMPACT>
+
+<DT>@option{-fda file}
+<DD>
+<DT>@option{-fdb file}
+<DD>
+Use <VAR>file</VAR> as floppy disk 0/1 image (See section <A HREF="qemu-doc.html#SEC15">3.6 Disk Images</A>). You can
+use the host floppy by using <TT>`/dev/fd0'</TT> as filename.
+
+<DT>@option{-hda file}
+<DD>
+<DT>@option{-hdb file}
+<DD>
+<DT>@option{-hdc file}
+<DD>
+<DT>@option{-hdd file}
+<DD>
+Use <VAR>file</VAR> as hard disk 0, 1, 2 or 3 image (See section <A HREF="qemu-doc.html#SEC15">3.6 Disk Images</A>).
+
+<DT>@option{-cdrom file}
+<DD>
+Use <VAR>file</VAR> as CD-ROM image (you cannot use @option{-hdc} and and
+@option{-cdrom} at the same time). You can use the host CD-ROM by
+using <TT>`/dev/cdrom'</TT> as filename.
+
+<DT>@option{-boot [a|c|d]}
+<DD>
+Boot on floppy (a), hard disk (c) or CD-ROM (d). Hard disk boot is
+the default.
+
+<DT>@option{-snapshot}
+<DD>
+Write to temporary files instead of disk image files. In this case,
+the raw disk image you use is not written back. You can however force
+the write back by pressing <KBD>C-a s</KBD> (See section <A HREF="qemu-doc.html#SEC15">3.6 Disk Images</A>). 
+
+<DT>@option{-m megs}
+<DD>
+Set virtual RAM size to <VAR>megs</VAR> megabytes. Default is 128 MB.
+
+<DT>@option{-nographic}
+<DD>
+Normally, QEMU uses SDL to display the VGA output. With this option,
+you can totally disable graphical output so that QEMU is a simple
+command line application. The emulated serial port is redirected on
+the console. Therefore, you can still use QEMU to debug a Linux kernel
+with a serial console.
+
+<DT>@option{-enable-audio}
+<DD>
+The SB16 emulation is disabled by default as it may give problems with
+Windows. You can enable it manually with this option.
+
+<DT>@option{-localtime}
+<DD>
+Set the real time clock to local time (the default is to UTC
+time). This option is needed to have correct date in MS-DOS or
+Windows.
+
+<DT>@option{-full-screen}
+<DD>
+Start in full screen.
+
+</DL>
+
+<P>
+Network options:
+
+
+<DL COMPACT>
+
+<DT>@option{-n script}
+<DD>
+Set TUN/TAP network init script [default=/etc/qemu-ifup]. This script
+is launched to configure the host network interface (usually tun0)
+corresponding to the virtual NE2000 card.
+
+<DT>@option{-macaddr addr}
+<DD>
+Set the mac address of the first interface (the format is
+aa:bb:cc:dd:ee:ff in hexa). The mac address is incremented for each
+new network interface.
+
+<DT>@option{-tun-fd fd}
+<DD>
+Assumes <VAR>fd</VAR> talks to a tap/tun host network interface and use
+it. Read <A HREF="http://bellard.org/qemu/tetrinet.html">http://bellard.org/qemu/tetrinet.html</A> to have an
+example of its use.
+
+<DT>@option{-user-net}
+<DD>
+Use the user mode network stack. This is the default if no tun/tap
+network init script is found.
+
+<DT>@option{-tftp prefix}
+<DD>
+When using the user mode network stack, activate a built-in TFTP
+server. All filenames beginning with <VAR>prefix</VAR> can be downloaded
+from the host to the guest using a TFTP client. The TFTP client on the
+guest must be configured in binary mode (use the command <CODE>bin</CODE> of
+the Unix TFTP client). The host IP address on the guest is as usual
+10.0.2.2.
+
+<DT>@option{-smb dir}
+<DD>
+When using the user mode network stack, activate a built-in SMB
+server so that Windows OSes can access to the host files in <TT>`dir'</TT>
+transparently.
+
+In the guest Windows OS, the line:
+
+<PRE>
+10.0.2.4 smbserver
+</PRE>
+
+must be added in the file <TT>`C:\WINDOWS\LMHOSTS'</TT> (for windows 9x/Me)
+or <TT>`C:\WINNT\SYSTEM32\DRIVERS\ETC\LMHOSTS'</TT> (Windows NT/2000).
+
+Then <TT>`dir'</TT> can be accessed in <TT>`\\smbserver\qemu'</TT>.
+
+Note that a SAMBA server must be installed on the host OS in
+<TT>`/usr/sbin/smbd'</TT>. QEMU was tested succesfully with smbd version
+2.2.7a from the Red Hat 9.
+
+<DT>@option{-redir [tcp|udp]:host-port:[guest-host]:guest-port}
+<DD>
+When using the user mode network stack, redirect incoming TCP or UDP
+connections to the host port <VAR>host-port</VAR> to the guest
+<VAR>guest-host</VAR> on guest port <VAR>guest-port</VAR>. If <VAR>guest-host</VAR>
+is not specified, its value is 10.0.2.15 (default address given by the
+built-in DHCP server).
+
+For example, to redirect host X11 connection from screen 1 to guest
+screen 0, use the following:
+
+
+<PRE>
+# on the host
+qemu -redir tcp:6001::6000 [...]
+# this host xterm should open in the guest X11 server
+xterm -display :1
+</PRE>
+
+To redirect telnet connections from host port 5555 to telnet port on
+the guest, use the following:
+
+
+<PRE>
+# on the host
+qemu -redir tcp:5555::23 [...]
+telnet localhost 5555
+</PRE>
+
+Then when you use on the host <CODE>telnet localhost 5555</CODE>, you
+connect to the guest telnet server.
+
+<DT>@option{-dummy-net}
+<DD>
+Use the dummy network stack: no packet will be received by the network
+cards.
+
+</DL>
+
+<P>
+Linux boot specific. When using this options, you can use a given
+Linux kernel without installing it in the disk image. It can be useful
+for easier testing of various kernels.
+
+
+<DL COMPACT>
+
+<DT>@option{-kernel bzImage}
+<DD>
+Use <VAR>bzImage</VAR> as kernel image.
+
+<DT>@option{-append cmdline}
+<DD>
+Use <VAR>cmdline</VAR> as kernel command line
+
+<DT>@option{-initrd file}
+<DD>
+Use <VAR>file</VAR> as initial ram disk.
+
+</DL>
+
+<P>
+Debug/Expert options:
+<DL COMPACT>
+
+<DT>@option{-serial dev}
+<DD>
+Redirect the virtual serial port to host device <VAR>dev</VAR>. Available
+devices are:
+<DL COMPACT>
+
+<DT><CODE>vc</CODE>
+<DD>
+Virtual console
+<DT><CODE>pty</CODE>
+<DD>
+[Linux only] Pseudo TTY (a new PTY is automatically allocated)
+<DT><CODE>null</CODE>
+<DD>
+void device
+<DT><CODE>stdio</CODE>
+<DD>
+[Unix only] standard input/output
+</DL>
+The default device is <CODE>vc</CODE> in graphical mode and <CODE>stdio</CODE> in
+non graphical mode.
+
+This option can be used several times to simulate up to 4 serials
+ports.
+
+<DT>@option{-monitor dev}
+<DD>
+Redirect the monitor to host device <VAR>dev</VAR> (same devices as the
+serial port).
+The default device is <CODE>vc</CODE> in graphical mode and <CODE>stdio</CODE> in
+non graphical mode.
+
+<DT>@option{-s}
+<DD>
+Wait gdb connection to port 1234 (See section <A HREF="qemu-doc.html#SEC25">3.10 GDB usage</A>). 
+<DT>@option{-p port}
+<DD>
+Change gdb connection port.
+<DT>@option{-S}
+<DD>
+Do not start CPU at startup (you must type 'c' in the monitor).
+<DT>@option{-d}
+<DD>
+Output log in /tmp/qemu.log
+<DT>@option{-isa}
+<DD>
+Simulate an ISA-only system (default is PCI system).
+<DT>@option{-std-vga}
+<DD>
+Simulate a standard VGA card with Bochs VBE extensions (default is
+Cirrus Logic GD5446 PCI VGA)
+<DT>@option{-loadvm file}
+<DD>
+Start right away with a saved state (<CODE>loadvm</CODE> in monitor)
+</DL>
+
+
+
+<H2><A NAME="SEC11" HREF="qemu-doc.html#TOC11">3.4 Keys</A></H2>
+
+<P>
+During the graphical emulation, you can use the following keys:
+<DL COMPACT>
+
+<DT><KBD>Ctrl-Alt-f</KBD>
+<DD>
+Toggle full screen
+
+<DT><KBD>Ctrl-Alt-n</KBD>
+<DD>
+Switch to virtual console 'n'. Standard console mappings are:
+<DL COMPACT>
+
+<DT><EM>1</EM>
+<DD>
+Target system display
+<DT><EM>2</EM>
+<DD>
+Monitor
+<DT><EM>3</EM>
+<DD>
+Serial port
+</DL>
+
+<DT><KBD>Ctrl-Alt</KBD>
+<DD>
+Toggle mouse and keyboard grab.
+</DL>
+
+<P>
+In the virtual consoles, you can use <KBD>Ctrl-Up</KBD>, <KBD>Ctrl-Down</KBD>,
+<KBD>Ctrl-PageUp</KBD> and <KBD>Ctrl-PageDown</KBD> to move in the back log.
+
+
+<P>
+During emulation, if you are using the @option{-nographic} option, use
+<KBD>Ctrl-a h</KBD> to get terminal commands:
+
+
+<DL COMPACT>
+
+<DT><KBD>Ctrl-a h</KBD>
+<DD>
+Print this help
+<DT><KBD>Ctrl-a x</KBD>
+<DD>
+Exit emulatior
+<DT><KBD>Ctrl-a s</KBD>
+<DD>
+Save disk data back to file (if -snapshot)
+<DT><KBD>Ctrl-a b</KBD>
+<DD>
+Send break (magic sysrq in Linux)
+<DT><KBD>Ctrl-a c</KBD>
+<DD>
+Switch between console and monitor
+<DT><KBD>Ctrl-a Ctrl-a</KBD>
+<DD>
+Send Ctrl-a
+</DL>
+
+
+
+<H2><A NAME="SEC12" HREF="qemu-doc.html#TOC12">3.5 QEMU Monitor</A></H2>
+
+<P>
+The QEMU monitor is used to give complex commands to the QEMU
+emulator. You can use it to:
+
+
+
+<UL>
+
+<LI>
+
+Remove or insert removable medias images
+(such as CD-ROM or floppies)
+
+<LI>
+
+Freeze/unfreeze the Virtual Machine (VM) and save or restore its state
+from a disk file.
+
+<LI>Inspect the VM state without an external debugger.
+
+</UL>
+
+
+
+<H3><A NAME="SEC13" HREF="qemu-doc.html#TOC13">3.5.1 Commands</A></H3>
+
+<P>
+The following commands are available:
+
+
+<DL COMPACT>
+
+<DT>@option{help or ? [cmd]}
+<DD>
+Show the help for all commands or just for command <VAR>cmd</VAR>.
+
+<DT>@option{commit}
+<DD>
+Commit changes to the disk images (if -snapshot is used)
+
+<DT>@option{info subcommand}
+<DD>
+show various information about the system state
+
+<DL COMPACT>
+
+<DT>@option{info network}
+<DD>
+show the network state
+<DT>@option{info block}
+<DD>
+show the block devices
+<DT>@option{info registers}
+<DD>
+show the cpu registers
+<DT>@option{info history}
+<DD>
+show the command line history
+</DL>
+
+<DT>@option{q or quit}
+<DD>
+Quit the emulator.
+
+<DT>@option{eject [-f] device}
+<DD>
+Eject a removable media (use -f to force it).
+
+<DT>@option{change device filename}
+<DD>
+Change a removable media.
+
+<DT>@option{screendump filename}
+<DD>
+Save screen into PPM image <VAR>filename</VAR>.
+
+<DT>@option{log item1[,...]}
+<DD>
+Activate logging of the specified items to <TT>`/tmp/qemu.log'</TT>.
+
+<DT>@option{savevm filename}
+<DD>
+Save the whole virtual machine state to <VAR>filename</VAR>.
+
+<DT>@option{loadvm filename}
+<DD>
+Restore the whole virtual machine state from <VAR>filename</VAR>.
+
+<DT>@option{stop}
+<DD>
+Stop emulation.
+
+<DT>@option{c or cont}
+<DD>
+Resume emulation.
+
+<DT>@option{gdbserver [port]}
+<DD>
+Start gdbserver session (default port=1234)
+
+<DT>@option{x/fmt addr}
+<DD>
+Virtual memory dump starting at <VAR>addr</VAR>.
+
+<DT>@option{xp /fmt addr}
+<DD>
+Physical memory dump starting at <VAR>addr</VAR>.
+
+<VAR>fmt</VAR> is a format which tells the command how to format the
+data. Its syntax is: @option{/{count}{format}{size}}
+
+<DL COMPACT>
+
+<DT><VAR>count</VAR>
+<DD>
+is the number of items to be dumped.
+
+<DT><VAR>format</VAR>
+<DD>
+can be x (hexa), d (signed decimal), u (unsigned decimal), o (octal),
+c (char) or i (asm instruction).
+
+<DT><VAR>size</VAR>
+<DD>
+can be b (8 bits), h (16 bits), w (32 bits) or g (64 bits). On x86,
+<CODE>h</CODE> or <CODE>w</CODE> can be specified with the <CODE>i</CODE> format to
+respectively select 16 or 32 bit code instruction size.
+
+</DL>
+
+Examples: 
+
+<UL>
+<LI>
+
+Dump 10 instructions at the current instruction pointer:
+
+<PRE>
+(qemu) x/10i $eip
+0x90107063:  ret
+0x90107064:  sti
+0x90107065:  lea    0x0(%esi,1),%esi
+0x90107069:  lea    0x0(%edi,1),%edi
+0x90107070:  ret
+0x90107071:  jmp    0x90107080
+0x90107073:  nop
+0x90107074:  nop
+0x90107075:  nop
+0x90107076:  nop
+</PRE>
+
+<LI>
+
+Dump 80 16 bit values at the start of the video memory.
+
+<PRE>
+(qemu) xp/80hx 0xb8000
+0x000b8000: 0x0b50 0x0b6c 0x0b65 0x0b78 0x0b38 0x0b36 0x0b2f 0x0b42
+0x000b8010: 0x0b6f 0x0b63 0x0b68 0x0b73 0x0b20 0x0b56 0x0b47 0x0b41
+0x000b8020: 0x0b42 0x0b69 0x0b6f 0x0b73 0x0b20 0x0b63 0x0b75 0x0b72
+0x000b8030: 0x0b72 0x0b65 0x0b6e 0x0b74 0x0b2d 0x0b63 0x0b76 0x0b73
+0x000b8040: 0x0b20 0x0b30 0x0b35 0x0b20 0x0b4e 0x0b6f 0x0b76 0x0b20
+0x000b8050: 0x0b32 0x0b30 0x0b30 0x0b33 0x0720 0x0720 0x0720 0x0720
+0x000b8060: 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720
+0x000b8070: 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720
+0x000b8080: 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720
+0x000b8090: 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720
+</PRE>
+
+</UL>
+
+<DT>@option{p or print/fmt expr}
+<DD>
+Print expression value. Only the <VAR>format</VAR> part of <VAR>fmt</VAR> is
+used.
+
+<DT>@option{sendkey keys}
+<DD>
+Send <VAR>keys</VAR> to the emulator. Use <CODE>-</CODE> to press several keys
+simultaneously. Example:
+
+<PRE>
+sendkey ctrl-alt-f1
+</PRE>
+
+This command is useful to send keys that your graphical user interface
+intercepts at low level, such as <CODE>ctrl-alt-f1</CODE> in X Window.
+
+<DT>@option{system_reset}
+<DD>
+Reset the system.
+
+</DL>
+
+
+
+<H3><A NAME="SEC14" HREF="qemu-doc.html#TOC14">3.5.2 Integer expressions</A></H3>
+
+<P>
+The monitor understands integers expressions for every integer
+argument. You can use register names to get the value of specifics
+CPU registers by prefixing them with <EM>$</EM>.
+
+
+
+
+<H2><A NAME="SEC15" HREF="qemu-doc.html#TOC15">3.6 Disk Images</A></H2>
+
+
+
+<H3><A NAME="SEC16" HREF="qemu-doc.html#TOC16">3.6.1 Raw disk images</A></H3>
+
+<P>
+The disk images can simply be raw images of the hard disk. You can
+create them with the command:
+
+<PRE>
+dd of=myimage bs=1024 seek=mysize count=0
+</PRE>
+
+<P>
+where <VAR>myimage</VAR> is the image filename and <VAR>mysize</VAR> is its size
+in kilobytes.
+
+
+
+
+<H3><A NAME="SEC17" HREF="qemu-doc.html#TOC17">3.6.2 Snapshot mode</A></H3>
+
+<P>
+If you use the option @option{-snapshot}, all disk images are
+considered as read only. When sectors in written, they are written in
+a temporary file created in <TT>`/tmp'</TT>. You can however force the
+write back to the raw disk images by pressing <KBD>C-a s</KBD>.
+
+
+<P>
+NOTE: The snapshot mode only works with raw disk images.
+
+
+
+
+<H3><A NAME="SEC18" HREF="qemu-doc.html#TOC18">3.6.3 Copy On Write disk images</A></H3>
+
+<P>
+QEMU also supports user mode Linux
+(<A HREF="http://user-mode-linux.sourceforge.net/">http://user-mode-linux.sourceforge.net/</A>) Copy On Write (COW)
+disk images. The COW disk images are much smaller than normal images
+as they store only modified sectors. They also permit the use of the
+same disk image template for many users.
+
+
+<P>
+To create a COW disk images, use the command:
+
+
+
+<PRE>
+qemu-mkcow -f myrawimage.bin mycowimage.cow
+</PRE>
+
+<P>
+<TT>`myrawimage.bin'</TT> is a raw image you want to use as original disk
+image. It will never be written to.
+
+
+<P>
+<TT>`mycowimage.cow'</TT> is the COW disk image which is created by
+<CODE>qemu-mkcow</CODE>. You can use it directly with the @option{-hdx}
+options. You must not modify the original raw disk image if you use
+COW images, as COW images only store the modified sectors from the raw
+disk image. QEMU stores the original raw disk image name and its
+modified time in the COW disk image so that chances of mistakes are
+reduced.
+
+
+<P>
+If the raw disk image is not read-only, by pressing <KBD>C-a s</KBD> you
+can flush the COW disk image back into the raw disk image, as in
+snapshot mode.
+
+
+<P>
+COW disk images can also be created without a corresponding raw disk
+image. It is useful to have a big initial virtual disk image without
+using much disk space. Use:
+
+
+
+<PRE>
+qemu-mkcow mycowimage.cow 1024
+</PRE>
+
+<P>
+to create a 1 gigabyte empty COW disk image.
+
+
+<P>
+NOTES: 
+
+<OL>
+<LI>
+
+COW disk images must be created on file systems supporting
+<EM>holes</EM> such as ext2 or ext3.
+<LI>
+
+Since holes are used, the displayed size of the COW disk image is not
+the real one. To know it, use the <CODE>ls -ls</CODE> command.
+</OL>
+
+
+
+<H3><A NAME="SEC19" HREF="qemu-doc.html#TOC19">3.6.4 Convert VMware disk images to raw disk images</A></H3>
+
+<P>
+You can use the tool <TT>`vmdk2raw'</TT> to convert VMware disk images to
+raw disk images directly usable by QEMU. The syntax is:
+
+<PRE>
+vmdk2raw vmware_image output_image
+</PRE>
+
+
+
+<H2><A NAME="SEC20" HREF="qemu-doc.html#TOC20">3.7 Network emulation</A></H2>
+
+<P>
+QEMU simulates up to 6 networks cards (NE2000 boards). Each card can
+be connected to a specific host network interface.
+
+
+
+
+<H3><A NAME="SEC21" HREF="qemu-doc.html#TOC21">3.7.1 Using tun/tap network interface</A></H3>
+
+<P>
+This is the standard way to emulate network. QEMU adds a virtual
+network device on your host (called <CODE>tun0</CODE>), and you can then
+configure it as if it was a real ethernet card.
+
+
+<P>
+As an example, you can download the <TT>`linux-test-xxx.tar.gz'</TT>
+archive and copy the script <TT>`qemu-ifup'</TT> in <TT>`/etc'</TT> and
+configure properly <CODE>sudo</CODE> so that the command <CODE>ifconfig</CODE>
+contained in <TT>`qemu-ifup'</TT> can be executed as root. You must verify
+that your host kernel supports the TUN/TAP network interfaces: the
+device <TT>`/dev/net/tun'</TT> must be present.
+
+
+<P>
+See section <A HREF="qemu-doc.html#SEC23">3.8 Direct Linux Boot</A> to have an example of network use with a
+Linux distribution.
+
+
+
+
+<H3><A NAME="SEC22" HREF="qemu-doc.html#TOC22">3.7.2 Using the user mode network stack</A></H3>
+
+<P>
+By using the option @option{-user-net} or if you have no tun/tap init
+script, QEMU uses a completely user mode network stack (you don't need
+root priviledge to use the virtual network). The virtual network
+configuration is the following:
+
+
+
+<PRE>
+
+QEMU Virtual Machine    &#60;------&#62;  Firewall/DHCP server &#60;-----&#62; Internet
+     (10.0.2.x)            |          (10.0.2.2)
+                           |
+                           ----&#62;  DNS server (10.0.2.3)
+                           |     
+                           ----&#62;  SMB server (10.0.2.4)
+</PRE>
+
+<P>
+The QEMU VM behaves as if it was behind a firewall which blocks all
+incoming connections. You can use a DHCP client to automatically
+configure the network in the QEMU VM.
+
+
+<P>
+In order to check that the user mode network is working, you can ping
+the address 10.0.2.2 and verify that you got an address in the range
+10.0.2.x from the QEMU virtual DHCP server.
+
+
+<P>
+Note that <CODE>ping</CODE> is not supported reliably to the internet as it
+would require root priviledges. It means you can only ping the local
+router (10.0.2.2).
+
+
+<P>
+When using the built-in TFTP server, the router is also the TFTP
+server.
+
+
+<P>
+When using the @option{-redir} option, TCP or UDP connections can be
+redirected from the host to the guest. It allows for example to
+redirect X11, telnet or SSH connections.
+
+
+
+
+<H2><A NAME="SEC23" HREF="qemu-doc.html#TOC23">3.8 Direct Linux Boot</A></H2>
+
+<P>
+This section explains how to launch a Linux kernel inside QEMU without
+having to make a full bootable image. It is very useful for fast Linux
+kernel testing. The QEMU network configuration is also explained.
+
+
+
+<OL>
+<LI>
+
+Download the archive <TT>`linux-test-xxx.tar.gz'</TT> containing a Linux
+kernel and a disk image. 
+
+<LI>Optional: If you want network support (for example to launch X11 examples), you
+
+must copy the script <TT>`qemu-ifup'</TT> in <TT>`/etc'</TT> and configure
+properly <CODE>sudo</CODE> so that the command <CODE>ifconfig</CODE> contained in
+<TT>`qemu-ifup'</TT> can be executed as root. You must verify that your host
+kernel supports the TUN/TAP network interfaces: the device
+<TT>`/dev/net/tun'</TT> must be present.
+
+When network is enabled, there is a virtual network connection between
+the host kernel and the emulated kernel. The emulated kernel is seen
+from the host kernel at IP address 172.20.0.2 and the host kernel is
+seen from the emulated kernel at IP address 172.20.0.1.
+
+<LI>Launch <CODE>qemu.sh</CODE>. You should have the following output:
+
+
+<PRE>
+&#62; ./qemu.sh 
+Connected to host network interface: tun0
+Linux version 2.4.21 (bellard@voyager.localdomain) (gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)) #5 Tue Nov 11 18:18:53 CET 2003
+BIOS-provided physical RAM map:
+ BIOS-e801: 0000000000000000 - 000000000009f000 (usable)
+ BIOS-e801: 0000000000100000 - 0000000002000000 (usable)
+32MB LOWMEM available.
+On node 0 totalpages: 8192
+zone(0): 4096 pages.
+zone(1): 4096 pages.
+zone(2): 0 pages.
+Kernel command line: root=/dev/hda sb=0x220,5,1,5 ide2=noprobe ide3=noprobe ide4=noprobe ide5=noprobe console=ttyS0
+ide_setup: ide2=noprobe
+ide_setup: ide3=noprobe
+ide_setup: ide4=noprobe
+ide_setup: ide5=noprobe
+Initializing CPU#0
+Detected 2399.621 MHz processor.
+Console: colour EGA 80x25
+Calibrating delay loop... 4744.80 BogoMIPS
+Memory: 28872k/32768k available (1210k kernel code, 3508k reserved, 266k data, 64k init, 0k highmem)
+Dentry cache hash table entries: 4096 (order: 3, 32768 bytes)
+Inode cache hash table entries: 2048 (order: 2, 16384 bytes)
+Mount cache hash table entries: 512 (order: 0, 4096 bytes)
+Buffer-cache hash table entries: 1024 (order: 0, 4096 bytes)
+Page-cache hash table entries: 8192 (order: 3, 32768 bytes)
+CPU: Intel Pentium Pro stepping 03
+Checking 'hlt' instruction... OK.
+POSIX conformance testing by UNIFIX
+Linux NET4.0 for Linux 2.4
+Based upon Swansea University Computer Society NET3.039
+Initializing RT netlink socket
+apm: BIOS not found.
+Starting kswapd
+Journalled Block Device driver loaded
+Detected PS/2 Mouse Port.
+pty: 256 Unix98 ptys configured
+Serial driver version 5.05c (2001-07-08) with no serial options enabled
+ttyS00 at 0x03f8 (irq = 4) is a 16450
+ne.c:v1.10 9/23/94 Donald Becker (becker@scyld.com)
+Last modified Nov 1, 2000 by Paul Gortmaker
+NE*000 ethercard probe at 0x300: 52 54 00 12 34 56
+eth0: NE2000 found at 0x300, using IRQ 9.
+RAMDISK driver initialized: 16 RAM disks of 4096K size 1024 blocksize
+Uniform Multi-Platform E-IDE driver Revision: 7.00beta4-2.4
+ide: Assuming 50MHz system bus speed for PIO modes; override with idebus=xx
+hda: QEMU HARDDISK, ATA DISK drive
+ide0 at 0x1f0-0x1f7,0x3f6 on irq 14
+hda: attached ide-disk driver.
+hda: 20480 sectors (10 MB) w/256KiB Cache, CHS=20/16/63
+Partition check:
+ hda:
+Soundblaster audio driver Copyright (C) by Hannu Savolainen 1993-1996
+NET4: Linux TCP/IP 1.0 for NET4.0
+IP Protocols: ICMP, UDP, TCP, IGMP
+IP: routing cache hash table of 512 buckets, 4Kbytes
+TCP: Hash tables configured (established 2048 bind 4096)
+NET4: Unix domain sockets 1.0/SMP for Linux NET4.0.
+EXT2-fs warning: mounting unchecked fs, running e2fsck is recommended
+VFS: Mounted root (ext2 filesystem).
+Freeing unused kernel memory: 64k freed
+Linux version 2.4.21 (bellard@voyager.localdomain) (gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)) #5 Tue Nov 11 18:18:53 CET 2003
+QEMU Linux test distribution (based on Redhat 9)
+Type 'exit' to halt the system
+sh-2.05b# 
+</PRE>
+
+<LI>
+
+Then you can play with the kernel inside the virtual serial console. You
+can launch <CODE>ls</CODE> for example. Type <KBD>Ctrl-a h</KBD> to have an help
+about the keys you can type inside the virtual serial console. In
+particular, use <KBD>Ctrl-a x</KBD> to exit QEMU and use <KBD>Ctrl-a b</KBD> as
+the Magic SysRq key.
+
+<LI>
+
+If the network is enabled, launch the script <TT>`/etc/linuxrc'</TT> in the
+emulator (don't forget the leading dot):
+
+<PRE>
+. /etc/linuxrc
+</PRE>
+
+Then enable X11 connections on your PC from the emulated Linux: 
+
+<PRE>
+xhost +172.20.0.2
+</PRE>
+
+You can now launch <TT>`xterm'</TT> or <TT>`xlogo'</TT> and verify that you have
+a real Virtual Linux system !
+
+</OL>
+
+<P>
+NOTES:
+
+<OL>
+<LI>
+
+A 2.5.74 kernel is also included in the archive. Just
+replace the bzImage in qemu.sh to try it.
+
+<LI>
+
+qemu-fast creates a temporary file in <VAR>$QEMU_TMPDIR</VAR> (<TT>`/tmp'</TT> is the
+default) containing all the simulated PC memory. If possible, try to use
+a temporary directory using the tmpfs filesystem to avoid too many
+unnecessary disk accesses.
+
+<LI>
+
+In order to exit cleanly from qemu, you can do a <EM>shutdown</EM> inside
+qemu. qemu will automatically exit when the Linux shutdown is done.
+
+<LI>
+
+You can boot slightly faster by disabling the probe of non present IDE
+interfaces. To do so, add the following options on the kernel command
+line:
+
+<PRE>
+ide1=noprobe ide2=noprobe ide3=noprobe ide4=noprobe ide5=noprobe
+</PRE>
+
+<LI>
+
+The example disk image is a modified version of the one made by Kevin
+Lawton for the plex86 Project (<A HREF="www.plex86.org">www.plex86.org</A>).
+
+</OL>
+
+
+
+<H2><A NAME="SEC24" HREF="qemu-doc.html#TOC24">3.9 Linux Kernel Compilation</A></H2>
+
+<P>
+You can use any linux kernel with QEMU. However, if you want to use
+<CODE>qemu-fast</CODE> to get maximum performances, you must use a modified
+guest kernel. If you are using a 2.6 guest kernel, you can use
+directly the patch <TT>`linux-2.6-qemu-fast.patch'</TT> made by Rusty
+Russel available in the QEMU source archive. Otherwise, you can make the
+following changes <EM>by hand</EM> to the Linux kernel:
+
+
+
+<OL>
+<LI>
+
+The kernel must be mapped at 0x90000000 (the default is
+0xc0000000). You must modify only two lines in the kernel source:
+
+In <TT>`include/asm/page.h'</TT>, replace
+
+<PRE>
+#define __PAGE_OFFSET           (0xc0000000)
+</PRE>
+
+by
+
+<PRE>
+#define __PAGE_OFFSET           (0x90000000)
+</PRE>
+
+And in <TT>`arch/i386/vmlinux.lds'</TT>, replace
+
+<PRE>
+  . = 0xc0000000 + 0x100000;
+</PRE>
+
+by 
+
+<PRE>
+  . = 0x90000000 + 0x100000;
+</PRE>
+
+<LI>
+
+If you want to enable SMP (Symmetric Multi-Processing) support, you
+must make the following change in <TT>`include/asm/fixmap.h'</TT>. Replace
+
+<PRE>
+#define FIXADDR_TOP    (0xffffX000UL)
+</PRE>
+
+by 
+
+<PRE>
+#define FIXADDR_TOP    (0xa7ffX000UL)
+</PRE>
+
+(X is 'e' or 'f' depending on the kernel version). Although you can
+use an SMP kernel with QEMU, it only supports one CPU.
+
+<LI>
+
+If you are not using a 2.6 kernel as host kernel but if you use a target
+2.6 kernel, you must also ensure that the 'HZ' define is set to 100
+(1000 is the default) as QEMU cannot currently emulate timers at
+frequencies greater than 100 Hz on host Linux systems &#60; 2.6. In
+<TT>`include/asm/param.h'</TT>, replace:
+
+
+<PRE>
+# define HZ            1000            /* Internal kernel timer frequency */
+</PRE>
+
+by
+
+<PRE>
+# define HZ            100             /* Internal kernel timer frequency */
+</PRE>
+
+</OL>
+
+<P>
+The file config-2.x.x gives the configuration of the example kernels.
+
+
+<P>
+Just type
+
+<PRE>
+make bzImage
+</PRE>
+
+<P>
+As you would do to make a real kernel. Then you can use with QEMU
+exactly the same kernel as you would boot on your PC (in
+<TT>`arch/i386/boot/bzImage'</TT>).
+
+
+
+
+<H2><A NAME="SEC25" HREF="qemu-doc.html#TOC25">3.10 GDB usage</A></H2>
+
+<P>
+QEMU has a primitive support to work with gdb, so that you can do
+'Ctrl-C' while the virtual machine is running and inspect its state.
+
+
+<P>
+In order to use gdb, launch qemu with the '-s' option. It will wait for a
+gdb connection:
+
+<PRE>
+&#62; qemu -s -kernel arch/i386/boot/bzImage -hda root-2.4.20.img -append "root=/dev/hda"
+Connected to host network interface: tun0
+Waiting gdb connection on port 1234
+</PRE>
+
+<P>
+Then launch gdb on the 'vmlinux' executable:
+
+<PRE>
+&#62; gdb vmlinux
+</PRE>
+
+<P>
+In gdb, connect to QEMU:
+
+<PRE>
+(gdb) target remote localhost:1234
+</PRE>
+
+<P>
+Then you can use gdb normally. For example, type 'c' to launch the kernel:
+
+<PRE>
+(gdb) c
+</PRE>
+
+<P>
+Here are some useful tips in order to use gdb on system code:
+
+
+
+<OL>
+<LI>
+
+Use <CODE>info reg</CODE> to display all the CPU registers.
+<LI>
+
+Use <CODE>x/10i $eip</CODE> to display the code at the PC position.
+<LI>
+
+Use <CODE>set architecture i8086</CODE> to dump 16 bit code. Then use
+<CODE>x/10i $cs*16+*eip</CODE> to dump the code at the PC position.
+</OL>
+
+
+
+<H2><A NAME="SEC26" HREF="qemu-doc.html#TOC26">3.11 Target OS specific information</A></H2>
+
+
+
+<H3><A NAME="SEC27" HREF="qemu-doc.html#TOC27">3.11.1 Linux</A></H3>
+
+<P>
+To have access to SVGA graphic modes under X11, use the <CODE>vesa</CODE> or
+the <CODE>cirrus</CODE> X11 driver. For optimal performances, use 16 bit
+color depth in the guest and the host OS.
+
+
+<P>
+When using a 2.6 guest Linux kernel, you should add the option
+<CODE>clock=pit</CODE> on the kernel command line because the 2.6 Linux
+kernels make very strict real time clock checks by default that QEMU
+cannot simulate exactly.
+
+
+
+
+<H3><A NAME="SEC28" HREF="qemu-doc.html#TOC28">3.11.2 Windows</A></H3>
+
+<P>
+If you have a slow host, using Windows 95 is better as it gives the
+best speed. Windows 2000 is also a good choice.
+
+
+
+
+<H4><A NAME="SEC29" HREF="qemu-doc.html#TOC29">3.11.2.1 SVGA graphic modes support</A></H4>
+
+<P>
+QEMU emulates a Cirrus Logic GD5446 Video
+card. All Windows versions starting from Windows 95 should recognize
+and use this graphic card. For optimal performances, use 16 bit color
+depth in the guest and the host OS.
+
+
+
+
+<H4><A NAME="SEC30" HREF="qemu-doc.html#TOC30">3.11.2.2 CPU usage reduction</A></H4>
+
+<P>
+Windows 9x does not correctly use the CPU HLT
+instruction. The result is that it takes host CPU cycles even when
+idle. You can install the utility from
+<A HREF="http://www.user.cityline.ru/~maxamn/amnhltm.zip">http://www.user.cityline.ru/~maxamn/amnhltm.zip</A> to solve this
+problem. Note that no such tool is needed for NT, 2000 or XP.
+
+
+
+
+<H4><A NAME="SEC31" HREF="qemu-doc.html#TOC31">3.11.2.3 Windows 2000 disk full problems</A></H4>
+
+<P>
+Currently (release 0.6.0) QEMU has a bug which gives a <CODE>disk
+full</CODE> error during installation of some releases of Windows 2000. The
+workaround is to stop QEMU as soon as you notice that your disk image
+size is growing too fast (monitor it with <CODE>ls -ls</CODE>). Then
+relaunch QEMU to continue the installation. If you still experience
+the problem, relaunch QEMU again.
+
+
+<P>
+Future QEMU releases are likely to correct this bug.
+
+
+
+
+<H4><A NAME="SEC32" HREF="qemu-doc.html#TOC32">3.11.2.4 Windows XP security problems</A></H4>
+
+<P>
+Some releases of Windows XP install correctly but give a security
+error when booting:
+
+<PRE>
+A problem is preventing Windows from accurately checking the
+license for this computer. Error code: 0x800703e6.
+</PRE>
+
+<P>
+The only known workaround is to boot in Safe mode
+without networking support. 
+
+
+<P>
+Future QEMU releases are likely to correct this bug.
+
+
+
+
+<H3><A NAME="SEC33" HREF="qemu-doc.html#TOC33">3.11.3 MS-DOS and FreeDOS</A></H3>
+
+
+
+<H4><A NAME="SEC34" HREF="qemu-doc.html#TOC34">3.11.3.1 CPU usage reduction</A></H4>
+
+<P>
+DOS does not correctly use the CPU HLT instruction. The result is that
+it takes host CPU cycles even when idle. You can install the utility
+from <A HREF="http://www.vmware.com/software/dosidle210.zip">http://www.vmware.com/software/dosidle210.zip</A> to solve this
+problem.
+
+
+
+
+<H1><A NAME="SEC35" HREF="qemu-doc.html#TOC35">4. QEMU PowerPC System emulator invocation</A></H1>
+
+<P>
+Use the executable <TT>`qemu-system-ppc'</TT> to simulate a complete PREP
+or PowerMac PowerPC system.
+
+
+<P>
+QEMU emulates the following PowerMac peripherials:
+
+
+
+<UL>
+<LI>
+
+UniNorth PCI Bridge 
+<LI>
+
+PCI VGA compatible card with VESA Bochs Extensions
+<LI>
+
+2 PMAC IDE interfaces with hard disk and CD-ROM support
+<LI>
+
+NE2000 PCI adapters
+<LI>
+
+Non Volatile RAM
+<LI>
+
+VIA-CUDA with ADB keyboard and mouse.
+</UL>
+
+<P>
+QEMU emulates the following PREP peripherials:
+
+
+
+<UL>
+<LI>
+
+PCI Bridge
+<LI>
+
+PCI VGA compatible card with VESA Bochs Extensions
+<LI>
+
+2 IDE interfaces with hard disk and CD-ROM support
+<LI>
+
+Floppy disk
+<LI>
+
+NE2000 network adapters
+<LI>
+
+Serial port
+<LI>
+
+PREP Non Volatile RAM
+<LI>
+
+PC compatible keyboard and mouse.
+</UL>
+
+<P>
+QEMU uses the Open Hack'Ware Open Firmware Compatible BIOS available at
+<A HREF="http://site.voila.fr/jmayer/OpenHackWare/index.htm">http://site.voila.fr/jmayer/OpenHackWare/index.htm</A>.
+
+
+<P>
+You can read the qemu PC system emulation chapter to have more
+informations about QEMU usage.
+
+
+<P>
+The following options are specific to the PowerPC emulation:
+
+
+<DL COMPACT>
+
+<DT>@option{-prep}
+<DD>
+Simulate a PREP system (default is PowerMAC)
+
+<DT>@option{-g WxH[xDEPTH]}
+<DD>
+Set the initial VGA graphic mode. The default is 800x600x15.
+
+</DL>
+
+<P>
+More information is available at
+<A HREF="http://jocelyn.mayer.free.fr/qemu-ppc/">http://jocelyn.mayer.free.fr/qemu-ppc/</A>.
+
+
+
+
+<H1><A NAME="SEC36" HREF="qemu-doc.html#TOC36">5. QEMU User space emulator invocation</A></H1>
+
+
+
+<H2><A NAME="SEC37" HREF="qemu-doc.html#TOC37">5.1 Quick Start</A></H2>
+
+<P>
+In order to launch a Linux process, QEMU needs the process executable
+itself and all the target (x86) dynamic libraries used by it. 
+
+
+
+<UL>
+
+<LI>On x86, you can just try to launch any process by using the native
+
+libraries:
+
+
+<PRE>
+qemu-i386 -L / /bin/ls
+</PRE>
+
+<CODE>-L /</CODE> tells that the x86 dynamic linker must be searched with a
+<TT>`/'</TT> prefix.
+
+<LI>Since QEMU is also a linux process, you can launch qemu with qemu (NOTE: you can only do that if you compiled QEMU from the sources):
+
+
+<PRE>
+qemu-i386 -L / qemu-i386 -L / /bin/ls
+</PRE>
+
+<LI>On non x86 CPUs, you need first to download at least an x86 glibc
+
+(<TT>`qemu-runtime-i386-XXX-.tar.gz'</TT> on the QEMU web page). Ensure that
+<CODE>LD_LIBRARY_PATH</CODE> is not set:
+
+
+<PRE>
+unset LD_LIBRARY_PATH 
+</PRE>
+
+Then you can launch the precompiled <TT>`ls'</TT> x86 executable:
+
+
+<PRE>
+qemu-i386 tests/i386/ls
+</PRE>
+
+You can look at <TT>`qemu-binfmt-conf.sh'</TT> so that
+QEMU is automatically launched by the Linux kernel when you try to
+launch x86 executables. It requires the <CODE>binfmt_misc</CODE> module in the
+Linux kernel.
+
+<LI>The x86 version of QEMU is also included. You can try weird things such as:
+
+
+<PRE>
+qemu-i386 /usr/local/qemu-i386/bin/qemu-i386 /usr/local/qemu-i386/bin/ls-i386
+</PRE>
+
+</UL>
+
+
+
+<H2><A NAME="SEC38" HREF="qemu-doc.html#TOC38">5.2 Wine launch</A></H2>
+
+
+<UL>
+
+<LI>Ensure that you have a working QEMU with the x86 glibc
+
+distribution (see previous section). In order to verify it, you must be
+able to do:
+
+
+<PRE>
+qemu-i386 /usr/local/qemu-i386/bin/ls-i386
+</PRE>
+
+<LI>Download the binary x86 Wine install
+
+(<TT>`qemu-XXX-i386-wine.tar.gz'</TT> on the QEMU web page). 
+
+<LI>Configure Wine on your account. Look at the provided script
+
+<TT>`/usr/local/qemu-i386/bin/wine-conf.sh'</TT>. Your previous
+<CODE>${HOME}/.wine</CODE> directory is saved to <CODE>${HOME}/.wine.org</CODE>.
+
+<LI>Then you can try the example <TT>`putty.exe'</TT>:
+
+
+<PRE>
+qemu-i386 /usr/local/qemu-i386/wine/bin/wine /usr/local/qemu-i386/wine/c/Program\ Files/putty.exe
+</PRE>
+
+</UL>
+
+
+
+<H2><A NAME="SEC39" HREF="qemu-doc.html#TOC39">5.3 Command line options</A></H2>
+
+
+<PRE>
+usage: qemu-i386 [-h] [-d] [-L path] [-s size] program [arguments...]
+</PRE>
+
+<DL COMPACT>
+
+<DT>@option{-h}
+<DD>
+Print the help
+<DT>@option{-L path}
+<DD>
+Set the x86 elf interpreter prefix (default=/usr/local/qemu-i386)
+<DT>@option{-s size}
+<DD>
+Set the x86 stack size in bytes (default=524288)
+</DL>
+
+<P>
+Debug options:
+
+
+<DL COMPACT>
+
+<DT>@option{-d}
+<DD>
+Activate log (logfile=/tmp/qemu.log)
+<DT>@option{-p pagesize}
+<DD>
+Act as if the host page size was 'pagesize' bytes
+</DL>
+
+
+
+<H1><A NAME="SEC40" HREF="qemu-doc.html#TOC40">6. Compilation from the sources</A></H1>
+
+
+
+<H2><A NAME="SEC41" HREF="qemu-doc.html#TOC41">6.1 Linux/BSD</A></H2>
+
+<P>
+Read the <TT>`README'</TT> which gives the related information.
+
+
+
+
+<H2><A NAME="SEC42" HREF="qemu-doc.html#TOC42">6.2 Windows</A></H2>
+
+
+<UL>
+<LI>Install the current versions of MSYS and MinGW from
+
+<A HREF="http://www.mingw.org/">http://www.mingw.org/</A>. You can find detailed installation
+instructions in the download section and the FAQ.
+
+<LI>Download
+
+the MinGW development library of SDL 1.2.x
+(<TT>`SDL-devel-1.2.x-mingw32.tar.gz'</TT>) from
+<A HREF="http://www.libsdl.org">http://www.libsdl.org</A>. Unpack it in a temporary place, and
+unpack the archive <TT>`i386-mingw32msvc.tar.gz'</TT> in the MinGW tool
+directory. Edit the <TT>`sdl-config'</TT> script so that it gives the
+correct SDL directory when invoked.
+
+<LI>Extract the current version of QEMU.
+
+<LI>Start the MSYS shell (file <TT>`msys.bat'</TT>).
+
+<LI>Change to the QEMU directory. Launch <TT>`./configure'</TT> and
+
+<TT>`make'</TT>.  If you have problems using SDL, verify that
+<TT>`sdl-config'</TT> can be launched from the MSYS command line.
+
+<LI>You can install QEMU in <TT>`Program Files/Qemu'</TT> by typing
+
+<TT>`make install'</TT>. Don't forget to copy <TT>`SDL.dll'</TT> in
+<TT>`Program Files/Qemu'</TT>.
+
+</UL>
+
+
+
+<H2><A NAME="SEC43" HREF="qemu-doc.html#TOC43">6.3 Cross compilation for Windows with Linux</A></H2>
+
+
+<UL>
+<LI>
+
+Install the MinGW cross compilation tools available at
+<A HREF="http://www.mingw.org/">http://www.mingw.org/</A>.
+
+<LI>
+
+Install the Win32 version of SDL (<A HREF="http://www.libsdl.org">http://www.libsdl.org</A>) by
+unpacking <TT>`i386-mingw32msvc.tar.gz'</TT>. Set up the PATH environment
+variable so that <TT>`i386-mingw32msvc-sdl-config'</TT> can be launched by
+the QEMU configuration script.
+
+<LI>
+
+Configure QEMU for Windows cross compilation:
+
+<PRE>
+./configure --enable-mingw32
+</PRE>
+
+If necessary, you can change the cross-prefix according to the prefix
+choosen for the MinGW tools with --cross-prefix. You can also use
+--prefix to set the Win32 install path.
+
+<LI>You can install QEMU in the installation directory by typing
+
+<TT>`make install'</TT>. Don't forget to copy <TT>`SDL.dll'</TT> in the
+installation directory. 
+
+</UL>
+
+<P>
+Note: Currently, Wine does not seem able to launch
+QEMU for Win32.
+
+
+
+
+<H2><A NAME="SEC44" HREF="qemu-doc.html#TOC44">6.4 Mac OS X</A></H2>
+
+<P>
+The Mac OS X patches are not fully merged in QEMU, so you should look
+at the QEMU mailing list archive to have all the necessary
+information.
+
+
+<P><HR><P>
+This document was generated on 19 May 2005 using
+<A HREF="http://wwwinfo.cern.ch/dis/texi2html/">texi2html</A>&nbsp;1.56k.
+</BODY>
+</HTML>
diff --git a/tools/ioemu/qemu-doc.texi b/tools/ioemu/qemu-doc.texi
new file mode 100644 (file)
index 0000000..c262ee7
--- /dev/null
@@ -0,0 +1,1296 @@
+\input texinfo @c -*- texinfo -*-
+
+@iftex
+@settitle QEMU CPU Emulator User Documentation
+@titlepage
+@sp 7
+@center @titlefont{QEMU CPU Emulator User Documentation}
+@sp 3
+@end titlepage
+@end iftex
+
+@chapter Introduction
+
+@section Features
+
+QEMU is a FAST! processor emulator using dynamic translation to
+achieve good emulation speed.
+
+QEMU has two operating modes:
+
+@itemize @minus
+
+@item 
+Full system emulation. In this mode, QEMU emulates a full system (for
+example a PC), including a processor and various peripherials. It can
+be used to launch different Operating Systems without rebooting the
+PC or to debug system code.
+
+@item 
+User mode emulation (Linux host only). In this mode, QEMU can launch
+Linux processes compiled for one CPU on another CPU. It can be used to
+launch the Wine Windows API emulator (@url{http://www.winehq.org}) or
+to ease cross-compilation and cross-debugging.
+
+@end itemize
+
+As QEMU requires no host kernel driver to run, it is very safe and
+easy to use.
+
+For system emulation, the following hardware targets are supported:
+@itemize
+@item PC (x86 processor)
+@item PREP (PowerPC processor)
+@item PowerMac (PowerPC processor, in progress)
+@end itemize
+
+For user emulation, x86, PowerPC, ARM, and SPARC CPUs are supported.
+
+@chapter Installation
+
+If you want to compile QEMU yourself, see @ref{compilation}.
+
+@section Linux
+
+Download the binary distribution (@file{qemu-XXX-i386.tar.gz}) and
+untar it as root in @file{/}:
+
+@example
+su
+cd /
+tar zxvf /tmp/qemu-XXX-i386.tar.gz
+@end example
+
+@section Windows
+
+Download the experimental binary installer at
+@url{http://www.freeoszoo.org/download.php}.
+
+@section Mac OS X
+
+Download the experimental binary installer at
+@url{http://www.freeoszoo.org/download.php}.
+
+@chapter QEMU PC System emulator invocation
+
+@section Introduction
+
+@c man begin DESCRIPTION
+
+The QEMU System emulator simulates a complete PC.
+
+In order to meet specific user needs, two versions of QEMU are
+available:
+
+@enumerate
+
+@item 
+@code{qemu-fast} uses the host Memory Management Unit (MMU) to
+simulate the x86 MMU. It is @emph{fast} but has limitations because
+the whole 4 GB address space cannot be used and some memory mapped
+peripherials cannot be emulated accurately yet. Therefore, a specific
+guest Linux kernel can be used (@xref{linux_compile}) as guest
+OS. 
+
+Moreover there is no separation between the host and target address
+spaces, so it offers no security (the target OS can modify the
+@code{qemu-fast} code by writing at the right addresses).
+
+@item 
+@code{qemu} uses a software MMU. It is about @emph{two times slower}
+but gives a more accurate emulation and a complete separation between
+the host and target address spaces.
+
+@end enumerate
+
+QEMU emulates the following PC peripherials:
+
+@itemize @minus
+@item 
+i440FX host PCI bridge and PIIX3 PCI to ISA bridge
+@item
+Cirrus CLGD 5446 PCI VGA card or dummy VGA card with Bochs VESA
+extensions (hardware level, including all non standard modes).
+@item
+PS/2 mouse and keyboard
+@item 
+2 PCI IDE interfaces with hard disk and CD-ROM support
+@item
+Floppy disk
+@item 
+NE2000 PCI network adapters
+@item
+Serial ports
+@item
+Soundblaster 16 card
+@end itemize
+
+QEMU uses the PC BIOS from the Bochs project and the Plex86/Bochs LGPL
+VGA BIOS.
+
+@c man end
+
+@section Quick Start
+
+Download and uncompress the linux image (@file{linux.img}) and type:
+
+@example
+qemu linux.img
+@end example
+
+Linux should boot and give you a prompt.
+
+@section Invocation
+
+@example
+@c man begin SYNOPSIS
+usage: qemu [options] [disk_image]
+@c man end
+@end example
+
+@c man begin OPTIONS
+@var{disk_image} is a raw hard disk image for IDE hard disk 0.
+
+General options:
+@table @option
+@item -fda file
+@item -fdb file
+Use @var{file} as floppy disk 0/1 image (@xref{disk_images}). You can
+use the host floppy by using @file{/dev/fd0} as filename.
+
+@item -hda file
+@item -hdb file
+@item -hdc file
+@item -hdd file
+Use @var{file} as hard disk 0, 1, 2 or 3 image (@xref{disk_images}).
+
+@item -cdrom file
+Use @var{file} as CD-ROM image (you cannot use @option{-hdc} and and
+@option{-cdrom} at the same time). You can use the host CD-ROM by
+using @file{/dev/cdrom} as filename.
+
+@item -boot [a|c|d]
+Boot on floppy (a), hard disk (c) or CD-ROM (d). Hard disk boot is
+the default.
+
+@item -snapshot
+Write to temporary files instead of disk image files. In this case,
+the raw disk image you use is not written back. You can however force
+the write back by pressing @key{C-a s} (@xref{disk_images}). 
+
+@item -m megs
+Set virtual RAM size to @var{megs} megabytes. Default is 128 MB.
+
+@item -nographic
+
+Normally, QEMU uses SDL to display the VGA output. With this option,
+you can totally disable graphical output so that QEMU is a simple
+command line application. The emulated serial port is redirected on
+the console. Therefore, you can still use QEMU to debug a Linux kernel
+with a serial console.
+
+@item -enable-audio
+
+The SB16 emulation is disabled by default as it may give problems with
+Windows. You can enable it manually with this option.
+
+@item -localtime
+Set the real time clock to local time (the default is to UTC
+time). This option is needed to have correct date in MS-DOS or
+Windows.
+
+@item -full-screen
+Start in full screen.
+
+@end table
+
+Network options:
+
+@table @option
+
+@item -n script      
+Set TUN/TAP network init script [default=/etc/qemu-ifup]. This script
+is launched to configure the host network interface (usually tun0)
+corresponding to the virtual NE2000 card.
+
+@item -macaddr addr   
+
+Set the mac address of the first interface (the format is
+aa:bb:cc:dd:ee:ff in hexa). The mac address is incremented for each
+new network interface.
+
+@item -tun-fd fd
+Assumes @var{fd} talks to a tap/tun host network interface and use
+it. Read @url{http://bellard.org/qemu/tetrinet.html} to have an
+example of its use.
+
+@item -user-net 
+Use the user mode network stack. This is the default if no tun/tap
+network init script is found.
+
+@item -tftp prefix
+When using the user mode network stack, activate a built-in TFTP
+server. All filenames beginning with @var{prefix} can be downloaded
+from the host to the guest using a TFTP client. The TFTP client on the
+guest must be configured in binary mode (use the command @code{bin} of
+the Unix TFTP client). The host IP address on the guest is as usual
+10.0.2.2.
+
+@item -smb dir
+When using the user mode network stack, activate a built-in SMB
+server so that Windows OSes can access to the host files in @file{dir}
+transparently.
+
+In the guest Windows OS, the line:
+@example
+10.0.2.4 smbserver
+@end example
+must be added in the file @file{C:\WINDOWS\LMHOSTS} (for windows 9x/Me)
+or @file{C:\WINNT\SYSTEM32\DRIVERS\ETC\LMHOSTS} (Windows NT/2000).
+
+Then @file{dir} can be accessed in @file{\\smbserver\qemu}.
+
+Note that a SAMBA server must be installed on the host OS in
+@file{/usr/sbin/smbd}. QEMU was tested succesfully with smbd version
+2.2.7a from the Red Hat 9.
+
+@item -redir [tcp|udp]:host-port:[guest-host]:guest-port
+
+When using the user mode network stack, redirect incoming TCP or UDP
+connections to the host port @var{host-port} to the guest
+@var{guest-host} on guest port @var{guest-port}. If @var{guest-host}
+is not specified, its value is 10.0.2.15 (default address given by the
+built-in DHCP server).
+
+For example, to redirect host X11 connection from screen 1 to guest
+screen 0, use the following:
+
+@example
+# on the host
+qemu -redir tcp:6001::6000 [...]
+# this host xterm should open in the guest X11 server
+xterm -display :1
+@end example
+
+To redirect telnet connections from host port 5555 to telnet port on
+the guest, use the following:
+
+@example
+# on the host
+qemu -redir tcp:5555::23 [...]
+telnet localhost 5555
+@end example
+
+Then when you use on the host @code{telnet localhost 5555}, you
+connect to the guest telnet server.
+
+@item -dummy-net 
+Use the dummy network stack: no packet will be received by the network
+cards.
+
+@end table
+
+Linux boot specific. When using this options, you can use a given
+Linux kernel without installing it in the disk image. It can be useful
+for easier testing of various kernels.
+
+@table @option
+
+@item -kernel bzImage 
+Use @var{bzImage} as kernel image.
+
+@item -append cmdline 
+Use @var{cmdline} as kernel command line
+
+@item -initrd file
+Use @var{file} as initial ram disk.
+
+@end table
+
+Debug/Expert options:
+@table @option
+
+@item -serial dev
+Redirect the virtual serial port to host device @var{dev}. Available
+devices are:
+@table @code
+@item vc
+Virtual console
+@item pty
+[Linux only] Pseudo TTY (a new PTY is automatically allocated)
+@item null
+void device
+@item stdio
+[Unix only] standard input/output
+@end table
+The default device is @code{vc} in graphical mode and @code{stdio} in
+non graphical mode.
+
+This option can be used several times to simulate up to 4 serials
+ports.
+
+@item -monitor dev
+Redirect the monitor to host device @var{dev} (same devices as the
+serial port).
+The default device is @code{vc} in graphical mode and @code{stdio} in
+non graphical mode.
+
+@item -s
+Wait gdb connection to port 1234 (@xref{gdb_usage}). 
+@item -p port
+Change gdb connection port.
+@item -S
+Do not start CPU at startup (you must type 'c' in the monitor).
+@item -d             
+Output log in /tmp/qemu.log
+@item -isa
+Simulate an ISA-only system (default is PCI system).
+@item -std-vga
+Simulate a standard VGA card with Bochs VBE extensions (default is
+Cirrus Logic GD5446 PCI VGA)
+@item -loadvm file
+Start right away with a saved state (@code{loadvm} in monitor)
+@end table
+
+@c man end
+
+@section Keys
+
+@c man begin OPTIONS
+
+During the graphical emulation, you can use the following keys:
+@table @key
+@item Ctrl-Alt-f
+Toggle full screen
+
+@item Ctrl-Alt-n
+Switch to virtual console 'n'. Standard console mappings are:
+@table @emph
+@item 1
+Target system display
+@item 2
+Monitor
+@item 3
+Serial port
+@end table
+
+@item Ctrl-Alt
+Toggle mouse and keyboard grab.
+@end table
+
+In the virtual consoles, you can use @key{Ctrl-Up}, @key{Ctrl-Down},
+@key{Ctrl-PageUp} and @key{Ctrl-PageDown} to move in the back log.
+
+During emulation, if you are using the @option{-nographic} option, use
+@key{Ctrl-a h} to get terminal commands:
+
+@table @key
+@item Ctrl-a h
+Print this help
+@item Ctrl-a x    
+Exit emulatior
+@item Ctrl-a s    
+Save disk data back to file (if -snapshot)
+@item Ctrl-a b
+Send break (magic sysrq in Linux)
+@item Ctrl-a c
+Switch between console and monitor
+@item Ctrl-a Ctrl-a
+Send Ctrl-a
+@end table
+@c man end
+
+@ignore
+
+@setfilename qemu 
+@settitle QEMU System Emulator
+
+@c man begin SEEALSO
+The HTML documentation of QEMU for more precise information and Linux
+user mode emulator invocation.
+@c man end
+
+@c man begin AUTHOR
+Fabrice Bellard
+@c man end
+
+@end ignore
+
+@end ignore
+
+
+@section QEMU Monitor
+
+The QEMU monitor is used to give complex commands to the QEMU
+emulator. You can use it to:
+
+@itemize @minus
+
+@item
+Remove or insert removable medias images
+(such as CD-ROM or floppies)
+
+@item 
+Freeze/unfreeze the Virtual Machine (VM) and save or restore its state
+from a disk file.
+
+@item Inspect the VM state without an external debugger.
+
+@end itemize
+
+@subsection Commands
+
+The following commands are available:
+
+@table @option
+
+@item help or ? [cmd]
+Show the help for all commands or just for command @var{cmd}.
+
+@item commit  
+Commit changes to the disk images (if -snapshot is used)
+
+@item info subcommand 
+show various information about the system state
+
+@table @option
+@item info network
+show the network state
+@item info block
+show the block devices
+@item info registers
+show the cpu registers
+@item info history
+show the command line history
+@end table
+
+@item q or quit
+Quit the emulator.
+
+@item eject [-f] device
+Eject a removable media (use -f to force it).
+
+@item change device filename
+Change a removable media.
+
+@item screendump filename
+Save screen into PPM image @var{filename}.
+
+@item log item1[,...]
+Activate logging of the specified items to @file{/tmp/qemu.log}.
+
+@item savevm filename
+Save the whole virtual machine state to @var{filename}.
+
+@item loadvm filename
+Restore the whole virtual machine state from @var{filename}.
+
+@item stop
+Stop emulation.
+
+@item c or cont
+Resume emulation.
+
+@item gdbserver [port]
+Start gdbserver session (default port=1234)
+
+@item x/fmt addr
+Virtual memory dump starting at @var{addr}.
+
+@item xp /fmt addr
+Physical memory dump starting at @var{addr}.
+
+@var{fmt} is a format which tells the command how to format the
+data. Its syntax is: @option{/@{count@}@{format@}@{size@}}
+
+@table @var
+@item count 
+is the number of items to be dumped.
+
+@item format
+can be x (hexa), d (signed decimal), u (unsigned decimal), o (octal),
+c (char) or i (asm instruction).
+
+@item size
+can be b (8 bits), h (16 bits), w (32 bits) or g (64 bits). On x86,
+@code{h} or @code{w} can be specified with the @code{i} format to
+respectively select 16 or 32 bit code instruction size.
+
+@end table
+
+Examples: 
+@itemize
+@item
+Dump 10 instructions at the current instruction pointer:
+@example 
+(qemu) x/10i $eip
+0x90107063:  ret
+0x90107064:  sti
+0x90107065:  lea    0x0(%esi,1),%esi
+0x90107069:  lea    0x0(%edi,1),%edi
+0x90107070:  ret
+0x90107071:  jmp    0x90107080
+0x90107073:  nop
+0x90107074:  nop
+0x90107075:  nop
+0x90107076:  nop
+@end example
+
+@item
+Dump 80 16 bit values at the start of the video memory.
+@example 
+(qemu) xp/80hx 0xb8000
+0x000b8000: 0x0b50 0x0b6c 0x0b65 0x0b78 0x0b38 0x0b36 0x0b2f 0x0b42
+0x000b8010: 0x0b6f 0x0b63 0x0b68 0x0b73 0x0b20 0x0b56 0x0b47 0x0b41
+0x000b8020: 0x0b42 0x0b69 0x0b6f 0x0b73 0x0b20 0x0b63 0x0b75 0x0b72
+0x000b8030: 0x0b72 0x0b65 0x0b6e 0x0b74 0x0b2d 0x0b63 0x0b76 0x0b73
+0x000b8040: 0x0b20 0x0b30 0x0b35 0x0b20 0x0b4e 0x0b6f 0x0b76 0x0b20
+0x000b8050: 0x0b32 0x0b30 0x0b30 0x0b33 0x0720 0x0720 0x0720 0x0720
+0x000b8060: 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720
+0x000b8070: 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720
+0x000b8080: 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720
+0x000b8090: 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720 0x0720
+@end example
+@end itemize
+
+@item p or print/fmt expr
+
+Print expression value. Only the @var{format} part of @var{fmt} is
+used.
+
+@item sendkey keys
+
+Send @var{keys} to the emulator. Use @code{-} to press several keys
+simultaneously. Example:
+@example
+sendkey ctrl-alt-f1
+@end example
+
+This command is useful to send keys that your graphical user interface
+intercepts at low level, such as @code{ctrl-alt-f1} in X Window.
+
+@item system_reset
+
+Reset the system.
+
+@end table
+
+@subsection Integer expressions
+
+The monitor understands integers expressions for every integer
+argument. You can use register names to get the value of specifics
+CPU registers by prefixing them with @emph{$}.
+
+@node disk_images
+@section Disk Images
+
+@subsection Raw disk images
+
+The disk images can simply be raw images of the hard disk. You can
+create them with the command:
+@example
+dd of=myimage bs=1024 seek=mysize count=0
+@end example
+where @var{myimage} is the image filename and @var{mysize} is its size
+in kilobytes.
+
+@subsection Snapshot mode
+
+If you use the option @option{-snapshot}, all disk images are
+considered as read only. When sectors in written, they are written in
+a temporary file created in @file{/tmp}. You can however force the
+write back to the raw disk images by pressing @key{C-a s}.
+
+NOTE: The snapshot mode only works with raw disk images.
+
+@subsection Copy On Write disk images
+
+QEMU also supports user mode Linux
+(@url{http://user-mode-linux.sourceforge.net/}) Copy On Write (COW)
+disk images. The COW disk images are much smaller than normal images
+as they store only modified sectors. They also permit the use of the
+same disk image template for many users.
+
+To create a COW disk images, use the command:
+
+@example
+qemu-mkcow -f myrawimage.bin mycowimage.cow
+@end example
+
+@file{myrawimage.bin} is a raw image you want to use as original disk
+image. It will never be written to.
+
+@file{mycowimage.cow} is the COW disk image which is created by
+@code{qemu-mkcow}. You can use it directly with the @option{-hdx}
+options. You must not modify the original raw disk image if you use
+COW images, as COW images only store the modified sectors from the raw
+disk image. QEMU stores the original raw disk image name and its
+modified time in the COW disk image so that chances of mistakes are
+reduced.
+
+If the raw disk image is not read-only, by pressing @key{C-a s} you
+can flush the COW disk image back into the raw disk image, as in
+snapshot mode.
+
+COW disk images can also be created without a corresponding raw disk
+image. It is useful to have a big initial virtual disk image without
+using much disk space. Use:
+
+@example
+qemu-mkcow mycowimage.cow 1024
+@end example
+
+to create a 1 gigabyte empty COW disk image.
+
+NOTES: 
+@enumerate
+@item
+COW disk images must be created on file systems supporting
+@emph{holes} such as ext2 or ext3.
+@item 
+Since holes are used, the displayed size of the COW disk image is not
+the real one. To know it, use the @code{ls -ls} command.
+@end enumerate
+
+@subsection Convert VMware disk images to raw disk images
+
+You can use the tool @file{vmdk2raw} to convert VMware disk images to
+raw disk images directly usable by QEMU. The syntax is:
+@example
+vmdk2raw vmware_image output_image
+@end example
+
+@section Network emulation
+
+QEMU simulates up to 6 networks cards (NE2000 boards). Each card can
+be connected to a specific host network interface.
+
+@subsection Using tun/tap network interface
+
+This is the standard way to emulate network. QEMU adds a virtual
+network device on your host (called @code{tun0}), and you can then
+configure it as if it was a real ethernet card.
+
+As an example, you can download the @file{linux-test-xxx.tar.gz}
+archive and copy the script @file{qemu-ifup} in @file{/etc} and
+configure properly @code{sudo} so that the command @code{ifconfig}
+contained in @file{qemu-ifup} can be executed as root. You must verify
+that your host kernel supports the TUN/TAP network interfaces: the
+device @file{/dev/net/tun} must be present.
+
+See @ref{direct_linux_boot} to have an example of network use with a
+Linux distribution.
+
+@subsection Using the user mode network stack
+
+By using the option @option{-user-net} or if you have no tun/tap init
+script, QEMU uses a completely user mode network stack (you don't need
+root priviledge to use the virtual network). The virtual network
+configuration is the following:
+
+@example
+
+QEMU Virtual Machine    <------>  Firewall/DHCP server <-----> Internet
+     (10.0.2.x)            |          (10.0.2.2)
+                           |
+                           ---->  DNS server (10.0.2.3)
+                           |     
+                           ---->  SMB server (10.0.2.4)
+@end example
+
+The QEMU VM behaves as if it was behind a firewall which blocks all
+incoming connections. You can use a DHCP client to automatically
+configure the network in the QEMU VM.
+
+In order to check that the user mode network is working, you can ping
+the address 10.0.2.2 and verify that you got an address in the range
+10.0.2.x from the QEMU virtual DHCP server.
+
+Note that @code{ping} is not supported reliably to the internet as it
+would require root priviledges. It means you can only ping the local
+router (10.0.2.2).
+
+When using the built-in TFTP server, the router is also the TFTP
+server.
+
+When using the @option{-redir} option, TCP or UDP connections can be
+redirected from the host to the guest. It allows for example to
+redirect X11, telnet or SSH connections.
+
+@node direct_linux_boot
+@section Direct Linux Boot
+
+This section explains how to launch a Linux kernel inside QEMU without
+having to make a full bootable image. It is very useful for fast Linux
+kernel testing. The QEMU network configuration is also explained.
+
+@enumerate
+@item
+Download the archive @file{linux-test-xxx.tar.gz} containing a Linux
+kernel and a disk image. 
+
+@item Optional: If you want network support (for example to launch X11 examples), you
+must copy the script @file{qemu-ifup} in @file{/etc} and configure
+properly @code{sudo} so that the command @code{ifconfig} contained in
+@file{qemu-ifup} can be executed as root. You must verify that your host
+kernel supports the TUN/TAP network interfaces: the device
+@file{/dev/net/tun} must be present.
+
+When network is enabled, there is a virtual network connection between
+the host kernel and the emulated kernel. The emulated kernel is seen
+from the host kernel at IP address 172.20.0.2 and the host kernel is
+seen from the emulated kernel at IP address 172.20.0.1.
+
+@item Launch @code{qemu.sh}. You should have the following output:
+
+@example
+> ./qemu.sh 
+Connected to host network interface: tun0
+Linux version 2.4.21 (bellard@voyager.localdomain) (gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)) #5 Tue Nov 11 18:18:53 CET 2003
+BIOS-provided physical RAM map:
+ BIOS-e801: 0000000000000000 - 000000000009f000 (usable)
+ BIOS-e801: 0000000000100000 - 0000000002000000 (usable)
+32MB LOWMEM available.
+On node 0 totalpages: 8192
+zone(0): 4096 pages.
+zone(1): 4096 pages.
+zone(2): 0 pages.
+Kernel command line: root=/dev/hda sb=0x220,5,1,5 ide2=noprobe ide3=noprobe ide4=noprobe ide5=noprobe console=ttyS0
+ide_setup: ide2=noprobe
+ide_setup: ide3=noprobe
+ide_setup: ide4=noprobe
+ide_setup: ide5=noprobe
+Initializing CPU#0
+Detected 2399.621 MHz processor.
+Console: colour EGA 80x25
+Calibrating delay loop... 4744.80 BogoMIPS
+Memory: 28872k/32768k available (1210k kernel code, 3508k reserved, 266k data, 64k init, 0k highmem)
+Dentry cache hash table entries: 4096 (order: 3, 32768 bytes)
+Inode cache hash table entries: 2048 (order: 2, 16384 bytes)
+Mount cache hash table entries: 512 (order: 0, 4096 bytes)
+Buffer-cache hash table entries: 1024 (order: 0, 4096 bytes)
+Page-cache hash table entries: 8192 (order: 3, 32768 bytes)
+CPU: Intel Pentium Pro stepping 03
+Checking 'hlt' instruction... OK.
+POSIX conformance testing by UNIFIX
+Linux NET4.0 for Linux 2.4
+Based upon Swansea University Computer Society NET3.039
+Initializing RT netlink socket
+apm: BIOS not found.
+Starting kswapd
+Journalled Block Device driver loaded
+Detected PS/2 Mouse Port.
+pty: 256 Unix98 ptys configured
+Serial driver version 5.05c (2001-07-08) with no serial options enabled
+ttyS00 at 0x03f8 (irq = 4) is a 16450
+ne.c:v1.10 9/23/94 Donald Becker (becker@scyld.com)
+Last modified Nov 1, 2000 by Paul Gortmaker
+NE*000 ethercard probe at 0x300: 52 54 00 12 34 56
+eth0: NE2000 found at 0x300, using IRQ 9.
+RAMDISK driver initialized: 16 RAM disks of 4096K size 1024 blocksize
+Uniform Multi-Platform E-IDE driver Revision: 7.00beta4-2.4
+ide: Assuming 50MHz system bus speed for PIO modes; override with idebus=xx
+hda: QEMU HARDDISK, ATA DISK drive
+ide0 at 0x1f0-0x1f7,0x3f6 on irq 14
+hda: attached ide-disk driver.
+hda: 20480 sectors (10 MB) w/256KiB Cache, CHS=20/16/63
+Partition check:
+ hda:
+Soundblaster audio driver Copyright (C) by Hannu Savolainen 1993-1996
+NET4: Linux TCP/IP 1.0 for NET4.0
+IP Protocols: ICMP, UDP, TCP, IGMP
+IP: routing cache hash table of 512 buckets, 4Kbytes
+TCP: Hash tables configured (established 2048 bind 4096)
+NET4: Unix domain sockets 1.0/SMP for Linux NET4.0.
+EXT2-fs warning: mounting unchecked fs, running e2fsck is recommended
+VFS: Mounted root (ext2 filesystem).
+Freeing unused kernel memory: 64k freed
+Linux version 2.4.21 (bellard@voyager.localdomain) (gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)) #5 Tue Nov 11 18:18:53 CET 2003
+QEMU Linux test distribution (based on Redhat 9)
+Type 'exit' to halt the system
+sh-2.05b# 
+@end example
+
+@item
+Then you can play with the kernel inside the virtual serial console. You
+can launch @code{ls} for example. Type @key{Ctrl-a h} to have an help
+about the keys you can type inside the virtual serial console. In
+particular, use @key{Ctrl-a x} to exit QEMU and use @key{Ctrl-a b} as
+the Magic SysRq key.
+
+@item 
+If the network is enabled, launch the script @file{/etc/linuxrc} in the
+emulator (don't forget the leading dot):
+@example
+. /etc/linuxrc
+@end example
+
+Then enable X11 connections on your PC from the emulated Linux: 
+@example
+xhost +172.20.0.2
+@end example
+
+You can now launch @file{xterm} or @file{xlogo} and verify that you have
+a real Virtual Linux system !
+
+@end enumerate
+
+NOTES:
+@enumerate
+@item 
+A 2.5.74 kernel is also included in the archive. Just
+replace the bzImage in qemu.sh to try it.
+
+@item 
+qemu-fast creates a temporary file in @var{$QEMU_TMPDIR} (@file{/tmp} is the
+default) containing all the simulated PC memory. If possible, try to use
+a temporary directory using the tmpfs filesystem to avoid too many
+unnecessary disk accesses.
+
+@item 
+In order to exit cleanly from qemu, you can do a @emph{shutdown} inside
+qemu. qemu will automatically exit when the Linux shutdown is done.
+
+@item 
+You can boot slightly faster by disabling the probe of non present IDE
+interfaces. To do so, add the following options on the kernel command
+line:
+@example
+ide1=noprobe ide2=noprobe ide3=noprobe ide4=noprobe ide5=noprobe
+@end example
+
+@item 
+The example disk image is a modified version of the one made by Kevin
+Lawton for the plex86 Project (@url{www.plex86.org}).
+
+@end enumerate
+
+@node linux_compile
+@section Linux Kernel Compilation
+
+You can use any linux kernel with QEMU. However, if you want to use
+@code{qemu-fast} to get maximum performances, you must use a modified
+guest kernel. If you are using a 2.6 guest kernel, you can use
+directly the patch @file{linux-2.6-qemu-fast.patch} made by Rusty
+Russel available in the QEMU source archive. Otherwise, you can make the
+following changes @emph{by hand} to the Linux kernel:
+
+@enumerate
+@item
+The kernel must be mapped at 0x90000000 (the default is
+0xc0000000). You must modify only two lines in the kernel source:
+
+In @file{include/asm/page.h}, replace
+@example
+#define __PAGE_OFFSET           (0xc0000000)
+@end example
+by
+@example
+#define __PAGE_OFFSET           (0x90000000)
+@end example
+
+And in @file{arch/i386/vmlinux.lds}, replace
+@example
+  . = 0xc0000000 + 0x100000;
+@end example
+by 
+@example
+  . = 0x90000000 + 0x100000;
+@end example
+
+@item
+If you want to enable SMP (Symmetric Multi-Processing) support, you
+must make the following change in @file{include/asm/fixmap.h}. Replace
+@example
+#define FIXADDR_TOP    (0xffffX000UL)
+@end example
+by 
+@example
+#define FIXADDR_TOP    (0xa7ffX000UL)
+@end example
+(X is 'e' or 'f' depending on the kernel version). Although you can
+use an SMP kernel with QEMU, it only supports one CPU.
+
+@item
+If you are not using a 2.6 kernel as host kernel but if you use a target
+2.6 kernel, you must also ensure that the 'HZ' define is set to 100
+(1000 is the default) as QEMU cannot currently emulate timers at
+frequencies greater than 100 Hz on host Linux systems < 2.6. In
+@file{include/asm/param.h}, replace:
+
+@example
+# define HZ            1000            /* Internal kernel timer frequency */
+@end example
+by
+@example
+# define HZ            100             /* Internal kernel timer frequency */
+@end example
+
+@end enumerate
+
+The file config-2.x.x gives the configuration of the example kernels.
+
+Just type
+@example
+make bzImage
+@end example
+
+As you would do to make a real kernel. Then you can use with QEMU
+exactly the same kernel as you would boot on your PC (in
+@file{arch/i386/boot/bzImage}).
+
+@node gdb_usage
+@section GDB usage
+
+QEMU has a primitive support to work with gdb, so that you can do
+'Ctrl-C' while the virtual machine is running and inspect its state.
+
+In order to use gdb, launch qemu with the '-s' option. It will wait for a
+gdb connection:
+@example
+> qemu -s -kernel arch/i386/boot/bzImage -hda root-2.4.20.img -append "root=/dev/hda"
+Connected to host network interface: tun0
+Waiting gdb connection on port 1234
+@end example
+
+Then launch gdb on the 'vmlinux' executable:
+@example
+> gdb vmlinux
+@end example
+
+In gdb, connect to QEMU:
+@example
+(gdb) target remote localhost:1234
+@end example
+
+Then you can use gdb normally. For example, type 'c' to launch the kernel:
+@example
+(gdb) c
+@end example
+
+Here are some useful tips in order to use gdb on system code:
+
+@enumerate
+@item
+Use @code{info reg} to display all the CPU registers.
+@item
+Use @code{x/10i $eip} to display the code at the PC position.
+@item
+Use @code{set architecture i8086} to dump 16 bit code. Then use
+@code{x/10i $cs*16+*eip} to dump the code at the PC position.
+@end enumerate
+
+@section Target OS specific information
+
+@subsection Linux
+
+To have access to SVGA graphic modes under X11, use the @code{vesa} or
+the @code{cirrus} X11 driver. For optimal performances, use 16 bit
+color depth in the guest and the host OS.
+
+When using a 2.6 guest Linux kernel, you should add the option
+@code{clock=pit} on the kernel command line because the 2.6 Linux
+kernels make very strict real time clock checks by default that QEMU
+cannot simulate exactly.
+
+@subsection Windows
+
+If you have a slow host, using Windows 95 is better as it gives the
+best speed. Windows 2000 is also a good choice.
+
+@subsubsection SVGA graphic modes support
+
+QEMU emulates a Cirrus Logic GD5446 Video
+card. All Windows versions starting from Windows 95 should recognize
+and use this graphic card. For optimal performances, use 16 bit color
+depth in the guest and the host OS.
+
+@subsubsection CPU usage reduction
+
+Windows 9x does not correctly use the CPU HLT
+instruction. The result is that it takes host CPU cycles even when
+idle. You can install the utility from
+@url{http://www.user.cityline.ru/~maxamn/amnhltm.zip} to solve this
+problem. Note that no such tool is needed for NT, 2000 or XP.
+
+@subsubsection Windows 2000 disk full problems
+
+Currently (release 0.6.0) QEMU has a bug which gives a @code{disk
+full} error during installation of some releases of Windows 2000. The
+workaround is to stop QEMU as soon as you notice that your disk image
+size is growing too fast (monitor it with @code{ls -ls}). Then
+relaunch QEMU to continue the installation. If you still experience
+the problem, relaunch QEMU again.
+
+Future QEMU releases are likely to correct this bug.
+
+@subsubsection Windows XP security problems
+
+Some releases of Windows XP install correctly but give a security
+error when booting:
+@example
+A problem is preventing Windows from accurately checking the
+license for this computer. Error code: 0x800703e6.
+@end example
+The only known workaround is to boot in Safe mode
+without networking support. 
+
+Future QEMU releases are likely to correct this bug.
+
+@subsection MS-DOS and FreeDOS
+
+@subsubsection CPU usage reduction
+
+DOS does not correctly use the CPU HLT instruction. The result is that
+it takes host CPU cycles even when idle. You can install the utility
+from @url{http://www.vmware.com/software/dosidle210.zip} to solve this
+problem.
+
+@chapter QEMU PowerPC System emulator invocation
+
+Use the executable @file{qemu-system-ppc} to simulate a complete PREP
+or PowerMac PowerPC system.
+
+QEMU emulates the following PowerMac peripherials:
+
+@itemize @minus
+@item 
+UniNorth PCI Bridge 
+@item
+PCI VGA compatible card with VESA Bochs Extensions
+@item 
+2 PMAC IDE interfaces with hard disk and CD-ROM support
+@item 
+NE2000 PCI adapters
+@item
+Non Volatile RAM
+@item
+VIA-CUDA with ADB keyboard and mouse.
+@end itemize
+
+QEMU emulates the following PREP peripherials:
+
+@itemize @minus
+@item 
+PCI Bridge
+@item
+PCI VGA compatible card with VESA Bochs Extensions
+@item 
+2 IDE interfaces with hard disk and CD-ROM support
+@item
+Floppy disk
+@item 
+NE2000 network adapters
+@item
+Serial port
+@item
+PREP Non Volatile RAM
+@item
+PC compatible keyboard and mouse.
+@end itemize
+
+QEMU uses the Open Hack'Ware Open Firmware Compatible BIOS available at
+@url{http://site.voila.fr/jmayer/OpenHackWare/index.htm}.
+
+You can read the qemu PC system emulation chapter to have more
+informations about QEMU usage.
+
+@c man begin OPTIONS
+
+The following options are specific to the PowerPC emulation:
+
+@table @option
+
+@item -prep
+Simulate a PREP system (default is PowerMAC)
+
+@item -g WxH[xDEPTH]  
+
+Set the initial VGA graphic mode. The default is 800x600x15.
+
+@end table
+
+@c man end 
+
+
+More information is available at
+@url{http://jocelyn.mayer.free.fr/qemu-ppc/}.
+
+@chapter QEMU User space emulator invocation
+
+@section Quick Start
+
+In order to launch a Linux process, QEMU needs the process executable
+itself and all the target (x86) dynamic libraries used by it. 
+
+@itemize
+
+@item On x86, you can just try to launch any process by using the native
+libraries:
+
+@example 
+qemu-i386 -L / /bin/ls
+@end example
+
+@code{-L /} tells that the x86 dynamic linker must be searched with a
+@file{/} prefix.
+
+@item Since QEMU is also a linux process, you can launch qemu with qemu (NOTE: you can only do that if you compiled QEMU from the sources):
+
+@example 
+qemu-i386 -L / qemu-i386 -L / /bin/ls
+@end example
+
+@item On non x86 CPUs, you need first to download at least an x86 glibc
+(@file{qemu-runtime-i386-XXX-.tar.gz} on the QEMU web page). Ensure that
+@code{LD_LIBRARY_PATH} is not set:
+
+@example
+unset LD_LIBRARY_PATH 
+@end example
+
+Then you can launch the precompiled @file{ls} x86 executable:
+
+@example
+qemu-i386 tests/i386/ls
+@end example
+You can look at @file{qemu-binfmt-conf.sh} so that
+QEMU is automatically launched by the Linux kernel when you try to
+launch x86 executables. It requires the @code{binfmt_misc} module in the
+Linux kernel.
+
+@item The x86 version of QEMU is also included. You can try weird things such as:
+@example
+qemu-i386 /usr/local/qemu-i386/bin/qemu-i386 /usr/local/qemu-i386/bin/ls-i386
+@end example
+
+@end itemize
+
+@section Wine launch
+
+@itemize
+
+@item Ensure that you have a working QEMU with the x86 glibc
+distribution (see previous section). In order to verify it, you must be
+able to do:
+
+@example
+qemu-i386 /usr/local/qemu-i386/bin/ls-i386
+@end example
+
+@item Download the binary x86 Wine install
+(@file{qemu-XXX-i386-wine.tar.gz} on the QEMU web page). 
+
+@item Configure Wine on your account. Look at the provided script
+@file{/usr/local/qemu-i386/bin/wine-conf.sh}. Your previous
+@code{$@{HOME@}/.wine} directory is saved to @code{$@{HOME@}/.wine.org}.
+
+@item Then you can try the example @file{putty.exe}:
+
+@example
+qemu-i386 /usr/local/qemu-i386/wine/bin/wine /usr/local/qemu-i386/wine/c/Program\ Files/putty.exe
+@end example
+
+@end itemize
+
+@section Command line options
+
+@example
+usage: qemu-i386 [-h] [-d] [-L path] [-s size] program [arguments...]
+@end example
+
+@table @option
+@item -h
+Print the help
+@item -L path   
+Set the x86 elf interpreter prefix (default=/usr/local/qemu-i386)
+@item -s size
+Set the x86 stack size in bytes (default=524288)
+@end table
+
+Debug options:
+
+@table @option
+@item -d
+Activate log (logfile=/tmp/qemu.log)
+@item -p pagesize
+Act as if the host page size was 'pagesize' bytes
+@end table
+
+@node compilation
+@chapter Compilation from the sources
+
+@section Linux/BSD
+
+Read the @file{README} which gives the related information.
+
+@section Windows
+
+@itemize
+@item Install the current versions of MSYS and MinGW from
+@url{http://www.mingw.org/}. You can find detailed installation
+instructions in the download section and the FAQ.
+
+@item Download 
+the MinGW development library of SDL 1.2.x
+(@file{SDL-devel-1.2.x-mingw32.tar.gz}) from
+@url{http://www.libsdl.org}. Unpack it in a temporary place, and
+unpack the archive @file{i386-mingw32msvc.tar.gz} in the MinGW tool
+directory. Edit the @file{sdl-config} script so that it gives the
+correct SDL directory when invoked.
+
+@item Extract the current version of QEMU.
+@item Start the MSYS shell (file @file{msys.bat}).
+
+@item Change to the QEMU directory. Launch @file{./configure} and 
+@file{make}.  If you have problems using SDL, verify that
+@file{sdl-config} can be launched from the MSYS command line.
+
+@item You can install QEMU in @file{Program Files/Qemu} by typing 
+@file{make install}. Don't forget to copy @file{SDL.dll} in
+@file{Program Files/Qemu}.
+
+@end itemize
+
+@section Cross compilation for Windows with Linux
+
+@itemize
+@item
+Install the MinGW cross compilation tools available at
+@url{http://www.mingw.org/}.
+
+@item 
+Install the Win32 version of SDL (@url{http://www.libsdl.org}) by
+unpacking @file{i386-mingw32msvc.tar.gz}. Set up the PATH environment
+variable so that @file{i386-mingw32msvc-sdl-config} can be launched by
+the QEMU configuration script.
+
+@item 
+Configure QEMU for Windows cross compilation:
+@example
+./configure --enable-mingw32
+@end example
+If necessary, you can change the cross-prefix according to the prefix
+choosen for the MinGW tools with --cross-prefix. You can also use
+--prefix to set the Win32 install path.
+
+@item You can install QEMU in the installation directory by typing 
+@file{make install}. Don't forget to copy @file{SDL.dll} in the
+installation directory. 
+
+@end itemize
+
+Note: Currently, Wine does not seem able to launch
+QEMU for Win32.
+
+@section Mac OS X
+
+The Mac OS X patches are not fully merged in QEMU, so you should look
+at the QEMU mailing list archive to have all the necessary
+information.
+
diff --git a/tools/ioemu/qemu-img.c b/tools/ioemu/qemu-img.c
new file mode 100644 (file)
index 0000000..132428c
--- /dev/null
@@ -0,0 +1,698 @@
+/*
+ * create a COW disk image
+ * 
+ * Copyright (c) 2003 Fabrice Bellard
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+
+void *get_mmap_addr(unsigned long size)
+{
+    return NULL;
+}
+
+void qemu_free(void *ptr)
+{
+    free(ptr);
+}
+
+void *qemu_malloc(size_t size)
+{
+    return malloc(size);
+}
+
+void *qemu_mallocz(size_t size)
+{
+    void *ptr;
+    ptr = qemu_malloc(size);
+    if (!ptr)
+        return NULL;
+    memset(ptr, 0, size);
+    return ptr;
+}
+
+char *qemu_strdup(const char *str)
+{
+    char *ptr;
+    ptr = qemu_malloc(strlen(str) + 1);
+    if (!ptr)
+        return NULL;
+    strcpy(ptr, str);
+    return ptr;
+}
+
+void pstrcpy(char *buf, int buf_size, const char *str)
+{
+    int c;
+    char *q = buf;
+
+    if (buf_size <= 0)
+        return;
+
+    for(;;) {
+        c = *str++;
+        if (c == 0 || q >= buf + buf_size - 1)
+            break;
+        *q++ = c;
+    }
+    *q = '\0';
+}
+
+/* strcat and truncate. */
+char *pstrcat(char *buf, int buf_size, const char *s)
+{
+    int len;
+    len = strlen(buf);
+    if (len < buf_size) 
+        pstrcpy(buf + len, buf_size - len, s);
+    return buf;
+}
+
+int strstart(const char *str, const char *val, const char **ptr)
+{
+    const char *p, *q;
+    p = str;
+    q = val;
+    while (*q != '\0') {
+        if (*p != *q)
+            return 0;
+        p++;
+        q++;
+    }
+    if (ptr)
+        *ptr = p;
+    return 1;
+}
+
+void term_printf(const char *fmt, ...)
+{
+    va_list ap;
+    va_start(ap, fmt);
+    vprintf(fmt, ap);
+    va_end(ap);
+}
+
+void __attribute__((noreturn)) error(const char *fmt, ...) 
+{
+    va_list ap;
+    va_start(ap, fmt);
+    fprintf(stderr, "qemu-img: ");
+    vfprintf(stderr, fmt, ap);
+    fprintf(stderr, "\n");
+    exit(1);
+    va_end(ap);
+}
+
+static void format_print(void *opaque, const char *name)
+{
+    printf(" %s", name);
+}
+
+void help(void)
+{
+    printf("qemu-img version " QEMU_VERSION ", Copyright (c) 2004 Fabrice Bellard\n"
+           "usage: qemu-img command [command options]\n"
+           "QEMU disk image utility\n"
+           "\n"
+           "Command syntax:\n"
+           "  create [-e] [-b base_image] [-f fmt] filename [size]\n"
+           "  commit [-f fmt] filename\n"
+           "  convert [-c] [-e] [-f fmt] filename [-O output_fmt] output_filename\n"
+           "  info [-f fmt] filename\n"
+           "\n"
+           "Command parameters:\n"
+           "  'filename' is a disk image filename\n"
+           "  'base_image' is the read-only disk image which is used as base for a copy on\n"
+           "    write image; the copy on write image only stores the modified data\n"
+           "  'fmt' is the disk image format. It is guessed automatically in most cases\n"
+           "  'size' is the disk image size in kilobytes. Optional suffixes 'M' (megabyte)\n"
+           "    and 'G' (gigabyte) are supported\n"
+           "  'output_filename' is the destination disk image filename\n"
+           "  'output_fmt' is the destination format\n"
+           "  '-c' indicates that target image must be compressed (qcow format only)\n"
+           "  '-e' indicates that the target image must be encrypted (qcow format only)\n"
+           );
+    printf("\nSupported format:");
+    bdrv_iterate_format(format_print, NULL);
+    printf("\n");
+    exit(1);
+}
+
+
+#define NB_SUFFIXES 4
+
+static void get_human_readable_size(char *buf, int buf_size, int64_t size)
+{
+    char suffixes[NB_SUFFIXES] = "KMGT";
+    int64_t base;
+    int i;
+
+    if (size <= 999) {
+        snprintf(buf, buf_size, "%lld", size);
+    } else {
+        base = 1024;
+        for(i = 0; i < NB_SUFFIXES; i++) {
+            if (size < (10 * base)) {
+                snprintf(buf, buf_size, "%0.1f%c", 
+                         (double)size / base,
+                         suffixes[i]);
+                break;
+            } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) {
+                snprintf(buf, buf_size, "%lld%c", 
+                         (size + (base >> 1)) / base,
+                         suffixes[i]);
+                break;
+            }
+            base = base * 1024;
+        }
+    }
+}
+
+#if defined(WIN32)
+/* XXX: put correct support for win32 */
+static int read_password(char *buf, int buf_size)
+{
+    int c, i;
+    printf("Password: ");
+    fflush(stdout);
+    i = 0;
+    for(;;) {
+        c = getchar();
+        if (c == '\n')
+            break;
+        if (i < (buf_size - 1))
+            buf[i++] = c;
+    }
+    buf[i] = '\0';
+    return 0;
+}
+
+#else
+
+#include <termios.h>
+
+static struct termios oldtty;
+
+static void term_exit(void)
+{
+    tcsetattr (0, TCSANOW, &oldtty);
+}
+
+static void term_init(void)
+{
+    struct termios tty;
+
+    tcgetattr (0, &tty);
+    oldtty = tty;
+
+    tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
+                          |INLCR|IGNCR|ICRNL|IXON);
+    tty.c_oflag |= OPOST;
+    tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
+    tty.c_cflag &= ~(CSIZE|PARENB);
+    tty.c_cflag |= CS8;
+    tty.c_cc[VMIN] = 1;
+    tty.c_cc[VTIME] = 0;
+    
+    tcsetattr (0, TCSANOW, &tty);
+
+    atexit(term_exit);
+}
+
+int read_password(char *buf, int buf_size)
+{
+    uint8_t ch;
+    int i, ret;
+
+    printf("password: ");
+    fflush(stdout);
+    term_init();
+    i = 0;
+    for(;;) {
+        ret = read(0, &ch, 1);
+        if (ret == -1) {
+            if (errno == EAGAIN || errno == EINTR) {
+                continue;
+            } else {
+                ret = -1;
+                break;
+            }
+        } else if (ret == 0) {
+            ret = -1;
+            break;
+        } else {
+            if (ch == '\r') {
+                ret = 0;
+                break;
+            }
+            if (i < (buf_size - 1))
+                buf[i++] = ch;
+        }
+    }
+    term_exit();
+    buf[i] = '\0';
+    printf("\n");
+    return ret;
+}
+#endif
+
+static BlockDriverState *bdrv_new_open(const char *filename,
+                                       const char *fmt)
+{
+    BlockDriverState *bs;
+    BlockDriver *drv;
+    char password[256];
+
+    bs = bdrv_new("");
+    if (!bs)
+        error("Not enough memory");
+    if (fmt) {
+        drv = bdrv_find_format(fmt);
+        if (!drv)
+            error("Unknown file format '%s'", fmt);
+    } else {
+        drv = NULL;
+    }
+    if (bdrv_open2(bs, filename, 0, drv) < 0) {
+        error("Could not open '%s'", filename);
+    }
+    if (bdrv_is_encrypted(bs)) {
+        printf("Disk image '%s' is encrypted.\n", filename);
+        if (read_password(password, sizeof(password)) < 0)
+            error("No password given");
+        if (bdrv_set_key(bs, password) < 0)
+            error("invalid password");
+    }
+    return bs;
+}
+
+static int img_create(int argc, char **argv)
+{
+    int c, ret, encrypted;
+    const char *fmt = "raw";
+    const char *filename;
+    const char *base_filename = NULL;
+    int64_t size;
+    const char *p;
+    BlockDriver *drv;
+    
+    encrypted = 0;
+    for(;;) {
+        c = getopt(argc, argv, "b:f:he");
+        if (c == -1)
+            break;
+        switch(c) {
+        case 'h':
+            help();
+            break;
+        case 'b':
+            base_filename = optarg;
+            break;
+        case 'f':
+            fmt = optarg;
+            break;
+        case 'e':
+            encrypted = 1;
+            break;
+        }
+    }
+    if (optind >= argc) 
+        help();
+    filename = argv[optind++];
+    size = 0;
+    if (base_filename) {
+        BlockDriverState *bs;
+        bs = bdrv_new_open(base_filename, NULL);
+        bdrv_get_geometry(bs, &size);
+        size *= 512;
+        bdrv_delete(bs);
+    } else {
+        if (optind >= argc)
+            help();
+        p = argv[optind];
+        size = strtoul(p, (char **)&p, 0);
+        if (*p == 'M') {
+            size *= 1024 * 1024;
+        } else if (*p == 'G') {
+            size *= 1024 * 1024 * 1024;
+        } else if (*p == 'k' || *p == 'K' || *p == '\0') {
+            size *= 1024;
+        } else {
+            help();
+        }
+    }
+    drv = bdrv_find_format(fmt);
+    if (!drv)
+        error("Unknown file format '%s'", fmt);
+    printf("Formating '%s', fmt=%s",
+           filename, fmt);
+    if (encrypted)
+        printf(", encrypted");
+    if (base_filename) {
+        printf(", backing_file=%s",
+               base_filename);
+    }
+    printf(", size=%lld kB\n", size / 1024);
+    ret = bdrv_create(drv, filename, size / 512, base_filename, encrypted);
+    if (ret < 0) {
+        if (ret == -ENOTSUP) {
+            error("Formatting or formatting option not supported for file format '%s'", fmt);
+        } else {
+            error("Error while formatting");
+        }
+    }
+    return 0;
+}
+
+static int img_commit(int argc, char **argv)
+{
+    int c, ret;
+    const char *filename, *fmt;
+    BlockDriver *drv;
+    BlockDriverState *bs;
+
+    fmt = NULL;
+    for(;;) {
+        c = getopt(argc, argv, "f:h");
+        if (c == -1)
+            break;
+        switch(c) {
+        case 'h':
+            help();
+            break;
+        case 'f':
+            fmt = optarg;
+            break;
+        }
+    }
+    if (optind >= argc) 
+        help();
+    filename = argv[optind++];
+
+    bs = bdrv_new("");
+    if (!bs)
+        error("Not enough memory");
+    if (fmt) {
+        drv = bdrv_find_format(fmt);
+        if (!drv)
+            error("Unknown file format '%s'", fmt);
+    } else {
+        drv = NULL;
+    }
+    if (bdrv_open2(bs, filename, 0, drv) < 0) {
+        error("Could not open '%s'", filename);
+    }
+    ret = bdrv_commit(bs);
+    switch(ret) {
+    case 0:
+        printf("Image committed.\n");
+        break;
+    case -ENOENT:
+        error("No disk inserted");
+        break;
+    case -EACCES:
+        error("Image is read-only");
+        break;
+    case -ENOTSUP:
+        error("Image is already committed");
+        break;
+    default:
+        error("Error while committing image");
+        break;
+    }
+
+    bdrv_delete(bs);
+    return 0;
+}
+
+static int is_not_zero(const uint8_t *sector, int len)
+{
+    int i;
+    len >>= 2;
+    for(i = 0;i < len; i++) {
+        if (((uint32_t *)sector)[i] != 0)
+            return 1;
+    }
+    return 0;
+}
+
+static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
+{
+    int v, i;
+
+    if (n <= 0) {
+        *pnum = 0;
+        return 0;
+    }
+    v = is_not_zero(buf, 512);
+    for(i = 1; i < n; i++) {
+        buf += 512;
+        if (v != is_not_zero(buf, 512))
+            break;
+    }
+    *pnum = i;
+    return v;
+}
+
+#define IO_BUF_SIZE 65536
+
+static int img_convert(int argc, char **argv)
+{
+    int c, ret, n, n1, compress, cluster_size, cluster_sectors, encrypt;
+    const char *filename, *fmt, *out_fmt, *out_filename;
+    BlockDriver *drv;
+    BlockDriverState *bs, *out_bs;
+    int64_t total_sectors, nb_sectors, sector_num;
+    uint8_t buf[IO_BUF_SIZE];
+    const uint8_t *buf1;
+
+    fmt = NULL;
+    out_fmt = "raw";
+    compress = 0;
+    encrypt = 0;
+    for(;;) {
+        c = getopt(argc, argv, "f:O:hce");
+        if (c == -1)
+            break;
+        switch(c) {
+        case 'h':
+            help();
+            break;
+        case 'f':
+            fmt = optarg;
+            break;
+        case 'O':
+            out_fmt = optarg;
+            break;
+        case 'c':
+            compress = 1;
+            break;
+        case 'e':
+            encrypt = 1;
+            break;
+        }
+    }
+    if (optind >= argc) 
+        help();
+    filename = argv[optind++];
+    if (optind >= argc) 
+        help();
+    out_filename = argv[optind++];
+    
+    bs = bdrv_new_open(filename, fmt);
+
+    drv = bdrv_find_format(out_fmt);
+    if (!drv)
+        error("Unknown file format '%s'", fmt);
+    if (compress && drv != &bdrv_qcow)
+        error("Compression not supported for this file format");
+    if (encrypt && drv != &bdrv_qcow)
+        error("Encryption not supported for this file format");
+    if (compress && encrypt)
+        error("Compression and encryption not supported at the same time");
+    bdrv_get_geometry(bs, &total_sectors);
+    ret = bdrv_create(drv, out_filename, total_sectors, NULL, encrypt);
+    if (ret < 0) {
+        if (ret == -ENOTSUP) {
+            error("Formatting not supported for file format '%s'", fmt);
+        } else {
+            error("Error while formatting '%s'", out_filename);
+        }
+    }
+    
+    out_bs = bdrv_new_open(out_filename, out_fmt);
+
+    if (compress) {
+        cluster_size = qcow_get_cluster_size(out_bs);
+        if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE)
+            error("invalid cluster size");
+        cluster_sectors = cluster_size >> 9;
+        sector_num = 0;
+        for(;;) {
+            nb_sectors = total_sectors - sector_num;
+            if (nb_sectors <= 0)
+                break;
+            if (nb_sectors >= cluster_sectors)
+                n = cluster_sectors;
+            else
+                n = nb_sectors;
+            if (bdrv_read(bs, sector_num, buf, n) < 0) 
+                error("error while reading");
+            if (n < cluster_sectors)
+                memset(buf + n * 512, 0, cluster_size - n * 512);
+            if (is_not_zero(buf, cluster_size)) {
+                if (qcow_compress_cluster(out_bs, sector_num, buf) != 0)
+                    error("error while compressing sector %lld", sector_num);
+            }
+            sector_num += n;
+        }
+    } else {
+        sector_num = 0;
+        for(;;) {
+            nb_sectors = total_sectors - sector_num;
+            if (nb_sectors <= 0)
+                break;
+            if (nb_sectors >= (IO_BUF_SIZE / 512))
+                n = (IO_BUF_SIZE / 512);
+            else
+                n = nb_sectors;
+            if (bdrv_read(bs, sector_num, buf, n) < 0) 
+                error("error while reading");
+            /* NOTE: at the same time we convert, we do not write zero
+               sectors to have a chance to compress the image. Ideally, we
+               should add a specific call to have the info to go faster */
+            buf1 = buf;
+            while (n > 0) {
+                if (is_allocated_sectors(buf1, n, &n1)) {
+                    if (bdrv_write(out_bs, sector_num, buf1, n1) < 0) 
+                        error("error while writing");
+                }
+                sector_num += n1;
+                n -= n1;
+                buf1 += n1 * 512;
+            }
+        }
+    }
+    bdrv_delete(out_bs);
+    bdrv_delete(bs);
+    return 0;
+}
+
+#ifdef _WIN32
+static int64_t get_allocated_file_size(const char *filename)
+{
+    struct _stati64 st;
+    if (_stati64(filename, &st) < 0) 
+        return -1;
+    return st.st_size;
+}
+#else
+static int64_t get_allocated_file_size(const char *filename)
+{
+    struct stat st;
+    if (stat(filename, &st) < 0) 
+        return -1;
+    return (int64_t)st.st_blocks * 512;
+}
+#endif
+
+static int img_info(int argc, char **argv)
+{
+    int c;
+    const char *filename, *fmt;
+    BlockDriver *drv;
+    BlockDriverState *bs;
+    char fmt_name[128], size_buf[128], dsize_buf[128];
+    int64_t total_sectors, allocated_size;
+
+    fmt = NULL;
+    for(;;) {
+        c = getopt(argc, argv, "f:h");
+        if (c == -1)
+            break;
+        switch(c) {
+        case 'h':
+            help();
+            break;
+        case 'f':
+            fmt = optarg;
+            break;
+        }
+    }
+    if (optind >= argc) 
+        help();
+    filename = argv[optind++];
+
+    bs = bdrv_new("");
+    if (!bs)
+        error("Not enough memory");
+    if (fmt) {
+        drv = bdrv_find_format(fmt);
+        if (!drv)
+            error("Unknown file format '%s'", fmt);
+    } else {
+        drv = NULL;
+    }
+    if (bdrv_open2(bs, filename, 0, drv) < 0) {
+        error("Could not open '%s'", filename);
+    }
+    bdrv_get_format(bs, fmt_name, sizeof(fmt_name));
+    bdrv_get_geometry(bs, &total_sectors);
+    get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);
+    allocated_size = get_allocated_file_size(filename);
+    if (allocated_size < 0)
+        error("Could not get file size '%s'", filename);
+    get_human_readable_size(dsize_buf, sizeof(dsize_buf), 
+                            allocated_size);
+    printf("image: %s\n"
+           "file format: %s\n"
+           "virtual size: %s (%lld bytes)\n"
+           "disk size: %s\n",
+           filename, fmt_name, size_buf, 
+           total_sectors * 512,
+           dsize_buf);
+    if (bdrv_is_encrypted(bs))
+        printf("encrypted: yes\n");
+    bdrv_delete(bs);
+    return 0;
+}
+
+int main(int argc, char **argv)
+{
+    const char *cmd;
+
+    bdrv_init();
+    if (argc < 2)
+        help();
+    cmd = argv[1];
+    optind++;
+    if (!strcmp(cmd, "create")) {
+        img_create(argc, argv);
+    } else if (!strcmp(cmd, "commit")) {
+        img_commit(argc, argv);
+    } else if (!strcmp(cmd, "convert")) {
+        img_convert(argc, argv);
+    } else if (!strcmp(cmd, "info")) {
+        img_info(argc, argv);
+    } else {
+        help();
+    }
+    return 0;
+}
diff --git a/tools/ioemu/qemu-mkcow.1 b/tools/ioemu/qemu-mkcow.1
new file mode 100644 (file)
index 0000000..d156de6
--- /dev/null
@@ -0,0 +1,105 @@
+.\" $Header: /cvsroot/qemu/qemu/qemu-mkcow.1,v 1.1 2004/03/26 22:42:54 bellard Exp $
+.\"
+.\"    transcript compatibility for postscript use.
+.\"
+.\"    synopsis:  .P! <file.ps>
+.\"
+.de P!
+.fl
+\!!1 setgray
+.fl
+\\&.\"
+.fl
+\!!0 setgray
+.fl                    \" force out current output buffer
+\!!save /psv exch def currentpoint translate 0 0 moveto
+\!!/showpage{}def
+.fl                    \" prolog
+.sy sed -e 's/^/!/' \\$1\" bring in postscript file
+\!!psv restore
+.
+.de pF
+.ie     \a\\*(f1\a\a .ds f1 \\n(.f
+.el .ie \a\\*(f2\a\a .ds f2 \\n(.f
+.el .ie \a\\*(f3\a\a .ds f3 \\n(.f
+.el .ie \a\\*(f4\a\a .ds f4 \\n(.f
+.el .tm ? font overflow
+.ft \\$1
+..
+.de fP
+.ie     !\a\\*(f4\a\a \{\
+.      ft \\*(f4
+.      ds f4\"
+'      br \}
+.el .ie !\a\\*(f3\a\a \{\
+.      ft \\*(f3
+.      ds f3\"
+'      br \}
+.el .ie !\a\\*(f2\a\a \{\
+.      ft \\*(f2
+.      ds f2\"
+'      br \}
+.el .ie !\a\\*(f1\a\a \{\
+.      ft \\*(f1
+.      ds f1\"
+'      br \}
+.el .tm ? font underflow
+..
+.ds f1\"
+.ds f2\"
+.ds f3\"
+.ds f4\"
+'\" t 
+.ta 8n 16n 24n 32n 40n 48n 56n 64n 72n  
+.TH "QEMU" "8" 
+.SH "NAME" 
+qemu-mkcow \(em create a copy-on-write file for qemu 
+.SH "SYNOPSIS" 
+.PP 
+\fBqemu-mkcow\fR [\fB-h\fP]  [\fB-f \fImaster_disk_image\fR\fP]  [\fIcow_image\fR]  [\fB\fIcow_size\fR\fP]  
+.SH "DESCRIPTION" 
+.PP 
+The \fBqemu-mkcow\fR command creates a 
+persistent copy-on-write file for \fBqemu\fR. 
+.PP 
+\fBqemu\fR can be used in a "copy-on-write" mode, 
+where changes made by \fBqemu\fR do not actually 
+change the disk image file.  One way is to invoke 
+\fBqemu\fR with -snapshot: these changes 
+are stored in a temporary file, which is discarded when  
+\fBqemu\fR exits. 
+.PP 
+\fBqemu-mkcow\fR creates an explicit copy-on-write 
+file where changes are to be stored: this way, changes made 
+inside \fBqemu\fR will still be there next time you 
+run it, although the master disk image isn't ever changed. 
+.PP 
+The usual method is to create the master image, then create a 
+copy-on-write file using \fBqemu-mkcow\fR with 
+\fB-f\fP.  The filename of the master image is stored 
+inside the generated copy-on-write file: it must not be modified 
+after this is run! 
+.PP 
+If no master file is specified, the effect is that of a 
+blank master of size \fIcow_size\fR. 
+.SH "SEE ALSO" 
+.PP 
+qemu(1), qemu-fast(1). 
+.SH "AUTHOR" 
+.PP 
+This manual page was written by Paul Russell prussell@debian.org for 
+the \fBDebian\fP system (but may be used by others).  Permission is 
+granted to copy, distribute and/or modify this document under 
+the terms of the GNU General Public License, Version 2 any  
+later version published by the Free Software Foundation. 
+.PP 
+On Debian systems, the complete text of the GNU General Public 
+License can be found in /usr/share/common-licenses/GPL. 
+.\" created by instant / docbook-to-man, Fri 12 Mar 2004, 05:58 
diff --git a/tools/ioemu/qemu-tech.html b/tools/ioemu/qemu-tech.html
new file mode 100644 (file)
index 0000000..4277cfe
--- /dev/null
@@ -0,0 +1,1303 @@
+<HTML>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<!-- Created on January, 25  2005 by texi2html 1.64 -->
+<!-- 
+Written by: Lionel Cons <Lionel.Cons@cern.ch> (original author)
+            Karl Berry  <karl@freefriends.org>
+            Olaf Bachmann <obachman@mathematik.uni-kl.de>
+            and many others.
+Maintained by: Olaf Bachmann <obachman@mathematik.uni-kl.de>
+Send bugs and suggestions to <texi2html@mathematik.uni-kl.de>
+-->
+<HEAD>
+<TITLE>Untitled Document: </TITLE>
+
+<META NAME="description" CONTENT="Untitled Document: ">
+<META NAME="keywords" CONTENT="Untitled Document: ">
+<META NAME="resource-type" CONTENT="document">
+<META NAME="distribution" CONTENT="global">
+<META NAME="Generator" CONTENT="texi2html 1.64">
+
+</HEAD>
+
+<BODY LANG="" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000">
+
+<A NAME="SEC1"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC2"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<P>
+
+<H1> 1. Introduction </H1>
+<!--docid::SEC1::-->
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC2"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC3"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 1.1 Features </H2>
+<!--docid::SEC2::-->
+<P>
+
+QEMU is a FAST! processor emulator using a portable dynamic
+translator.
+</P><P>
+
+QEMU has two operating modes:
+</P><P>
+
+<UL>
+
+<LI>
+Full system emulation. In this mode, QEMU emulates a full system
+(usually a PC), including a processor and various peripherials. It can
+be used to launch an different Operating System without rebooting the
+PC or to debug system code.
+<P>
+
+<LI>
+User mode emulation (Linux host only). In this mode, QEMU can launch
+Linux processes compiled for one CPU on another CPU. It can be used to
+launch the Wine Windows API emulator (<A HREF="http://www.winehq.org">http://www.winehq.org</A>) or
+to ease cross-compilation and cross-debugging.
+<P>
+
+</UL>
+<P>
+
+As QEMU requires no host kernel driver to run, it is very safe and
+easy to use.
+</P><P>
+
+QEMU generic features:
+</P><P>
+
+<UL>
+
+<LI>User space only or full system emulation.
+<P>
+
+<LI>Using dynamic translation to native code for reasonnable speed.
+<P>
+
+<LI>Working on x86 and PowerPC hosts. Being tested on ARM, Sparc32, Alpha and S390.
+<P>
+
+<LI>Self-modifying code support.
+<P>
+
+<LI>Precise exceptions support.
+<P>
+
+<LI>The virtual CPU is a library (<CODE>libqemu</CODE>) which can be used
+in other projects (look at <TT>`qemu/tests/qruncom.c'</TT> to have an
+example of user mode <CODE>libqemu</CODE> usage).
+<P>
+
+</UL>
+<P>
+
+QEMU user mode emulation features:
+<UL>
+<LI>Generic Linux system call converter, including most ioctls.
+<P>
+
+<LI>clone() emulation using native CPU clone() to use Linux scheduler for threads.
+<P>
+
+<LI>Accurate signal handling by remapping host signals to target signals.
+</UL>
+</UL>
+
+QEMU full system emulation features:
+<UL>
+<LI>QEMU can either use a full software MMU for maximum portability or use the host system call mmap() to simulate the target MMU.
+</UL>
+
+<HR SIZE="6">
+<A NAME="SEC3"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC2"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC4"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 1.2 x86 emulation </H2>
+<!--docid::SEC3::-->
+<P>
+
+QEMU x86 target features:
+</P><P>
+
+<UL>
+
+<LI>The virtual x86 CPU supports 16 bit and 32 bit addressing with segmentation.
+LDT/GDT and IDT are emulated. VM86 mode is also supported to run DOSEMU.
+<P>
+
+<LI>Support of host page sizes bigger than 4KB in user mode emulation.
+<P>
+
+<LI>QEMU can emulate itself on x86.
+<P>
+
+<LI>An extensive Linux x86 CPU test program is included <TT>`tests/test-i386'</TT>.
+It can be used to test other x86 virtual CPUs.
+<P>
+
+</UL>
+<P>
+
+Current QEMU limitations:
+</P><P>
+
+<UL>
+
+<LI>No SSE/MMX support (yet).
+<P>
+
+<LI>No x86-64 support.
+<P>
+
+<LI>IPC syscalls are missing.
+<P>
+
+<LI>The x86 segment limits and access rights are not tested at every
+memory access (yet). Hopefully, very few OSes seem to rely on that for
+normal use.
+<P>
+
+<LI>On non x86 host CPUs, <CODE>double</CODE>s are used instead of the non standard
+10 byte <CODE>long double</CODE>s of x86 for floating point emulation to get
+maximum performances.
+<P>
+
+</UL>
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC4"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC3"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC5"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 1.3 ARM emulation </H2>
+<!--docid::SEC4::-->
+<P>
+
+<UL>
+
+<LI>Full ARM 7 user emulation.
+<P>
+
+<LI>NWFPE FPU support included in user Linux emulation.
+<P>
+
+<LI>Can run most ARM Linux binaries.
+<P>
+
+</UL>
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC5"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC4"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC6"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 1.4 PowerPC emulation </H2>
+<!--docid::SEC5::-->
+<P>
+
+<UL>
+
+<LI>Full PowerPC 32 bit emulation, including priviledged instructions,
+FPU and MMU.
+<P>
+
+<LI>Can run most PowerPC Linux binaries.
+<P>
+
+</UL>
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC6"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC5"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC7"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 1.5 SPARC emulation </H2>
+<!--docid::SEC6::-->
+<P>
+
+<UL>
+
+<LI>SPARC V8 user support, except FPU instructions.
+<P>
+
+<LI>Can run some SPARC Linux binaries.
+<P>
+
+</UL>
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC7"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC6"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC8"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1> 2. QEMU Internals </H1>
+<!--docid::SEC7::-->
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC8"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC7"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC9"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 2.1 QEMU compared to other emulators </H2>
+<!--docid::SEC8::-->
+<P>
+
+Like bochs <A HREF="qemu-tech.html#BIB3">[3]</A>, QEMU emulates an x86 CPU. But QEMU is much faster than
+bochs as it uses dynamic compilation. Bochs is closely tied to x86 PC
+emulation while QEMU can emulate several processors.
+</P><P>
+
+Like Valgrind <A HREF="qemu-tech.html#BIB2">[2]</A>, QEMU does user space emulation and dynamic
+translation. Valgrind is mainly a memory debugger while QEMU has no
+support for it (QEMU could be used to detect out of bound memory
+accesses as Valgrind, but it has no support to track uninitialised data
+as Valgrind does). The Valgrind dynamic translator generates better code
+than QEMU (in particular it does register allocation) but it is closely
+tied to an x86 host and target and has no support for precise exceptions
+and system emulation.
+</P><P>
+
+EM86 <A HREF="qemu-tech.html#BIB4">[4]</A> is the closest project to user space QEMU (and QEMU still uses
+some of its code, in particular the ELF file loader). EM86 was limited
+to an alpha host and used a proprietary and slow interpreter (the
+interpreter part of the FX!32 Digital Win32 code translator <A HREF="qemu-tech.html#BIB5">[5]</A>).
+</P><P>
+
+TWIN <A HREF="qemu-tech.html#BIB6">[6]</A> is a Windows API emulator like Wine. It is less accurate than
+Wine but includes a protected mode x86 interpreter to launch x86 Windows
+executables. Such an approach has greater potential because most of the
+Windows API is executed natively but it is far more difficult to develop
+because all the data structures and function parameters exchanged
+between the API and the x86 code must be converted.
+</P><P>
+
+User mode Linux <A HREF="qemu-tech.html#BIB7">[7]</A> was the only solution before QEMU to launch a
+Linux kernel as a process while not needing any host kernel
+patches. However, user mode Linux requires heavy kernel patches while
+QEMU accepts unpatched Linux kernels. The price to pay is that QEMU is
+slower.
+</P><P>
+
+The new Plex86 <A HREF="qemu-tech.html#BIB8">[8]</A> PC virtualizer is done in the same spirit as the
+qemu-fast system emulator. It requires a patched Linux kernel to work
+(you cannot launch the same kernel on your PC), but the patches are
+really small. As it is a PC virtualizer (no emulation is done except
+for some priveledged instructions), it has the potential of being
+faster than QEMU. The downside is that a complicated (and potentially
+unsafe) host kernel patch is needed.
+</P><P>
+
+The commercial PC Virtualizers (VMWare <A HREF="qemu-tech.html#BIB9">[9]</A>, VirtualPC <A HREF="qemu-tech.html#BIB10">[10]</A>, TwoOStwo
+<A HREF="qemu-tech.html#BIB11">[11]</A>) are faster than QEMU, but they all need specific, proprietary
+and potentially unsafe host drivers. Moreover, they are unable to
+provide cycle exact simulation as an emulator can.
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC9"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC8"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC10"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 2.2 Portable dynamic translation </H2>
+<!--docid::SEC9::-->
+<P>
+
+QEMU is a dynamic translator. When it first encounters a piece of code,
+it converts it to the host instruction set. Usually dynamic translators
+are very complicated and highly CPU dependent. QEMU uses some tricks
+which make it relatively easily portable and simple while achieving good
+performances.
+</P><P>
+
+The basic idea is to split every x86 instruction into fewer simpler
+instructions. Each simple instruction is implemented by a piece of C
+code (see <TT>`target-i386/op.c'</TT>). Then a compile time tool
+(<TT>`dyngen'</TT>) takes the corresponding object file (<TT>`op.o'</TT>)
+to generate a dynamic code generator which concatenates the simple
+instructions to build a function (see <TT>`op.h:dyngen_code()'</TT>).
+</P><P>
+
+In essence, the process is similar to <A HREF="qemu-tech.html#BIB1">[1]</A>, but more work is done at
+compile time. 
+</P><P>
+
+A key idea to get optimal performances is that constant parameters can
+be passed to the simple operations. For that purpose, dummy ELF
+relocations are generated with gcc for each constant parameter. Then,
+the tool (<TT>`dyngen'</TT>) can locate the relocations and generate the
+appriopriate C code to resolve them when building the dynamic code.
+</P><P>
+
+That way, QEMU is no more difficult to port than a dynamic linker.
+</P><P>
+
+To go even faster, GCC static register variables are used to keep the
+state of the virtual CPU.
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC10"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC9"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC11"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 2.3 Register allocation </H2>
+<!--docid::SEC10::-->
+<P>
+
+Since QEMU uses fixed simple instructions, no efficient register
+allocation can be done. However, because RISC CPUs have a lot of
+register, most of the virtual CPU state can be put in registers without
+doing complicated register allocation.
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC11"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC10"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC12"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 2.4 Condition code optimisations </H2>
+<!--docid::SEC11::-->
+<P>
+
+Good CPU condition codes emulation (<CODE>EFLAGS</CODE> register on x86) is a
+critical point to get good performances. QEMU uses lazy condition code
+evaluation: instead of computing the condition codes after each x86
+instruction, it just stores one operand (called <CODE>CC_SRC</CODE>), the
+result (called <CODE>CC_DST</CODE>) and the type of operation (called
+<CODE>CC_OP</CODE>).
+</P><P>
+
+<CODE>CC_OP</CODE> is almost never explicitely set in the generated code
+because it is known at translation time.
+</P><P>
+
+In order to increase performances, a backward pass is performed on the
+generated simple instructions (see
+<CODE>target-i386/translate.c:optimize_flags()</CODE>). When it can be proved that
+the condition codes are not needed by the next instructions, no
+condition codes are computed at all.
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC12"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC11"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC13"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 2.5 CPU state optimisations </H2>
+<!--docid::SEC12::-->
+<P>
+
+The x86 CPU has many internal states which change the way it evaluates
+instructions. In order to achieve a good speed, the translation phase
+considers that some state information of the virtual x86 CPU cannot
+change in it. For example, if the SS, DS and ES segments have a zero
+base, then the translator does not even generate an addition for the
+segment base.
+</P><P>
+
+[The FPU stack pointer register is not handled that way yet].
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC13"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC12"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC14"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 2.6 Translation cache </H2>
+<!--docid::SEC13::-->
+<P>
+
+A 16 MByte cache holds the most recently used translations. For
+simplicity, it is completely flushed when it is full. A translation unit
+contains just a single basic block (a block of x86 instructions
+terminated by a jump or by a virtual CPU state change which the
+translator cannot deduce statically).
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC14"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC13"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC15"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 2.7 Direct block chaining </H2>
+<!--docid::SEC14::-->
+<P>
+
+After each translated basic block is executed, QEMU uses the simulated
+Program Counter (PC) and other cpu state informations (such as the CS
+segment base value) to find the next basic block.
+</P><P>
+
+In order to accelerate the most common cases where the new simulated PC
+is known, QEMU can patch a basic block so that it jumps directly to the
+next one.
+</P><P>
+
+The most portable code uses an indirect jump. An indirect jump makes
+it easier to make the jump target modification atomic. On some host
+architectures (such as x86 or PowerPC), the <CODE>JUMP</CODE> opcode is
+directly patched so that the block chaining has no overhead.
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC15"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC14"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC16"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 2.8 Self-modifying code and translated code invalidation </H2>
+<!--docid::SEC15::-->
+<P>
+
+Self-modifying code is a special challenge in x86 emulation because no
+instruction cache invalidation is signaled by the application when code
+is modified.
+</P><P>
+
+When translated code is generated for a basic block, the corresponding
+host page is write protected if it is not already read-only (with the
+system call <CODE>mprotect()</CODE>). Then, if a write access is done to the
+page, Linux raises a SEGV signal. QEMU then invalidates all the
+translated code in the page and enables write accesses to the page.
+</P><P>
+
+Correct translated code invalidation is done efficiently by maintaining
+a linked list of every translated block contained in a given page. Other
+linked lists are also maintained to undo direct block chaining. 
+</P><P>
+
+Although the overhead of doing <CODE>mprotect()</CODE> calls is important,
+most MSDOS programs can be emulated at reasonnable speed with QEMU and
+DOSEMU.
+</P><P>
+
+Note that QEMU also invalidates pages of translated code when it detects
+that memory mappings are modified with <CODE>mmap()</CODE> or <CODE>munmap()</CODE>.
+</P><P>
+
+When using a software MMU, the code invalidation is more efficient: if
+a given code page is invalidated too often because of write accesses,
+then a bitmap representing all the code inside the page is
+built. Every store into that page checks the bitmap to see if the code
+really needs to be invalidated. It avoids invalidating the code when
+only data is modified in the page.
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC16"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC15"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC17"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 2.9 Exception support </H2>
+<!--docid::SEC16::-->
+<P>
+
+longjmp() is used when an exception such as division by zero is
+encountered. 
+</P><P>
+
+The host SIGSEGV and SIGBUS signal handlers are used to get invalid
+memory accesses. The exact CPU state can be retrieved because all the
+x86 registers are stored in fixed host registers. The simulated program
+counter is found by retranslating the corresponding basic block and by
+looking where the host program counter was at the exception point.
+</P><P>
+
+The virtual CPU cannot retrieve the exact <CODE>EFLAGS</CODE> register because
+in some cases it is not computed because of condition code
+optimisations. It is not a big concern because the emulated code can
+still be restarted in any cases.
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC17"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC16"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC18"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 2.10 MMU emulation </H2>
+<!--docid::SEC17::-->
+<P>
+
+For system emulation, QEMU uses the mmap() system call to emulate the
+target CPU MMU. It works as long the emulated OS does not use an area
+reserved by the host OS (such as the area above 0xc0000000 on x86
+Linux).
+</P><P>
+
+In order to be able to launch any OS, QEMU also supports a soft
+MMU. In that mode, the MMU virtual to physical address translation is
+done at every memory access. QEMU uses an address translation cache to
+speed up the translation.
+</P><P>
+
+In order to avoid flushing the translated code each time the MMU
+mappings change, QEMU uses a physically indexed translation cache. It
+means that each basic block is indexed with its physical address. 
+</P><P>
+
+When MMU mappings change, only the chaining of the basic blocks is
+reset (i.e. a basic block can no longer jump directly to another one).
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC18"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC17"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC19"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 2.11 Hardware interrupts </H2>
+<!--docid::SEC18::-->
+<P>
+
+In order to be faster, QEMU does not check at every basic block if an
+hardware interrupt is pending. Instead, the user must asynchrously
+call a specific function to tell that an interrupt is pending. This
+function resets the chaining of the currently executing basic
+block. It ensures that the execution will return soon in the main loop
+of the CPU emulator. Then the main loop can test if the interrupt is
+pending and handle it.
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC19"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC18"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC20"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 2.12 User emulation specific details </H2>
+<!--docid::SEC19::-->
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC20"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC19"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC21"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H3> 2.12.1 Linux system call translation </H3>
+<!--docid::SEC20::-->
+<P>
+
+QEMU includes a generic system call translator for Linux. It means that
+the parameters of the system calls can be converted to fix the
+endianness and 32/64 bit issues. The IOCTLs are converted with a generic
+type description system (see <TT>`ioctls.h'</TT> and <TT>`thunk.c'</TT>).
+</P><P>
+
+QEMU supports host CPUs which have pages bigger than 4KB. It records all
+the mappings the process does and try to emulated the <CODE>mmap()</CODE>
+system calls in cases where the host <CODE>mmap()</CODE> call would fail
+because of bad page alignment.
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC21"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC20"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC22"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H3> 2.12.2 Linux signals </H3>
+<!--docid::SEC21::-->
+<P>
+
+Normal and real-time signals are queued along with their information
+(<CODE>siginfo_t</CODE>) as it is done in the Linux kernel. Then an interrupt
+request is done to the virtual CPU. When it is interrupted, one queued
+signal is handled by generating a stack frame in the virtual CPU as the
+Linux kernel does. The <CODE>sigreturn()</CODE> system call is emulated to return
+from the virtual signal handler.
+</P><P>
+
+Some signals (such as SIGALRM) directly come from the host. Other
+signals are synthetized from the virtual CPU exceptions such as SIGFPE
+when a division by zero is done (see <CODE>main.c:cpu_loop()</CODE>).
+</P><P>
+
+The blocked signal mask is still handled by the host Linux kernel so
+that most signal system calls can be redirected directly to the host
+Linux kernel. Only the <CODE>sigaction()</CODE> and <CODE>sigreturn()</CODE> system
+calls need to be fully emulated (see <TT>`signal.c'</TT>).
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC22"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC21"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC23"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H3> 2.12.3 clone() system call and threads </H3>
+<!--docid::SEC22::-->
+<P>
+
+The Linux clone() system call is usually used to create a thread. QEMU
+uses the host clone() system call so that real host threads are created
+for each emulated thread. One virtual CPU instance is created for each
+thread.
+</P><P>
+
+The virtual x86 CPU atomic operations are emulated with a global lock so
+that their semantic is preserved.
+</P><P>
+
+Note that currently there are still some locking issues in QEMU. In
+particular, the translated cache flush is not protected yet against
+reentrancy.
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC23"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC22"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC24"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H3> 2.12.4 Self-virtualization </H3>
+<!--docid::SEC23::-->
+<P>
+
+QEMU was conceived so that ultimately it can emulate itself. Although
+it is not very useful, it is an important test to show the power of the
+emulator.
+</P><P>
+
+Achieving self-virtualization is not easy because there may be address
+space conflicts. QEMU solves this problem by being an executable ELF
+shared object as the ld-linux.so ELF interpreter. That way, it can be
+relocated at load time.
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC24"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC23"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC25"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 2.13 Bibliography </H2>
+<!--docid::SEC24::-->
+<P>
+
+<DL COMPACT>
+
+<DT><A NAME="BIB1">[1]</A>
+<DD><A HREF="http://citeseer.nj.nec.com/piumarta98optimizing.html">http://citeseer.nj.nec.com/piumarta98optimizing.html</A>, Optimizing
+direct threaded code by selective inlining (1998) by Ian Piumarta, Fabio
+Riccardi.
+<P>
+
+<DT><A NAME="BIB2">[2]</A>
+<DD><A HREF="http://developer.kde.org/~sewardj/">http://developer.kde.org/~sewardj/</A>, Valgrind, an open-source
+memory debugger for x86-GNU/Linux, by Julian Seward.
+<P>
+
+<DT><A NAME="BIB3">[3]</A>
+<DD><A HREF="http://bochs.sourceforge.net/">http://bochs.sourceforge.net/</A>, the Bochs IA-32 Emulator Project,
+by Kevin Lawton et al.
+<P>
+
+<DT><A NAME="BIB4">[4]</A>
+<DD><A HREF="http://www.cs.rose-hulman.edu/~donaldlf/em86/index.html">http://www.cs.rose-hulman.edu/~donaldlf/em86/index.html</A>, the EM86
+x86 emulator on Alpha-Linux.
+<P>
+
+<DT><A NAME="BIB5">[5]</A>
+<DD><A HREF="http://www.usenix.org/publications/library/proceedings/usenix-nt97/full_papers/chernoff/chernoff.pdf">http://www.usenix.org/publications/library/proceedings/usenix-nt97/full_papers/chernoff/chernoff.pdf</A>,
+DIGITAL FX!32: Running 32-Bit x86 Applications on Alpha NT, by Anton
+Chernoff and Ray Hookway.
+<P>
+
+<DT><A NAME="BIB6">[6]</A>
+<DD><A HREF="http://www.willows.com/">http://www.willows.com/</A>, Windows API library emulation from
+Willows Software.
+<P>
+
+<DT><A NAME="BIB7">[7]</A>
+<DD><A HREF="http://user-mode-linux.sourceforge.net/">http://user-mode-linux.sourceforge.net/</A>, 
+The User-mode Linux Kernel.
+<P>
+
+<DT><A NAME="BIB8">[8]</A>
+<DD><A HREF="http://www.plex86.org/">http://www.plex86.org/</A>, 
+The new Plex86 project.
+<P>
+
+<DT><A NAME="BIB9">[9]</A>
+<DD><A HREF="http://www.vmware.com/">http://www.vmware.com/</A>, 
+The VMWare PC virtualizer.
+<P>
+
+<DT><A NAME="BIB10">[10]</A>
+<DD><A HREF="http://www.microsoft.com/windowsxp/virtualpc/">http://www.microsoft.com/windowsxp/virtualpc/</A>, 
+The VirtualPC PC virtualizer.
+<P>
+
+<DT><A NAME="BIB11">[11]</A>
+<DD><A HREF="http://www.twoostwo.org/">http://www.twoostwo.org/</A>, 
+The TwoOStwo PC virtualizer.
+<P>
+
+</DL>
+<P>
+
+<HR SIZE="6">
+<A NAME="SEC25"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC24"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC26"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1> 3. Regression Tests </H1>
+<!--docid::SEC25::-->
+<P>
+
+In the directory <TT>`tests/'</TT>, various interesting testing programs
+are available. There are used for regression testing.
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC26"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC25"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC27"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 3.1 <TT>`test-i386'</TT> </H2>
+<!--docid::SEC26::-->
+<P>
+
+This program executes most of the 16 bit and 32 bit x86 instructions and
+generates a text output. It can be compared with the output obtained with
+a real CPU or another emulator. The target <CODE>make test</CODE> runs this
+program and a <CODE>diff</CODE> on the generated output.
+</P><P>
+
+The Linux system call <CODE>modify_ldt()</CODE> is used to create x86 selectors
+to test some 16 bit addressing and 32 bit with segmentation cases.
+</P><P>
+
+The Linux system call <CODE>vm86()</CODE> is used to test vm86 emulation.
+</P><P>
+
+Various exceptions are raised to test most of the x86 user space
+exception reporting.
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC27"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC26"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC28"> &gt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 3.2 <TT>`linux-test'</TT> </H2>
+<!--docid::SEC27::-->
+<P>
+
+This program tests various Linux system calls. It is used to verify
+that the system call parameters are correctly converted between target
+and host CPUs.
+</P><P>
+
+<HR SIZE="6">
+<A NAME="SEC28"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC27"> &lt; </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[ &lt;&lt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1"> Up </A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[ &gt;&gt; ]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT"> &nbsp; <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H2> 3.3 <TT>`qruncom.c'</TT> </H2>
+<!--docid::SEC28::-->
+<P>
+
+Example of usage of <CODE>libqemu</CODE> to emulate a user mode i386 CPU.
+<HR SIZE="6">
+<A NAME="SEC_Contents"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1>Table of Contents</H1>
+<UL>
+<A NAME="TOC1" HREF="qemu-tech.html#SEC1">1. Introduction</A>
+<BR>
+<UL>
+<A NAME="TOC2" HREF="qemu-tech.html#SEC2">1.1 Features</A>
+<BR>
+<A NAME="TOC3" HREF="qemu-tech.html#SEC3">1.2 x86 emulation</A>
+<BR>
+<A NAME="TOC4" HREF="qemu-tech.html#SEC4">1.3 ARM emulation</A>
+<BR>
+<A NAME="TOC5" HREF="qemu-tech.html#SEC5">1.4 PowerPC emulation</A>
+<BR>
+<A NAME="TOC6" HREF="qemu-tech.html#SEC6">1.5 SPARC emulation</A>
+<BR>
+</UL>
+<A NAME="TOC7" HREF="qemu-tech.html#SEC7">2. QEMU Internals</A>
+<BR>
+<UL>
+<A NAME="TOC8" HREF="qemu-tech.html#SEC8">2.1 QEMU compared to other emulators</A>
+<BR>
+<A NAME="TOC9" HREF="qemu-tech.html#SEC9">2.2 Portable dynamic translation</A>
+<BR>
+<A NAME="TOC10" HREF="qemu-tech.html#SEC10">2.3 Register allocation</A>
+<BR>
+<A NAME="TOC11" HREF="qemu-tech.html#SEC11">2.4 Condition code optimisations</A>
+<BR>
+<A NAME="TOC12" HREF="qemu-tech.html#SEC12">2.5 CPU state optimisations</A>
+<BR>
+<A NAME="TOC13" HREF="qemu-tech.html#SEC13">2.6 Translation cache</A>
+<BR>
+<A NAME="TOC14" HREF="qemu-tech.html#SEC14">2.7 Direct block chaining</A>
+<BR>
+<A NAME="TOC15" HREF="qemu-tech.html#SEC15">2.8 Self-modifying code and translated code invalidation</A>
+<BR>
+<A NAME="TOC16" HREF="qemu-tech.html#SEC16">2.9 Exception support</A>
+<BR>
+<A NAME="TOC17" HREF="qemu-tech.html#SEC17">2.10 MMU emulation</A>
+<BR>
+<A NAME="TOC18" HREF="qemu-tech.html#SEC18">2.11 Hardware interrupts</A>
+<BR>
+<A NAME="TOC19" HREF="qemu-tech.html#SEC19">2.12 User emulation specific details</A>
+<BR>
+<UL>
+<A NAME="TOC20" HREF="qemu-tech.html#SEC20">2.12.1 Linux system call translation</A>
+<BR>
+<A NAME="TOC21" HREF="qemu-tech.html#SEC21">2.12.2 Linux signals</A>
+<BR>
+<A NAME="TOC22" HREF="qemu-tech.html#SEC22">2.12.3 clone() system call and threads</A>
+<BR>
+<A NAME="TOC23" HREF="qemu-tech.html#SEC23">2.12.4 Self-virtualization</A>
+<BR>
+</UL>
+<A NAME="TOC24" HREF="qemu-tech.html#SEC24">2.13 Bibliography</A>
+<BR>
+</UL>
+<A NAME="TOC25" HREF="qemu-tech.html#SEC25">3. Regression Tests</A>
+<BR>
+<UL>
+<A NAME="TOC26" HREF="qemu-tech.html#SEC26">3.1 <TT>`test-i386'</TT></A>
+<BR>
+<A NAME="TOC27" HREF="qemu-tech.html#SEC27">3.2 <TT>`linux-test'</TT></A>
+<BR>
+<A NAME="TOC28" HREF="qemu-tech.html#SEC28">3.3 <TT>`qruncom.c'</TT></A>
+<BR>
+</UL>
+</UL>
+<HR SIZE=1>
+<A NAME="SEC_OVERVIEW"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1>Short Table of Contents</H1>
+<BLOCKQUOTE>
+<A NAME="TOC1" HREF="qemu-tech.html#SEC1">1. Introduction</A>
+<BR>
+<A NAME="TOC7" HREF="qemu-tech.html#SEC7">2. QEMU Internals</A>
+<BR>
+<A NAME="TOC25" HREF="qemu-tech.html#SEC25">3. Regression Tests</A>
+<BR>
+
+</BLOCKQUOTE>
+<HR SIZE=1>
+<A NAME="SEC_About"></A>
+<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
+<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC1">Top</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_Contents">Contents</A>]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD>
+<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="qemu-tech.html#SEC_About"> ? </A>]</TD>
+</TR></TABLE>
+<H1>About this document</H1>
+This document was generated on <I>January, 25  2005</I>
+using <A HREF="http://www.mathematik.uni-kl.de/~obachman/Texi2html
+"><I>texi2html</I></A>
+<P></P>  
+The buttons in the navigation panels have the following meaning:
+<P></P>
+<table border = "1">
+<TR>
+<TH> Button </TH>
+<TH> Name </TH>
+<TH> Go to </TH>
+<TH> From 1.2.3 go to</TH>
+</TR>
+<TR>
+<TD ALIGN="CENTER">
+ [ &lt; ] </TD>
+<TD ALIGN="CENTER">
+Back
+</TD>
+<TD>
+previous section in reading order
+</TD>
+<TD>
+1.2.2
+</TD>
+</TR>
+<TR>
+<TD ALIGN="CENTER">
+ [ &gt; ] </TD>
+<TD ALIGN="CENTER">
+Forward
+</TD>
+<TD>
+next section in reading order
+</TD>
+<TD>
+1.2.4
+</TD>
+</TR>
+<TR>
+<TD ALIGN="CENTER">
+ [ &lt;&lt; ] </TD>
+<TD ALIGN="CENTER">
+FastBack
+</TD>
+<TD>
+previous or up-and-previous section 
+</TD>
+<TD>
+1.1
+</TD>
+</TR>
+<TR>
+<TD ALIGN="CENTER">
+ [ Up ] </TD>
+<TD ALIGN="CENTER">
+Up
+</TD>
+<TD>
+up section
+</TD>
+<TD>
+1.2
+</TD>
+</TR>
+<TR>
+<TD ALIGN="CENTER">
+ [ &gt;&gt; ] </TD>
+<TD ALIGN="CENTER">
+FastForward
+</TD>
+<TD>
+next or up-and-next section
+</TD>
+<TD>
+1.3
+</TD>
+</TR>
+<TR>
+<TD ALIGN="CENTER">
+ [Top] </TD>
+<TD ALIGN="CENTER">
+Top
+</TD>
+<TD>
+cover (top) of document
+</TD>
+<TD>
+ &nbsp; 
+</TD>
+</TR>
+<TR>
+<TD ALIGN="CENTER">
+ [Contents] </TD>
+<TD ALIGN="CENTER">
+Contents
+</TD>
+<TD>
+table of contents
+</TD>
+<TD>
+ &nbsp; 
+</TD>
+</TR>
+<TR>
+<TD ALIGN="CENTER">
+ [Index] </TD>
+<TD ALIGN="CENTER">
+Index
+</TD>
+<TD>
+concept index
+</TD>
+<TD>
+ &nbsp; 
+</TD>
+</TR>
+<TR>
+<TD ALIGN="CENTER">
+ [ ? ] </TD>
+<TD ALIGN="CENTER">
+About
+</TD>
+<TD>
+this page
+</TD>
+<TD>
+ &nbsp; 
+</TD>
+</TR>
+</TABLE>
+<P></P>
+where the <STRONG> Example </STRONG> assumes that the current position 
+is at <STRONG> Subsubsection One-Two-Three </STRONG> of a document of 
+the following structure:
+<UL>
+<LI> 1. Section One  </LI>
+<UL>
+<LI>1.1 Subsection One-One</LI>
+<UL>
+<LI> ... </LI>
+</UL>
+<LI>1.2 Subsection One-Two</LI>
+<UL>
+<LI>1.2.1 Subsubsection One-Two-One
+</LI><LI>1.2.2 Subsubsection One-Two-Two
+</LI><LI>1.2.3 Subsubsection One-Two-Three &nbsp; &nbsp; <STRONG>
+&lt;== Current Position </STRONG>
+</LI><LI>1.2.4 Subsubsection One-Two-Four
+</LI></UL>
+<LI>1.3 Subsection One-Three</LI>
+<UL>
+<LI> ... </LI>
+</UL>
+<LI>1.4 Subsection One-Four</LI>
+</UL>
+</UL>
+
+<HR SIZE=1>
+<BR>  
+<FONT SIZE="-1">
+This document was generated
+on <I>January, 25  2005</I>
+using <A HREF="http://www.mathematik.uni-kl.de/~obachman/Texi2html
+"><I>texi2html</I></A>
+
+</BODY>
+</HTML>
diff --git a/tools/ioemu/qemu-tech.texi b/tools/ioemu/qemu-tech.texi
new file mode 100644 (file)
index 0000000..4e6f507
--- /dev/null
@@ -0,0 +1,494 @@
+\input texinfo @c -*- texinfo -*-
+
+@iftex
+@settitle QEMU Internals
+@titlepage
+@sp 7
+@center @titlefont{QEMU Internals}
+@sp 3
+@end titlepage
+@end iftex
+
+@chapter Introduction
+
+@section Features
+
+QEMU is a FAST! processor emulator using a portable dynamic
+translator.
+
+QEMU has two operating modes:
+
+@itemize @minus
+
+@item 
+Full system emulation. In this mode, QEMU emulates a full system
+(usually a PC), including a processor and various peripherials. It can
+be used to launch an different Operating System without rebooting the
+PC or to debug system code.
+
+@item 
+User mode emulation (Linux host only). In this mode, QEMU can launch
+Linux processes compiled for one CPU on another CPU. It can be used to
+launch the Wine Windows API emulator (@url{http://www.winehq.org}) or
+to ease cross-compilation and cross-debugging.
+
+@end itemize
+
+As QEMU requires no host kernel driver to run, it is very safe and
+easy to use.
+
+QEMU generic features:
+
+@itemize 
+
+@item User space only or full system emulation.
+
+@item Using dynamic translation to native code for reasonnable speed.
+
+@item Working on x86 and PowerPC hosts. Being tested on ARM, Sparc32, Alpha and S390.
+
+@item Self-modifying code support.
+
+@item Precise exceptions support.
+
+@item The virtual CPU is a library (@code{libqemu}) which can be used 
+in other projects (look at @file{qemu/tests/qruncom.c} to have an
+example of user mode @code{libqemu} usage).
+
+@end itemize
+
+QEMU user mode emulation features:
+@itemize 
+@item Generic Linux system call converter, including most ioctls.
+
+@item clone() emulation using native CPU clone() to use Linux scheduler for threads.
+
+@item Accurate signal handling by remapping host signals to target signals. 
+@end itemize
+@end itemize
+
+QEMU full system emulation features:
+@itemize 
+@item QEMU can either use a full software MMU for maximum portability or use the host system call mmap() to simulate the target MMU.
+@end itemize
+
+@section x86 emulation
+
+QEMU x86 target features:
+
+@itemize 
+
+@item The virtual x86 CPU supports 16 bit and 32 bit addressing with segmentation. 
+LDT/GDT and IDT are emulated. VM86 mode is also supported to run DOSEMU.
+
+@item Support of host page sizes bigger than 4KB in user mode emulation.
+
+@item QEMU can emulate itself on x86.
+
+@item An extensive Linux x86 CPU test program is included @file{tests/test-i386}. 
+It can be used to test other x86 virtual CPUs.
+
+@end itemize
+
+Current QEMU limitations:
+
+@itemize 
+
+@item No SSE/MMX support (yet).
+
+@item No x86-64 support.
+
+@item IPC syscalls are missing.
+
+@item The x86 segment limits and access rights are not tested at every 
+memory access (yet). Hopefully, very few OSes seem to rely on that for
+normal use.
+
+@item On non x86 host CPUs, @code{double}s are used instead of the non standard 
+10 byte @code{long double}s of x86 for floating point emulation to get
+maximum performances.
+
+@end itemize
+
+@section ARM emulation
+
+@itemize
+
+@item Full ARM 7 user emulation.
+
+@item NWFPE FPU support included in user Linux emulation.
+
+@item Can run most ARM Linux binaries.
+
+@end itemize
+
+@section PowerPC emulation
+
+@itemize
+
+@item Full PowerPC 32 bit emulation, including priviledged instructions, 
+FPU and MMU.
+
+@item Can run most PowerPC Linux binaries.
+
+@end itemize
+
+@section SPARC emulation
+
+@itemize
+
+@item SPARC V8 user support, except FPU instructions.
+
+@item Can run some SPARC Linux binaries.
+
+@end itemize
+
+@chapter QEMU Internals
+
+@section QEMU compared to other emulators
+
+Like bochs [3], QEMU emulates an x86 CPU. But QEMU is much faster than
+bochs as it uses dynamic compilation. Bochs is closely tied to x86 PC
+emulation while QEMU can emulate several processors.
+
+Like Valgrind [2], QEMU does user space emulation and dynamic
+translation. Valgrind is mainly a memory debugger while QEMU has no
+support for it (QEMU could be used to detect out of bound memory
+accesses as Valgrind, but it has no support to track uninitialised data
+as Valgrind does). The Valgrind dynamic translator generates better code
+than QEMU (in particular it does register allocation) but it is closely
+tied to an x86 host and target and has no support for precise exceptions
+and system emulation.
+
+EM86 [4] is the closest project to user space QEMU (and QEMU still uses
+some of its code, in particular the ELF file loader). EM86 was limited
+to an alpha host and used a proprietary and slow interpreter (the
+interpreter part of the FX!32 Digital Win32 code translator [5]).
+
+TWIN [6] is a Windows API emulator like Wine. It is less accurate than
+Wine but includes a protected mode x86 interpreter to launch x86 Windows
+executables. Such an approach has greater potential because most of the
+Windows API is executed natively but it is far more difficult to develop
+because all the data structures and function parameters exchanged
+between the API and the x86 code must be converted.
+
+User mode Linux [7] was the only solution before QEMU to launch a
+Linux kernel as a process while not needing any host kernel
+patches. However, user mode Linux requires heavy kernel patches while
+QEMU accepts unpatched Linux kernels. The price to pay is that QEMU is
+slower.
+
+The new Plex86 [8] PC virtualizer is done in the same spirit as the
+qemu-fast system emulator. It requires a patched Linux kernel to work
+(you cannot launch the same kernel on your PC), but the patches are
+really small. As it is a PC virtualizer (no emulation is done except
+for some priveledged instructions), it has the potential of being
+faster than QEMU. The downside is that a complicated (and potentially
+unsafe) host kernel patch is needed.
+
+The commercial PC Virtualizers (VMWare [9], VirtualPC [10], TwoOStwo
+[11]) are faster than QEMU, but they all need specific, proprietary
+and potentially unsafe host drivers. Moreover, they are unable to
+provide cycle exact simulation as an emulator can.
+
+@section Portable dynamic translation
+
+QEMU is a dynamic translator. When it first encounters a piece of code,
+it converts it to the host instruction set. Usually dynamic translators
+are very complicated and highly CPU dependent. QEMU uses some tricks
+which make it relatively easily portable and simple while achieving good
+performances.
+
+The basic idea is to split every x86 instruction into fewer simpler
+instructions. Each simple instruction is implemented by a piece of C
+code (see @file{target-i386/op.c}). Then a compile time tool
+(@file{dyngen}) takes the corresponding object file (@file{op.o})
+to generate a dynamic code generator which concatenates the simple
+instructions to build a function (see @file{op.h:dyngen_code()}).
+
+In essence, the process is similar to [1], but more work is done at
+compile time. 
+
+A key idea to get optimal performances is that constant parameters can
+be passed to the simple operations. For that purpose, dummy ELF
+relocations are generated with gcc for each constant parameter. Then,
+the tool (@file{dyngen}) can locate the relocations and generate the
+appriopriate C code to resolve them when building the dynamic code.
+
+That way, QEMU is no more difficult to port than a dynamic linker.
+
+To go even faster, GCC static register variables are used to keep the
+state of the virtual CPU.
+
+@section Register allocation
+
+Since QEMU uses fixed simple instructions, no efficient register
+allocation can be done. However, because RISC CPUs have a lot of
+register, most of the virtual CPU state can be put in registers without
+doing complicated register allocation.
+
+@section Condition code optimisations
+
+Good CPU condition codes emulation (@code{EFLAGS} register on x86) is a
+critical point to get good performances. QEMU uses lazy condition code
+evaluation: instead of computing the condition codes after each x86
+instruction, it just stores one operand (called @code{CC_SRC}), the
+result (called @code{CC_DST}) and the type of operation (called
+@code{CC_OP}).
+
+@code{CC_OP} is almost never explicitely set in the generated code
+because it is known at translation time.
+
+In order to increase performances, a backward pass is performed on the
+generated simple instructions (see
+@code{target-i386/translate.c:optimize_flags()}). When it can be proved that
+the condition codes are not needed by the next instructions, no
+condition codes are computed at all.
+
+@section CPU state optimisations
+
+The x86 CPU has many internal states which change the way it evaluates
+instructions. In order to achieve a good speed, the translation phase
+considers that some state information of the virtual x86 CPU cannot
+change in it. For example, if the SS, DS and ES segments have a zero
+base, then the translator does not even generate an addition for the
+segment base.
+
+[The FPU stack pointer register is not handled that way yet].
+
+@section Translation cache
+
+A 16 MByte cache holds the most recently used translations. For
+simplicity, it is completely flushed when it is full. A translation unit
+contains just a single basic block (a block of x86 instructions
+terminated by a jump or by a virtual CPU state change which the
+translator cannot deduce statically).
+
+@section Direct block chaining
+
+After each translated basic block is executed, QEMU uses the simulated
+Program Counter (PC) and other cpu state informations (such as the CS
+segment base value) to find the next basic block.
+
+In order to accelerate the most common cases where the new simulated PC
+is known, QEMU can patch a basic block so that it jumps directly to the
+next one.
+
+The most portable code uses an indirect jump. An indirect jump makes
+it easier to make the jump target modification atomic. On some host
+architectures (such as x86 or PowerPC), the @code{JUMP} opcode is
+directly patched so that the block chaining has no overhead.
+
+@section Self-modifying code and translated code invalidation
+
+Self-modifying code is a special challenge in x86 emulation because no
+instruction cache invalidation is signaled by the application when code
+is modified.
+
+When translated code is generated for a basic block, the corresponding
+host page is write protected if it is not already read-only (with the
+system call @code{mprotect()}). Then, if a write access is done to the
+page, Linux raises a SEGV signal. QEMU then invalidates all the
+translated code in the page and enables write accesses to the page.
+
+Correct translated code invalidation is done efficiently by maintaining
+a linked list of every translated block contained in a given page. Other
+linked lists are also maintained to undo direct block chaining. 
+
+Although the overhead of doing @code{mprotect()} calls is important,
+most MSDOS programs can be emulated at reasonnable speed with QEMU and
+DOSEMU.
+
+Note that QEMU also invalidates pages of translated code when it detects
+that memory mappings are modified with @code{mmap()} or @code{munmap()}.
+
+When using a software MMU, the code invalidation is more efficient: if
+a given code page is invalidated too often because of write accesses,
+then a bitmap representing all the code inside the page is
+built. Every store into that page checks the bitmap to see if the code
+really needs to be invalidated. It avoids invalidating the code when
+only data is modified in the page.
+
+@section Exception support
+
+longjmp() is used when an exception such as division by zero is
+encountered. 
+
+The host SIGSEGV and SIGBUS signal handlers are used to get invalid
+memory accesses. The exact CPU state can be retrieved because all the
+x86 registers are stored in fixed host registers. The simulated program
+counter is found by retranslating the corresponding basic block and by
+looking where the host program counter was at the exception point.
+
+The virtual CPU cannot retrieve the exact @code{EFLAGS} register because
+in some cases it is not computed because of condition code
+optimisations. It is not a big concern because the emulated code can
+still be restarted in any cases.
+
+@section MMU emulation
+
+For system emulation, QEMU uses the mmap() system call to emulate the
+target CPU MMU. It works as long the emulated OS does not use an area
+reserved by the host OS (such as the area above 0xc0000000 on x86
+Linux).
+
+In order to be able to launch any OS, QEMU also supports a soft
+MMU. In that mode, the MMU virtual to physical address translation is
+done at every memory access. QEMU uses an address translation cache to
+speed up the translation.
+
+In order to avoid flushing the translated code each time the MMU
+mappings change, QEMU uses a physically indexed translation cache. It
+means that each basic block is indexed with its physical address. 
+
+When MMU mappings change, only the chaining of the basic blocks is
+reset (i.e. a basic block can no longer jump directly to another one).
+
+@section Hardware interrupts
+
+In order to be faster, QEMU does not check at every basic block if an
+hardware interrupt is pending. Instead, the user must asynchrously
+call a specific function to tell that an interrupt is pending. This
+function resets the chaining of the currently executing basic
+block. It ensures that the execution will return soon in the main loop
+of the CPU emulator. Then the main loop can test if the interrupt is
+pending and handle it.
+
+@section User emulation specific details
+
+@subsection Linux system call translation
+
+QEMU includes a generic system call translator for Linux. It means that
+the parameters of the system calls can be converted to fix the
+endianness and 32/64 bit issues. The IOCTLs are converted with a generic
+type description system (see @file{ioctls.h} and @file{thunk.c}).
+
+QEMU supports host CPUs which have pages bigger than 4KB. It records all
+the mappings the process does and try to emulated the @code{mmap()}
+system calls in cases where the host @code{mmap()} call would fail
+because of bad page alignment.
+
+@subsection Linux signals
+
+Normal and real-time signals are queued along with their information
+(@code{siginfo_t}) as it is done in the Linux kernel. Then an interrupt
+request is done to the virtual CPU. When it is interrupted, one queued
+signal is handled by generating a stack frame in the virtual CPU as the
+Linux kernel does. The @code{sigreturn()} system call is emulated to return
+from the virtual signal handler.
+
+Some signals (such as SIGALRM) directly come from the host. Other
+signals are synthetized from the virtual CPU exceptions such as SIGFPE
+when a division by zero is done (see @code{main.c:cpu_loop()}).
+
+The blocked signal mask is still handled by the host Linux kernel so
+that most signal system calls can be redirected directly to the host
+Linux kernel. Only the @code{sigaction()} and @code{sigreturn()} system
+calls need to be fully emulated (see @file{signal.c}).
+
+@subsection clone() system call and threads
+
+The Linux clone() system call is usually used to create a thread. QEMU
+uses the host clone() system call so that real host threads are created
+for each emulated thread. One virtual CPU instance is created for each
+thread.
+
+The virtual x86 CPU atomic operations are emulated with a global lock so
+that their semantic is preserved.
+
+Note that currently there are still some locking issues in QEMU. In
+particular, the translated cache flush is not protected yet against
+reentrancy.
+
+@subsection Self-virtualization
+
+QEMU was conceived so that ultimately it can emulate itself. Although
+it is not very useful, it is an important test to show the power of the
+emulator.
+
+Achieving self-virtualization is not easy because there may be address
+space conflicts. QEMU solves this problem by being an executable ELF
+shared object as the ld-linux.so ELF interpreter. That way, it can be
+relocated at load time.
+
+@section Bibliography
+
+@table @asis
+
+@item [1] 
+@url{http://citeseer.nj.nec.com/piumarta98optimizing.html}, Optimizing
+direct threaded code by selective inlining (1998) by Ian Piumarta, Fabio
+Riccardi.
+
+@item [2]
+@url{http://developer.kde.org/~sewardj/}, Valgrind, an open-source
+memory debugger for x86-GNU/Linux, by Julian Seward.
+
+@item [3]
+@url{http://bochs.sourceforge.net/}, the Bochs IA-32 Emulator Project,
+by Kevin Lawton et al.
+
+@item [4]
+@url{http://www.cs.rose-hulman.edu/~donaldlf/em86/index.html}, the EM86
+x86 emulator on Alpha-Linux.
+
+@item [5]
+@url{http://www.usenix.org/publications/library/proceedings/usenix-nt97/full_papers/chernoff/chernoff.pdf},
+DIGITAL FX!32: Running 32-Bit x86 Applications on Alpha NT, by Anton
+Chernoff and Ray Hookway.
+
+@item [6]
+@url{http://www.willows.com/}, Windows API library emulation from
+Willows Software.
+
+@item [7]
+@url{http://user-mode-linux.sourceforge.net/}, 
+The User-mode Linux Kernel.
+
+@item [8]
+@url{http://www.plex86.org/}, 
+The new Plex86 project.
+
+@item [9]
+@url{http://www.vmware.com/}, 
+The VMWare PC virtualizer.
+
+@item [10]
+@url{http://www.microsoft.com/windowsxp/virtualpc/}, 
+The VirtualPC PC virtualizer.
+
+@item [11]
+@url{http://www.twoostwo.org/}, 
+The TwoOStwo PC virtualizer.
+
+@end table
+
+@chapter Regression Tests
+
+In the directory @file{tests/}, various interesting testing programs
+are available. There are used for regression testing.
+
+@section @file{test-i386}
+
+This program executes most of the 16 bit and 32 bit x86 instructions and
+generates a text output. It can be compared with the output obtained with
+a real CPU or another emulator. The target @code{make test} runs this
+program and a @code{diff} on the generated output.
+
+The Linux system call @code{modify_ldt()} is used to create x86 selectors
+to test some 16 bit addressing and 32 bit with segmentation cases.
+
+The Linux system call @code{vm86()} is used to test vm86 emulation.
+
+Various exceptions are raised to test most of the x86 user space
+exception reporting.
+
+@section @file{linux-test}
+
+This program tests various Linux system calls. It is used to verify
+that the system call parameters are correctly converted between target
+and host CPUs.
+
+@section @file{qruncom.c}
+
+Example of usage of @code{libqemu} to emulate a user mode i386 CPU.
diff --git a/tools/ioemu/qemu.1 b/tools/ioemu/qemu.1
new file mode 100644 (file)
index 0000000..ddf0c2b
--- /dev/null
@@ -0,0 +1,457 @@
+.\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.14
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sh \" Subsection heading
+.br
+.if t .Sp
+.ne 5
+.PP
+\fB\\$1\fR
+.PP
+..
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings.  \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote.  | will give a
+.\" real vertical bar.  \*(C+ will give a nicer C++.  Capital omega is used to
+.\" do unbreakable dashes and therefore won't be available.  \*(C` and \*(C'
+.\" expand to `' in nroff, nothing in troff, for use with C<>.
+.tr \(*W-|\(bv\*(Tr
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+.    ds -- \(*W-
+.    ds PI pi
+.    if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+.    if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\"  diablo 12 pitch
+.    ds L" ""
+.    ds R" ""
+.    ds C` ""
+.    ds C' ""
+'br\}
+.el\{\
+.    ds -- \|\(em\|
+.    ds PI \(*p
+.    ds L" ``
+.    ds R" ''
+'br\}
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index
+.\" entries marked with X<> in POD.  Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.if \nF \{\
+.    de IX
+.    tm Index:\\$1\t\\n%\t"\\$2"
+..
+.    nr % 0
+.    rr F
+.\}
+.\"
+.\" For nroff, turn off justification.  Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.hy 0
+.if n .na
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear.  Run.  Save yourself.  No user-serviceable parts.
+.    \" fudge factors for nroff and troff
+.if n \{\
+.    ds #H 0
+.    ds #V .8m
+.    ds #F .3m
+.    ds #[ \f1
+.    ds #] \fP
+.\}
+.if t \{\
+.    ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+.    ds #V .6m
+.    ds #F 0
+.    ds #[ \&
+.    ds #] \&
+.\}
+.    \" simple accents for nroff and troff
+.if n \{\
+.    ds ' \&
+.    ds ` \&
+.    ds ^ \&
+.    ds , \&
+.    ds ~ ~
+.    ds /
+.\}
+.if t \{\
+.    ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+.    ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+.    ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+.    ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+.    ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+.    ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+.    \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+.    \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+.    \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+.    ds : e
+.    ds 8 ss
+.    ds o a
+.    ds d- d\h'-1'\(ga
+.    ds D- D\h'-1'\(hy
+.    ds th \o'bp'
+.    ds Th \o'LP'
+.    ds ae ae
+.    ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "QEMU 1"
+.TH QEMU 1 "2005-05-19" " " " "
+.SH "NAME"
+qemu  \- QEMU System Emulator
+.SH "SYNOPSIS"
+.IX Header "SYNOPSIS"
+usage: qemu [options] [disk_image]
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+The \s-1QEMU\s0 System emulator simulates a complete \s-1PC\s0.
+.PP
+In order to meet specific user needs, two versions of \s-1QEMU\s0 are
+available:
+.IP "1." 4
+\&\f(CW\*(C`qemu\-fast\*(C'\fR uses the host Memory Management Unit (\s-1MMU\s0) to
+simulate the x86 \s-1MMU\s0. It is \fIfast\fR but has limitations because
+the whole 4 \s-1GB\s0 address space cannot be used and some memory mapped
+peripherials cannot be emulated accurately yet. Therefore, a specific
+guest Linux kernel can be used  
+.Sp
+Moreover there is no separation between the host and target address
+spaces, so it offers no security (the target \s-1OS\s0 can modify the
+\&\f(CW\*(C`qemu\-fast\*(C'\fR code by writing at the right addresses).
+.IP "2." 4
+\&\f(CW\*(C`qemu\*(C'\fR uses a software \s-1MMU\s0. It is about \fItwo times slower\fR
+but gives a more accurate emulation and a complete separation between
+the host and target address spaces.
+.PP
+\&\s-1QEMU\s0 emulates the following \s-1PC\s0 peripherials:
+.IP "\-" 4
+i440FX host \s-1PCI\s0 bridge and \s-1PIIX3\s0 \s-1PCI\s0 to \s-1ISA\s0 bridge
+.IP "\-" 4
+Cirrus \s-1CLGD\s0 5446 \s-1PCI\s0 \s-1VGA\s0 card or dummy \s-1VGA\s0 card with Bochs \s-1VESA\s0
+extensions (hardware level, including all non standard modes).
+.IP "\-" 4
+\&\s-1PS/2\s0 mouse and keyboard
+.IP "\-" 4
+2 \s-1PCI\s0 \s-1IDE\s0 interfaces with hard disk and CD-ROM support
+.IP "\-" 4
+Floppy disk
+.IP "\-" 4
+\&\s-1NE2000\s0 \s-1PCI\s0 network adapters
+.IP "\-" 4
+Serial ports
+.IP "\-" 4
+Soundblaster 16 card
+.PP
+\&\s-1QEMU\s0 uses the \s-1PC\s0 \s-1BIOS\s0 from the Bochs project and the Plex86/Bochs \s-1LGPL\s0
+\&\s-1VGA\s0 \s-1BIOS\s0.
+.SH "OPTIONS"
+.IX Header "OPTIONS"
+\&\fIdisk_image\fR is a raw hard disk image for \s-1IDE\s0 hard disk 0.
+.PP
+General options:
+.IP "\fB\-fda file\fR" 4
+.IX Item "-fda file"
+.PD 0
+.IP "\fB\-fdb file\fR" 4
+.IX Item "-fdb file"
+.PD
+Use \fIfile\fR as floppy disk 0/1 image  You can
+use the host floppy by using \fI/dev/fd0\fR as filename.
+.IP "\fB\-hda file\fR" 4
+.IX Item "-hda file"
+.PD 0
+.IP "\fB\-hdb file\fR" 4
+.IX Item "-hdb file"
+.IP "\fB\-hdc file\fR" 4
+.IX Item "-hdc file"
+.IP "\fB\-hdd file\fR" 4
+.IX Item "-hdd file"
+.PD
+Use \fIfile\fR as hard disk 0, 1, 2 or 3 image 
+.IP "\fB\-cdrom file\fR" 4
+.IX Item "-cdrom file"
+Use \fIfile\fR as CD-ROM image (you cannot use \fB\-hdc\fR and and
+\&\fB\-cdrom\fR at the same time). You can use the host CD-ROM by
+using \fI/dev/cdrom\fR as filename.
+.IP "\fB\-boot [a|c|d]\fR" 4
+.IX Item "-boot [a|c|d]"
+Boot on floppy (a), hard disk (c) or CD-ROM (d). Hard disk boot is
+the default.
+.IP "\fB\-snapshot\fR" 4
+.IX Item "-snapshot"
+Write to temporary files instead of disk image files. In this case,
+the raw disk image you use is not written back. You can however force
+the write back by pressing \fBC\-a s\fR  
+.IP "\fB\-m megs\fR" 4
+.IX Item "-m megs"
+Set virtual \s-1RAM\s0 size to \fImegs\fR megabytes. Default is 128 \s-1MB\s0.
+.IP "\fB\-nographic\fR" 4
+.IX Item "-nographic"
+Normally, \s-1QEMU\s0 uses \s-1SDL\s0 to display the \s-1VGA\s0 output. With this option,
+you can totally disable graphical output so that \s-1QEMU\s0 is a simple
+command line application. The emulated serial port is redirected on
+the console. Therefore, you can still use \s-1QEMU\s0 to debug a Linux kernel
+with a serial console.
+.IP "\fB\-enable\-audio\fR" 4
+.IX Item "-enable-audio"
+The \s-1SB16\s0 emulation is disabled by default as it may give problems with
+Windows. You can enable it manually with this option.
+.IP "\fB\-localtime\fR" 4
+.IX Item "-localtime"
+Set the real time clock to local time (the default is to \s-1UTC\s0
+time). This option is needed to have correct date in MS-DOS or
+Windows.
+.IP "\fB\-full\-screen\fR" 4
+.IX Item "-full-screen"
+Start in full screen.
+.PP
+Network options:
+.IP "\fB\-n script\fR" 4
+.IX Item "-n script"
+Set \s-1TUN/TAP\s0 network init script [default=/etc/qemu\-ifup]. This script
+is launched to configure the host network interface (usually tun0)
+corresponding to the virtual \s-1NE2000\s0 card.
+.IP "\fB\-macaddr addr\fR" 4
+.IX Item "-macaddr addr"
+Set the mac address of the first interface (the format is
+aa:bb:cc:dd:ee:ff in hexa). The mac address is incremented for each
+new network interface.
+.IP "\fB\-tun\-fd fd\fR" 4
+.IX Item "-tun-fd fd"
+Assumes \fIfd\fR talks to a tap/tun host network interface and use
+it. Read <\fBhttp://bellard.org/qemu/tetrinet.html\fR> to have an
+example of its use.
+.IP "\fB\-user\-net\fR" 4
+.IX Item "-user-net"
+Use the user mode network stack. This is the default if no tun/tap
+network init script is found.
+.IP "\fB\-tftp prefix\fR" 4
+.IX Item "-tftp prefix"
+When using the user mode network stack, activate a built-in \s-1TFTP\s0
+server. All filenames beginning with \fIprefix\fR can be downloaded
+from the host to the guest using a \s-1TFTP\s0 client. The \s-1TFTP\s0 client on the
+guest must be configured in binary mode (use the command \f(CW\*(C`bin\*(C'\fR of
+the Unix \s-1TFTP\s0 client). The host \s-1IP\s0 address on the guest is as usual
+10.0.2.2.
+.IP "\fB\-smb dir\fR" 4
+.IX Item "-smb dir"
+When using the user mode network stack, activate a built-in \s-1SMB\s0
+server so that Windows OSes can access to the host files in \fIdir\fR
+transparently.
+.Sp
+In the guest Windows \s-1OS\s0, the line:
+.Sp
+.Vb 1
+\&        10.0.2.4 smbserver
+.Ve
+.Sp
+must be added in the file \fIC:\eWINDOWS\eLMHOSTS\fR (for windows 9x/Me)
+or \fIC:\eWINNT\eSYSTEM32\eDRIVERS\eETC\eLMHOSTS\fR (Windows \s-1NT/2000\s0).
+.Sp
+Then \fIdir\fR can be accessed in \fI\e\esmbserver\eqemu\fR.
+.Sp
+Note that a \s-1SAMBA\s0 server must be installed on the host \s-1OS\s0 in
+\&\fI/usr/sbin/smbd\fR. \s-1QEMU\s0 was tested succesfully with smbd version
+2.2.7a from the Red Hat 9.
+.IP "\fB\-redir [tcp|udp]:host\-port:[guest\-host]:guest\-port\fR" 4
+.IX Item "-redir [tcp|udp]:host-port:[guest-host]:guest-port"
+When using the user mode network stack, redirect incoming \s-1TCP\s0 or \s-1UDP\s0
+connections to the host port \fIhost-port\fR to the guest
+\&\fIguest-host\fR on guest port \fIguest-port\fR. If \fIguest-host\fR
+is not specified, its value is 10.0.2.15 (default address given by the
+built-in \s-1DHCP\s0 server).
+.Sp
+For example, to redirect host X11 connection from screen 1 to guest
+screen 0, use the following:
+.Sp
+.Vb 4
+\&        # on the host
+\&        qemu -redir tcp:6001::6000 [...]
+\&        # this host xterm should open in the guest X11 server
+\&        xterm -display :1
+.Ve
+.Sp
+To redirect telnet connections from host port 5555 to telnet port on
+the guest, use the following:
+.Sp
+.Vb 3
+\&        # on the host
+\&        qemu -redir tcp:5555::23 [...]
+\&        telnet localhost 5555
+.Ve
+.Sp
+Then when you use on the host \f(CW\*(C`telnet localhost 5555\*(C'\fR, you
+connect to the guest telnet server.
+.IP "\fB\-dummy\-net\fR" 4
+.IX Item "-dummy-net"
+Use the dummy network stack: no packet will be received by the network
+cards.
+.PP
+Linux boot specific. When using this options, you can use a given
+Linux kernel without installing it in the disk image. It can be useful
+for easier testing of various kernels.
+.IP "\fB\-kernel bzImage\fR" 4
+.IX Item "-kernel bzImage"
+Use \fIbzImage\fR as kernel image.
+.IP "\fB\-append cmdline\fR" 4
+.IX Item "-append cmdline"
+Use \fIcmdline\fR as kernel command line
+.IP "\fB\-initrd file\fR" 4
+.IX Item "-initrd file"
+Use \fIfile\fR as initial ram disk.
+.PP
+Debug/Expert options:
+.IP "\fB\-serial dev\fR" 4
+.IX Item "-serial dev"
+Redirect the virtual serial port to host device \fIdev\fR. Available
+devices are:
+.RS 4
+.ie n .IP """vc""" 4
+.el .IP "\f(CWvc\fR" 4
+.IX Item "vc"
+Virtual console
+.ie n .IP """pty""" 4
+.el .IP "\f(CWpty\fR" 4
+.IX Item "pty"
+[Linux only] Pseudo \s-1TTY\s0 (a new \s-1PTY\s0 is automatically allocated)
+.ie n .IP """null""" 4
+.el .IP "\f(CWnull\fR" 4
+.IX Item "null"
+void device
+.ie n .IP """stdio""" 4
+.el .IP "\f(CWstdio\fR" 4
+.IX Item "stdio"
+[Unix only] standard input/output
+.RE
+.RS 4
+.Sp
+The default device is \f(CW\*(C`vc\*(C'\fR in graphical mode and \f(CW\*(C`stdio\*(C'\fR in
+non graphical mode.
+.Sp
+This option can be used several times to simulate up to 4 serials
+ports.
+.RE
+.IP "\fB\-monitor dev\fR" 4
+.IX Item "-monitor dev"
+Redirect the monitor to host device \fIdev\fR (same devices as the
+serial port).
+The default device is \f(CW\*(C`vc\*(C'\fR in graphical mode and \f(CW\*(C`stdio\*(C'\fR in
+non graphical mode.
+.IP "\fB\-s\fR" 4
+.IX Item "-s"
+Wait gdb connection to port 1234  
+.IP "\fB\-p port\fR" 4
+.IX Item "-p port"
+Change gdb connection port.
+.IP "\fB\-S\fR" 4
+.IX Item "-S"
+Do not start \s-1CPU\s0 at startup (you must type 'c' in the monitor).
+.IP "\fB\-d\fR" 4
+.IX Item "-d"
+Output log in /tmp/qemu.log
+.IP "\fB\-isa\fR" 4
+.IX Item "-isa"
+Simulate an ISA-only system (default is \s-1PCI\s0 system).
+.IP "\fB\-std\-vga\fR" 4
+.IX Item "-std-vga"
+Simulate a standard \s-1VGA\s0 card with Bochs \s-1VBE\s0 extensions (default is
+Cirrus Logic \s-1GD5446\s0 \s-1PCI\s0 \s-1VGA\s0)
+.IP "\fB\-loadvm file\fR" 4
+.IX Item "-loadvm file"
+Start right away with a saved state (\f(CW\*(C`loadvm\*(C'\fR in monitor)
+.PP
+During the graphical emulation, you can use the following keys:
+.IP "\fBCtrl-Alt-f\fR" 4
+.IX Item "Ctrl-Alt-f"
+Toggle full screen
+.IP "\fBCtrl-Alt-n\fR" 4
+.IX Item "Ctrl-Alt-n"
+Switch to virtual console 'n'. Standard console mappings are:
+.RS 4
+.IP "\fI1\fR" 4
+.IX Item "1"
+Target system display
+.IP "\fI2\fR" 4
+.IX Item "2"
+Monitor
+.IP "\fI3\fR" 4
+.IX Item "3"
+Serial port
+.RE
+.RS 4
+.RE
+.IP "\fBCtrl-Alt\fR" 4
+.IX Item "Ctrl-Alt"
+Toggle mouse and keyboard grab.
+.PP
+In the virtual consoles, you can use \fBCtrl-Up\fR, \fBCtrl-Down\fR,
+\&\fBCtrl-PageUp\fR and \fBCtrl-PageDown\fR to move in the back log.
+.PP
+During emulation, if you are using the \fB\-nographic\fR option, use
+\&\fBCtrl-a h\fR to get terminal commands:
+.IP "\fBCtrl-a h\fR" 4
+.IX Item "Ctrl-a h"
+Print this help
+.IP "\fBCtrl-a x\fR" 4
+.IX Item "Ctrl-a x"
+Exit emulatior
+.IP "\fBCtrl-a s\fR" 4
+.IX Item "Ctrl-a s"
+Save disk data back to file (if \-snapshot)
+.IP "\fBCtrl-a b\fR" 4
+.IX Item "Ctrl-a b"
+Send break (magic sysrq in Linux)
+.IP "\fBCtrl-a c\fR" 4
+.IX Item "Ctrl-a c"
+Switch between console and monitor
+.IP "\fBCtrl-a Ctrl-a\fR" 4
+.IX Item "Ctrl-a Ctrl-a"
+Send Ctrl-a
+.PP
+The following options are specific to the PowerPC emulation:
+.IP "\fB\-prep\fR" 4
+.IX Item "-prep"
+Simulate a \s-1PREP\s0 system (default is PowerMAC)
+.IP "\fB\-g WxH[xDEPTH]\fR" 4
+.IX Item "-g WxH[xDEPTH]"
+Set the initial \s-1VGA\s0 graphic mode. The default is 800x600x15.
+.SH "SEE ALSO"
+.IX Header "SEE ALSO"
+The \s-1HTML\s0 documentation of \s-1QEMU\s0 for more precise information and Linux
+user mode emulator invocation.
+.SH "AUTHOR"
+.IX Header "AUTHOR"
+Fabrice Bellard
diff --git a/tools/ioemu/readline.c b/tools/ioemu/readline.c
new file mode 100644 (file)
index 0000000..5ed0971
--- /dev/null
@@ -0,0 +1,424 @@
+/*
+ * QEMU readline utility
+ * 
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+
+#define TERM_CMD_BUF_SIZE 4095
+#define TERM_MAX_CMDS 64
+#define NB_COMPLETIONS_MAX 256
+
+#define IS_NORM 0
+#define IS_ESC  1
+#define IS_CSI  2
+
+#define printf do_not_use_printf
+
+static char term_cmd_buf[TERM_CMD_BUF_SIZE + 1];
+static int term_cmd_buf_index;
+static int term_cmd_buf_size;
+
+static char term_last_cmd_buf[TERM_CMD_BUF_SIZE + 1];
+static int term_last_cmd_buf_index;
+static int term_last_cmd_buf_size;
+
+static int term_esc_state;
+static int term_esc_param;
+
+static char *term_history[TERM_MAX_CMDS];
+static int term_hist_entry = -1;
+
+static int nb_completions;
+int completion_index;
+static char *completions[NB_COMPLETIONS_MAX];
+
+static ReadLineFunc *term_readline_func;
+static int term_is_password;
+static char term_prompt[256];
+static void *term_readline_opaque;
+
+static void term_show_prompt2(void)
+{
+    term_printf("%s", term_prompt);
+    term_flush();
+    term_last_cmd_buf_index = 0;
+    term_last_cmd_buf_size = 0;
+    term_esc_state = IS_NORM;
+}
+
+static void term_show_prompt(void)
+{
+    term_show_prompt2();
+    term_cmd_buf_index = 0;
+    term_cmd_buf_size = 0;
+}
+
+/* update the displayed command line */
+static void term_update(void)
+{
+    int i, delta, len;
+
+    if (term_cmd_buf_size != term_last_cmd_buf_size ||
+        memcmp(term_cmd_buf, term_last_cmd_buf, term_cmd_buf_size) != 0) {
+        for(i = 0; i < term_last_cmd_buf_index; i++) {
+            term_printf("\033[D");
+        }
+        term_cmd_buf[term_cmd_buf_size] = '\0';
+        if (term_is_password) {
+            len = strlen(term_cmd_buf);
+            for(i = 0; i < len; i++)
+                term_printf("*");
+        } else {
+            term_printf("%s", term_cmd_buf);
+        }
+        term_printf("\033[K");
+        memcpy(term_last_cmd_buf, term_cmd_buf, term_cmd_buf_size);
+        term_last_cmd_buf_size = term_cmd_buf_size;
+        term_last_cmd_buf_index = term_cmd_buf_size;
+    }
+    if (term_cmd_buf_index != term_last_cmd_buf_index) {
+        delta = term_cmd_buf_index - term_last_cmd_buf_index;
+        if (delta > 0) {
+            for(i = 0;i < delta; i++) {
+                term_printf("\033[C");
+            }
+        } else {
+            delta = -delta;
+            for(i = 0;i < delta; i++) {
+                term_printf("\033[D");
+            }
+        }
+        term_last_cmd_buf_index = term_cmd_buf_index;
+    }
+    term_flush();
+}
+
+static void term_insert_char(int ch)
+{
+    if (term_cmd_buf_index < TERM_CMD_BUF_SIZE) {
+        memmove(term_cmd_buf + term_cmd_buf_index + 1,
+                term_cmd_buf + term_cmd_buf_index,
+                term_cmd_buf_size - term_cmd_buf_index);
+        term_cmd_buf[term_cmd_buf_index] = ch;
+        term_cmd_buf_size++;
+        term_cmd_buf_index++;
+    }
+}
+
+static void term_backward_char(void)
+{
+    if (term_cmd_buf_index > 0) {
+        term_cmd_buf_index--;
+    }
+}
+
+static void term_forward_char(void)
+{
+    if (term_cmd_buf_index < term_cmd_buf_size) {
+        term_cmd_buf_index++;
+    }
+}
+
+static void term_delete_char(void)
+{
+    if (term_cmd_buf_index < term_cmd_buf_size) {
+        memmove(term_cmd_buf + term_cmd_buf_index,
+                term_cmd_buf + term_cmd_buf_index + 1,
+                term_cmd_buf_size - term_cmd_buf_index - 1);
+        term_cmd_buf_size--;
+    }
+}
+
+static void term_backspace(void)
+{
+    if (term_cmd_buf_index > 0) {
+        term_backward_char();
+        term_delete_char();
+    }
+}
+
+static void term_bol(void)
+{
+    term_cmd_buf_index = 0;
+}
+
+static void term_eol(void)
+{
+    term_cmd_buf_index = term_cmd_buf_size;
+}
+
+static void term_up_char(void)
+{
+    int idx;
+
+    if (term_hist_entry == 0)
+       return;
+    if (term_hist_entry == -1) {
+       /* Find latest entry */
+       for (idx = 0; idx < TERM_MAX_CMDS; idx++) {
+           if (term_history[idx] == NULL)
+               break;
+       }
+       term_hist_entry = idx;
+    }
+    term_hist_entry--;
+    if (term_hist_entry >= 0) {
+       pstrcpy(term_cmd_buf, sizeof(term_cmd_buf), 
+                term_history[term_hist_entry]);
+       term_cmd_buf_index = term_cmd_buf_size = strlen(term_cmd_buf);
+    }
+}
+
+static void term_down_char(void)
+{
+    if (term_hist_entry == TERM_MAX_CMDS - 1 || term_hist_entry == -1)
+       return;
+    if (term_history[++term_hist_entry] != NULL) {
+       pstrcpy(term_cmd_buf, sizeof(term_cmd_buf),
+                term_history[term_hist_entry]);
+    } else {
+       term_hist_entry = -1;
+    }
+    term_cmd_buf_index = term_cmd_buf_size = strlen(term_cmd_buf);
+}
+
+static void term_hist_add(const char *cmdline)
+{
+    char *hist_entry, *new_entry;
+    int idx;
+
+    if (cmdline[0] == '\0')
+       return;
+    new_entry = NULL;
+    if (term_hist_entry != -1) {
+       /* We were editing an existing history entry: replace it */
+       hist_entry = term_history[term_hist_entry];
+       idx = term_hist_entry;
+       if (strcmp(hist_entry, cmdline) == 0) {
+           goto same_entry;
+       }
+    }
+    /* Search cmdline in history buffers */
+    for (idx = 0; idx < TERM_MAX_CMDS; idx++) {
+       hist_entry = term_history[idx];
+       if (hist_entry == NULL)
+           break;
+       if (strcmp(hist_entry, cmdline) == 0) {
+       same_entry:
+           new_entry = hist_entry;
+           /* Put this entry at the end of history */
+           memmove(&term_history[idx], &term_history[idx + 1],
+                   &term_history[TERM_MAX_CMDS] - &term_history[idx + 1]);
+           term_history[TERM_MAX_CMDS - 1] = NULL;
+           for (; idx < TERM_MAX_CMDS; idx++) {
+               if (term_history[idx] == NULL)
+                   break;
+           }
+           break;
+       }
+    }
+    if (idx == TERM_MAX_CMDS) {
+       /* Need to get one free slot */
+       free(term_history[0]);
+       memcpy(term_history, &term_history[1],
+              &term_history[TERM_MAX_CMDS] - &term_history[1]);
+       term_history[TERM_MAX_CMDS - 1] = NULL;
+       idx = TERM_MAX_CMDS - 1;
+    }
+    if (new_entry == NULL)
+       new_entry = strdup(cmdline);
+    term_history[idx] = new_entry;
+    term_hist_entry = -1;
+}
+
+/* completion support */
+
+void add_completion(const char *str)
+{
+    if (nb_completions < NB_COMPLETIONS_MAX) {
+        completions[nb_completions++] = qemu_strdup(str);
+    }
+}
+
+static void term_completion(void)
+{
+    int len, i, j, max_width, nb_cols;
+    char *cmdline;
+
+    nb_completions = 0;
+    
+    cmdline = qemu_malloc(term_cmd_buf_index + 1);
+    if (!cmdline)
+        return;
+    memcpy(cmdline, term_cmd_buf, term_cmd_buf_index);
+    cmdline[term_cmd_buf_index] = '\0';
+    qemu_free(cmdline);
+
+    /* no completion found */
+    if (nb_completions <= 0)
+        return;
+    if (nb_completions == 1) {
+        len = strlen(completions[0]);
+        for(i = completion_index; i < len; i++) {
+            term_insert_char(completions[0][i]);
+        }
+        /* extra space for next argument. XXX: make it more generic */
+        if (len > 0 && completions[0][len - 1] != '/')
+            term_insert_char(' ');
+    } else {
+        term_printf("\n");
+        max_width = 0;
+        for(i = 0; i < nb_completions; i++) {
+            len = strlen(completions[i]);
+            if (len > max_width)
+                max_width = len;
+        }
+        max_width += 2;
+        if (max_width < 10)
+            max_width = 10;
+        else if (max_width > 80)
+            max_width = 80;
+        nb_cols = 80 / max_width;
+        j = 0;
+        for(i = 0; i < nb_completions; i++) {
+            term_printf("%-*s", max_width, completions[i]);
+            if (++j == nb_cols || i == (nb_completions - 1)) {
+                term_printf("\n");
+                j = 0;
+            }
+        }
+        term_show_prompt2();
+    }
+}
+
+/* return true if command handled */
+void readline_handle_byte(int ch)
+{
+    switch(term_esc_state) {
+    case IS_NORM:
+        switch(ch) {
+        case 1:
+            term_bol();
+            break;
+        case 4:
+            term_delete_char();
+            break;
+        case 5:
+            term_eol();
+            break;
+        case 9:
+            term_completion();
+            break;
+        case 10:
+        case 13:
+            term_cmd_buf[term_cmd_buf_size] = '\0';
+            if (!term_is_password)
+                term_hist_add(term_cmd_buf);
+            term_printf("\n");
+            /* NOTE: readline_start can be called here */
+            term_readline_func(term_readline_opaque, term_cmd_buf);
+            break;
+        case 27:
+            term_esc_state = IS_ESC;
+            break;
+        case 127:
+        case 8:
+            term_backspace();
+            break;
+       case 155:
+            term_esc_state = IS_CSI;
+           break;
+        default:
+            if (ch >= 32) {
+                term_insert_char(ch);
+            }
+            break;
+        }
+        break;
+    case IS_ESC:
+        if (ch == '[') {
+            term_esc_state = IS_CSI;
+            term_esc_param = 0;
+        } else {
+            term_esc_state = IS_NORM;
+        }
+        break;
+    case IS_CSI:
+        switch(ch) {
+       case 'A':
+       case 'F':
+           term_up_char();
+           break;
+       case 'B':
+       case 'E':
+           term_down_char();
+           break;
+        case 'D':
+            term_backward_char();
+            break;
+        case 'C':
+            term_forward_char();
+            break;
+        case '0' ... '9':
+            term_esc_param = term_esc_param * 10 + (ch - '0');
+            goto the_end;
+        case '~':
+            switch(term_esc_param) {
+            case 1:
+                term_bol();
+                break;
+            case 3:
+                term_delete_char();
+                break;
+            case 4:
+                term_eol();
+                break;
+            }
+            break;
+        default:
+            break;
+        }
+        term_esc_state = IS_NORM;
+    the_end:
+        break;
+    }
+    term_update();
+}
+
+void readline_start(const char *prompt, int is_password,
+                    ReadLineFunc *readline_func, void *opaque)
+{
+    pstrcpy(term_prompt, sizeof(term_prompt), prompt);
+    term_readline_func = readline_func;
+    term_readline_opaque = opaque;
+    term_is_password = is_password;
+    term_show_prompt();
+}
+
+const char *readline_get_history(unsigned int index)
+{
+    if (index >= TERM_MAX_CMDS)
+        return NULL;
+    return term_history[index];
+}
+
+
diff --git a/tools/ioemu/sdl.c b/tools/ioemu/sdl.c
new file mode 100644 (file)
index 0000000..91c0e23
--- /dev/null
@@ -0,0 +1,605 @@
+/*
+ * QEMU SDL display driver
+ * 
+ * Copyright (c) 2003 Fabrice Bellard
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+
+#include <SDL.h>
+
+/* keyboard stuff */
+#include <SDL_keysym.h>
+#include "keysym_adapter_sdl.h"
+#include "keyboard_rdesktop.c"
+
+#ifndef _WIN32
+#include <signal.h>
+#endif
+
+#if defined(__APPLE__)
+#define CONFIG_SDL_GENERIC_KBD
+#endif
+
+static SDL_Surface *screen;
+static int gui_grab; /* if true, all keyboard/mouse events are grabbed */
+static int last_vm_running;
+static int gui_saved_grab;
+static int gui_fullscreen;
+static int gui_key_modifier_pressed;
+static int gui_keysym;
+static void* kbd_layout=0;
+static int gui_fullscreen_initial_grab;
+static int gui_grab_code = KMOD_LALT | KMOD_LCTRL;
+static uint8_t modifiers_state[256];
+
+SDL_PixelFormat* sdl_get_format() {
+       return screen->format;
+}
+
+static void sdl_update(DisplayState *ds, int x, int y, int w, int h)
+{
+    SDL_UpdateRect(screen, x, y, w, h);
+}
+
+static void sdl_resize(DisplayState *ds, int w, int h)
+{
+    int flags;
+
+    //    printf("resizing to %d %d\n", w, h);
+
+    flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL;
+    flags |= SDL_RESIZABLE;
+    if (gui_fullscreen)
+        flags |= SDL_FULLSCREEN;
+    screen = SDL_SetVideoMode(w, h, 0, flags);
+    if (!screen) {
+        fprintf(stderr, "Could not open SDL display\n");
+        exit(1);
+    }
+    ds->data = screen->pixels;
+    ds->linesize = screen->pitch;
+    ds->depth = screen->format->BitsPerPixel;
+    ds->width = w;
+    ds->height = h;
+}
+
+#ifdef CONFIG_SDL_GENERIC_KBD
+
+/* XXX: use keymap tables defined in the VNC patch because the
+   following code suppose you have a US keyboard. */
+
+static const uint8_t scancodes[SDLK_LAST] = {
+    [SDLK_ESCAPE]   = 0x01,
+    [SDLK_1]        = 0x02,
+    [SDLK_2]        = 0x03,
+    [SDLK_3]        = 0x04,
+    [SDLK_4]        = 0x05,
+    [SDLK_5]        = 0x06,
+    [SDLK_6]        = 0x07,
+    [SDLK_7]        = 0x08,
+    [SDLK_8]        = 0x09,
+    [SDLK_9]        = 0x0a,
+    [SDLK_0]        = 0x0b,
+    [SDLK_MINUS]    = 0x0c,
+    [SDLK_EQUALS]   = 0x0d,
+    [SDLK_BACKSPACE]        = 0x0e,
+    [SDLK_TAB]      = 0x0f,
+    [SDLK_q]        = 0x10,
+    [SDLK_w]        = 0x11,
+    [SDLK_e]        = 0x12,
+    [SDLK_r]        = 0x13,
+    [SDLK_t]        = 0x14,
+    [SDLK_y]        = 0x15,
+    [SDLK_u]        = 0x16,
+    [SDLK_i]        = 0x17,
+    [SDLK_o]        = 0x18,
+    [SDLK_p]        = 0x19,
+    [SDLK_LEFTBRACKET]      = 0x1a,
+    [SDLK_RIGHTBRACKET]     = 0x1b,
+    [SDLK_RETURN]   = 0x1c,
+    [SDLK_LCTRL]    = 0x1d,
+    [SDLK_a]        = 0x1e,
+    [SDLK_s]        = 0x1f,
+    [SDLK_d]        = 0x20,
+    [SDLK_f]        = 0x21,
+    [SDLK_g]        = 0x22,
+    [SDLK_h]        = 0x23,
+    [SDLK_j]        = 0x24,
+    [SDLK_k]        = 0x25,
+    [SDLK_l]        = 0x26,
+    [SDLK_SEMICOLON]        = 0x27,
+    [SDLK_QUOTE]    = 0x28,
+    [SDLK_BACKQUOTE]        = 0x29,
+    [SDLK_LSHIFT]   = 0x2a,
+    [SDLK_BACKSLASH]        = 0x2b,
+    [SDLK_z]        = 0x2c,
+    [SDLK_x]        = 0x2d,
+    [SDLK_c]        = 0x2e,
+    [SDLK_v]        = 0x2f,
+    [SDLK_b]        = 0x30,
+    [SDLK_n]        = 0x31,
+    [SDLK_m]        = 0x32,
+    [SDLK_COMMA]    = 0x33,
+    [SDLK_PERIOD]   = 0x34,
+    [SDLK_SLASH]    = 0x35,
+    [SDLK_KP_MULTIPLY]      = 0x37,
+    [SDLK_LALT]     = 0x38,
+    [SDLK_SPACE]    = 0x39,
+    [SDLK_CAPSLOCK] = 0x3a,
+    [SDLK_F1]       = 0x3b,
+    [SDLK_F2]       = 0x3c,
+    [SDLK_F3]       = 0x3d,
+    [SDLK_F4]       = 0x3e,
+    [SDLK_F5]       = 0x3f,
+    [SDLK_F6]       = 0x40,
+    [SDLK_F7]       = 0x41,
+    [SDLK_F8]       = 0x42,
+    [SDLK_F9]       = 0x43,
+    [SDLK_F10]      = 0x44,
+    [SDLK_NUMLOCK]  = 0x45,
+    [SDLK_SCROLLOCK]        = 0x46,
+    [SDLK_KP7]      = 0x47,
+    [SDLK_KP8]      = 0x48,
+    [SDLK_KP9]      = 0x49,
+    [SDLK_KP_MINUS] = 0x4a,
+    [SDLK_KP4]      = 0x4b,
+    [SDLK_KP5]      = 0x4c,
+    [SDLK_KP6]      = 0x4d,
+    [SDLK_KP_PLUS]  = 0x4e,
+    [SDLK_KP1]      = 0x4f,
+    [SDLK_KP2]      = 0x50,
+    [SDLK_KP3]      = 0x51,
+    [SDLK_KP0]      = 0x52,
+    [SDLK_KP_PERIOD]        = 0x53,
+    [SDLK_PRINT]    = 0x54,
+    [SDLK_LMETA]    = 0x56,
+
+    [SDLK_KP_ENTER]  = 0x9c,
+    [SDLK_KP_DIVIDE] = 0xb5,
+    
+    [SDLK_UP]       = 0xc8,
+    [SDLK_DOWN]     = 0xd0,
+    [SDLK_RIGHT]    = 0xcd,
+    [SDLK_LEFT]     = 0xcb,
+    [SDLK_INSERT]   = 0xd2,
+    [SDLK_HOME]     = 0xc7,
+    [SDLK_END]      = 0xcf,
+    [SDLK_PAGEUP]   = 0xc9,
+    [SDLK_PAGEDOWN] = 0xd1,
+    [SDLK_DELETE]   = 0xd3,
+};
+
+static uint8_t sdl_keyevent_to_keycode(const SDL_KeyboardEvent *ev)
+{
+    return scancodes[ev->keysym.sym];
+}
+
+#elif defined(_WIN32)
+
+static uint8_t sdl_keyevent_to_keycode(const SDL_KeyboardEvent *ev)
+{
+    return ev->keysym.scancode;
+}
+
+#else
+
+static const uint8_t x_keycode_to_pc_keycode[61] = {
+   0xc7,      /*  97  Home   */
+   0xc8,      /*  98  Up     */
+   0xc9,      /*  99  PgUp   */
+   0xcb,      /* 100  Left   */
+   0x4c,        /* 101  KP-5   */
+   0xcd,      /* 102  Right  */
+   0xcf,      /* 103  End    */
+   0xd0,      /* 104  Down   */
+   0xd1,      /* 105  PgDn   */
+   0xd2,      /* 106  Ins    */
+   0xd3,      /* 107  Del    */
+   0x9c,      /* 108  Enter  */
+   0x9d,      /* 109  Ctrl-R */
+   0x0,       /* 110  Pause  */
+   0xb7,      /* 111  Print  */
+   0xb5,      /* 112  Divide */
+   0xb8,      /* 113  Alt-R  */
+   0xc6,      /* 114  Break  */   
+   0x0,         /* 115 */
+   0x0,         /* 116 */
+   0x0,         /* 117 */
+   0x0,         /* 118 */
+   0x0,         /* 119 */
+   0x70,         /* 120 Hiragana_Katakana */
+   0x0,         /* 121 */
+   0x0,         /* 122 */
+   0x73,         /* 123 backslash */
+   0x0,         /* 124 */
+   0x0,         /* 125 */
+   0x0,         /* 126 */
+   0x0,         /* 127 */
+   0x0,         /* 128 */
+   0x79,         /* 129 Henkan */
+   0x0,         /* 130 */
+   0x7b,         /* 131 Muhenkan */
+   0x0,         /* 132 */
+   0x7d,         /* 133 Yen */
+   0x0,         /* 134 */
+   0x0,         /* 135 */
+   0x47,         /* 136 KP_7 */
+   0x48,         /* 137 KP_8 */
+   0x49,         /* 138 KP_9 */
+   0x4b,         /* 139 KP_4 */
+   0x4c,         /* 140 KP_5 */
+   0x4d,         /* 141 KP_6 */
+   0x4f,         /* 142 KP_1 */
+   0x50,         /* 143 KP_2 */
+   0x51,         /* 144 KP_3 */
+   0x52,         /* 145 KP_0 */
+   0x53,         /* 146 KP_. */
+   0x47,         /* 147 KP_HOME */
+   0x48,         /* 148 KP_UP */
+   0x49,         /* 149 KP_PgUp */
+   0x4b,         /* 150 KP_Left */
+   0x4c,         /* 151 KP_ */
+   0x4d,         /* 152 KP_Right */
+   0x4f,         /* 153 KP_End */
+   0x50,         /* 154 KP_Down */
+   0x51,         /* 155 KP_PgDn */
+   0x52,         /* 156 KP_Ins */
+   0x53,         /* 157 KP_Del */
+};
+
+static uint8_t sdl_keyevent_to_keycode(const SDL_KeyboardEvent *ev)
+{
+    int keycode;
+
+    keycode = ev->keysym.scancode;
+
+    if (keycode < 9) {
+        keycode = 0;
+    } else if (keycode < 97) {
+        keycode -= 8; /* just an offset */
+    } else if (keycode < 158) {
+        /* use conversion table */
+        keycode = x_keycode_to_pc_keycode[keycode - 97];
+    } else {
+        keycode = 0;
+    }
+    return keycode;
+}
+
+#endif
+
+static void reset_keys(void)
+{
+    int i;
+    for(i = 0; i < 256; i++) {
+        if (modifiers_state[i]) {
+            if (i & 0x80)
+                kbd_put_keycode(0xe0);
+            kbd_put_keycode(i | 0x80);
+            modifiers_state[i] = 0;
+        }
+    }
+}
+
+static void sdl_process_key(SDL_KeyboardEvent *ev)
+{
+    int keycode, v;
+
+    if(kbd_layout)
+       keycode=keysym2scancode(kbd_layout, ev->keysym.sym);
+    else {
+
+    if (ev->keysym.sym == SDLK_PAUSE) {
+        /* specific case */
+        v = 0;
+        if (ev->type == SDL_KEYUP)
+            v |= 0x80;
+        kbd_put_keycode(0xe1);
+        kbd_put_keycode(0x1d | v);
+        kbd_put_keycode(0x45 | v);
+        return;
+    }
+
+    /* XXX: not portable, but avoids complicated mappings */
+    keycode = sdl_keyevent_to_keycode(ev);
+
+    switch(keycode) {
+    case 0x00:
+        /* sent when leaving window: reset the modifiers state */
+        reset_keys();
+        return;
+    case 0x2a:                          /* Left Shift */
+    case 0x36:                          /* Right Shift */
+    case 0x1d:                          /* Left CTRL */
+    case 0x9d:                          /* Right CTRL */
+    case 0x38:                          /* Left ALT */
+    case 0xb8:                         /* Right ALT */
+        if (ev->type == SDL_KEYUP)
+            modifiers_state[keycode] = 0;
+        else
+            modifiers_state[keycode] = 1;
+        break;
+    case 0x45: /* num lock */
+    case 0x3a: /* caps lock */
+        /* SDL does not send the key up event, so we generate it */
+        kbd_put_keycode(keycode);
+        kbd_put_keycode(keycode | 0x80);
+        return;
+    }
+    }
+
+    /* now send the key code */
+    if (keycode & 0x80)
+        kbd_put_keycode(0xe0);
+    if (ev->type == SDL_KEYUP)
+        kbd_put_keycode(keycode | 0x80);
+    else
+        kbd_put_keycode(keycode & 0x7f);
+}
+
+static void sdl_update_caption(void)
+{
+    char buf[1024];
+    strcpy(buf, "VTXen");
+    if (!vm_running) {
+        strcat(buf, " [Stopped]");
+    }
+    if (gui_grab) {
+        strcat(buf, " - Press Ctrl-Alt to exit grab");
+    }
+    SDL_WM_SetCaption(buf, "VTXen");
+}
+
+static void sdl_grab_start(void)
+{
+    SDL_ShowCursor(0);
+    SDL_WM_GrabInput(SDL_GRAB_ON);
+    /* dummy read to avoid moving the mouse */
+    SDL_GetRelativeMouseState(NULL, NULL);
+    gui_grab = 1;
+    sdl_update_caption();
+}
+
+static void sdl_grab_end(void)
+{
+    SDL_WM_GrabInput(SDL_GRAB_OFF);
+    SDL_ShowCursor(1);
+    gui_grab = 0;
+    sdl_update_caption();
+}
+
+static void sdl_send_mouse_event(void)
+{
+    int dx, dy, dz, state, buttons;
+    state = SDL_GetRelativeMouseState(&dx, &dy);
+    buttons = 0;
+    if (state & SDL_BUTTON(SDL_BUTTON_LEFT))
+        buttons |= MOUSE_EVENT_LBUTTON;
+    if (state & SDL_BUTTON(SDL_BUTTON_RIGHT))
+        buttons |= MOUSE_EVENT_RBUTTON;
+    if (state & SDL_BUTTON(SDL_BUTTON_MIDDLE))
+        buttons |= MOUSE_EVENT_MBUTTON;
+    /* XXX: test wheel */
+    dz = 0;
+#ifdef SDL_BUTTON_WHEELUP
+    if (state & SDL_BUTTON(SDL_BUTTON_WHEELUP))
+        dz--;
+    if (state & SDL_BUTTON(SDL_BUTTON_WHEELDOWN))
+        dz++;
+#endif
+    kbd_mouse_event(dx, dy, dz, buttons);
+}
+
+static void toggle_full_screen(DisplayState *ds)
+{
+    gui_fullscreen = !gui_fullscreen;
+    sdl_resize(ds, screen->w, screen->h);
+    if (gui_fullscreen) {
+        gui_saved_grab = gui_grab;
+        sdl_grab_start();
+    } else {
+        if (!gui_saved_grab)
+            sdl_grab_end();
+    }
+    vga_invalidate_display();
+    vga_update_display();
+}
+
+static void sdl_refresh(DisplayState *ds)
+{
+    SDL_Event ev1, *ev = &ev1;
+    int mod_state;
+                     
+    if (last_vm_running != vm_running) {
+        last_vm_running = vm_running;
+        sdl_update_caption();
+    }
+
+    if (is_active_console(vga_console)) 
+        vga_update_display();
+
+    while (SDL_PollEvent(ev)) {
+        switch (ev->type) {
+        case SDL_VIDEOEXPOSE:
+            sdl_update(ds, 0, 0, screen->w, screen->h);
+            break;
+        case SDL_KEYDOWN:
+        case SDL_KEYUP:
+            if (ev->type == SDL_KEYDOWN) {
+                mod_state = (SDL_GetModState() & gui_grab_code) ==
+                    gui_grab_code;
+                gui_key_modifier_pressed = mod_state;
+                if (gui_key_modifier_pressed) {
+                    int keycode;
+                    keycode = sdl_keyevent_to_keycode(&ev->key);
+                    switch(keycode) {
+                    case 0x21: /* 'f' key on US keyboard */
+                        toggle_full_screen(ds);
+                        gui_keysym = 1;
+                        break;
+                    case 0x02 ... 0x0a: /* '1' to '9' keys */ 
+                        console_select(keycode - 0x02);
+                        if (is_active_console(vga_console)) {
+                            /* tell the vga console to redisplay itself */
+                            vga_invalidate_display();
+                        } else {
+                            /* display grab if going to a text console */
+                            if (gui_grab)
+                                sdl_grab_end();
+                        }
+                        gui_keysym = 1;
+                        break;
+                    default:
+                        break;
+                    }
+                } else if (!is_active_console(vga_console)) {
+                    int keysym;
+                    keysym = 0;
+                    if (ev->key.keysym.mod & (KMOD_LCTRL | KMOD_RCTRL)) {
+                        switch(ev->key.keysym.sym) {
+                        case SDLK_UP: keysym = QEMU_KEY_CTRL_UP; break;
+                        case SDLK_DOWN: keysym = QEMU_KEY_CTRL_DOWN; break;
+                        case SDLK_LEFT: keysym = QEMU_KEY_CTRL_LEFT; break;
+                        case SDLK_RIGHT: keysym = QEMU_KEY_CTRL_RIGHT; break;
+                        case SDLK_HOME: keysym = QEMU_KEY_CTRL_HOME; break;
+                        case SDLK_END: keysym = QEMU_KEY_CTRL_END; break;
+                        case SDLK_PAGEUP: keysym = QEMU_KEY_CTRL_PAGEUP; break;
+                        case SDLK_PAGEDOWN: keysym = QEMU_KEY_CTRL_PAGEDOWN; break;
+                        default: break;
+                        }
+                    } else {
+                        switch(ev->key.keysym.sym) {
+                        case SDLK_UP: keysym = QEMU_KEY_UP; break;
+                        case SDLK_DOWN: keysym = QEMU_KEY_DOWN; break;
+                        case SDLK_LEFT: keysym = QEMU_KEY_LEFT; break;
+                        case SDLK_RIGHT: keysym = QEMU_KEY_RIGHT; break;
+                        case SDLK_HOME: keysym = QEMU_KEY_HOME; break;
+                        case SDLK_END: keysym = QEMU_KEY_END; break;
+                        case SDLK_PAGEUP: keysym = QEMU_KEY_PAGEUP; break;
+                        case SDLK_PAGEDOWN: keysym = QEMU_KEY_PAGEDOWN; break;
+                        case SDLK_BACKSPACE: keysym = QEMU_KEY_BACKSPACE; break;                        case SDLK_DELETE: keysym = QEMU_KEY_DELETE; break;
+                        default: break;
+                        }
+                    }
+                    if (keysym) {
+                        kbd_put_keysym(keysym);
+                    } else if (ev->key.keysym.unicode != 0) {
+                        kbd_put_keysym(ev->key.keysym.unicode);
+                    }
+                }
+            } else if (ev->type == SDL_KEYUP) {
+                mod_state = (ev->key.keysym.mod & gui_grab_code);
+                if (!mod_state) {
+                    if (gui_key_modifier_pressed) {
+                        gui_key_modifier_pressed = 0;
+                        if (gui_keysym == 0) {
+                            /* exit/enter grab if pressing Ctrl-Alt */
+                            if (!gui_grab)
+                                sdl_grab_start();
+                            else
+                                sdl_grab_end();
+                            /* SDL does not send back all the
+                               modifiers key, so we must correct it */
+                            reset_keys();
+                            break;
+                        }
+                        gui_keysym = 0;
+                    }
+                }
+            }
+            if (is_active_console(vga_console)) 
+                sdl_process_key(&ev->key);
+            break;
+        case SDL_QUIT:
+            qemu_system_shutdown_request();
+            break;
+        case SDL_MOUSEMOTION:
+            if (gui_grab) {
+                sdl_send_mouse_event();
+            }
+            break;
+        case SDL_MOUSEBUTTONDOWN:
+        case SDL_MOUSEBUTTONUP:
+            {
+                SDL_MouseButtonEvent *bev = &ev->button;
+                if (!gui_grab) {
+                    if (ev->type == SDL_MOUSEBUTTONDOWN &&
+                        (bev->state & SDL_BUTTON_LMASK)) {
+                        /* start grabbing all events */
+                        sdl_grab_start();
+                    }
+                } else {
+                    sdl_send_mouse_event();
+                }
+            }
+            break;
+        case SDL_ACTIVEEVENT:
+            if (gui_grab && (ev->active.gain & SDL_ACTIVEEVENTMASK) == 0 &&
+                !gui_fullscreen_initial_grab) {
+                sdl_grab_end();
+            }
+            break;
+        default:
+            break;
+        }
+    }
+}
+
+static void sdl_cleanup(void) 
+{
+    SDL_Quit();
+}
+
+void sdl_display_init(DisplayState *ds, int full_screen)
+{
+    int flags;
+
+    if(keyboard_layout)
+           kbd_layout=init_keyboard_layout(keyboard_layout);
+
+    flags = SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE;
+    if (SDL_Init (flags)) {
+        fprintf(stderr, "Could not initialize SDL - exiting\n");
+        exit(1);
+    }
+#ifndef _WIN32
+    /* NOTE: we still want Ctrl-C to work, so we undo the SDL redirections */
+    signal(SIGINT, SIG_DFL);
+    signal(SIGQUIT, SIG_DFL);
+#endif
+
+    ds->dpy_update = sdl_update;
+    ds->dpy_resize = sdl_resize;
+    ds->dpy_refresh = sdl_refresh;
+
+    sdl_resize(ds, 640, 400);
+    sdl_update_caption();
+    SDL_EnableKeyRepeat(250, 50);
+    SDL_EnableUNICODE(1);
+    gui_grab = 0;
+
+    atexit(sdl_cleanup);
+    if (full_screen) {
+        gui_fullscreen = 1;
+        gui_fullscreen_initial_grab = 1;
+        sdl_grab_start();
+    }
+}
diff --git a/tools/ioemu/target-i386-dm/device-model b/tools/ioemu/target-i386-dm/device-model
new file mode 100755 (executable)
index 0000000..b25c175
--- /dev/null
@@ -0,0 +1,69 @@
+#!/bin/sh
+
+. /etc/rc.d/init.d/functions
+
+qemubin=/usr/bin/qemu-dm
+
+ulimit -c unlimited
+
+# Use this for debugging:
+#gdb --args /usr/sbin/qemu-dm -hda /var/images/qemu-linux.img -nographic \
+#      -serial pty -l 'ioport,int' $*
+
+while getopts ":f:" opt;
+do
+    case $opt in
+      f) QEMUCONFIGFILE=$OPTARG;shift;shift;;
+      \?) echo;;
+    esac
+done
+
+echo $QEMUCONFIGFILE
+if [ ! -z $QEMUCONFIGFILE ];then
+    . $QEMUCONFIGFILE
+else
+    echo "no config file specified!" > /dev/tty
+    echo "no config file specified!" >> /tmp/qemustart.log
+    exit
+fi
+PARMETER=""
+
+if [ ! -z $hda ];then
+PARMETER="$PARMETER -hda $hda"
+fi
+
+if [ ! -z $hdb ];then
+PARMETER="$PARMETER -hdb $hdb"
+fi
+
+if [ ! -z $hdc ];then
+PARMETER="$PARMETER -hdc $hdc"
+fi
+
+if [ ! -z $hdd ];then
+PARMETER="$PARMETER -hdd $hdd"
+fi
+
+if [ ! -z $nographic ] && [ $nographic -eq 1 ];then
+PARMETER="$PARMETER -nographic"
+fi
+
+vnc=${vnc:=1}
+sdl=${sdl:=0}
+if qemu-dm 2>&1 |grep vnc > /dev/null;then
+       if [ $vnc -eq 1 ] && [ $sdl -eq 1 ];then
+               PARMETER="$PARMETER -vnc-and-sdl -k en-us"
+       elif [ $vnc -eq 1 ];then
+               PARMETER="$PARMETER -vnc -k en-us"
+       fi
+fi
+
+#optional cmdline for qemu        
+#       -nographic \
+#       -serial pty \
+
+
+PARMETER="$PARMETER -l int $*";
+echo "$qemubin $PARMETER" >>/tmp/qemustart.log
+$qemubin $PARMETER &
diff --git a/tools/ioemu/target-i386-dm/helper2.c b/tools/ioemu/target-i386-dm/helper2.c
new file mode 100644 (file)
index 0000000..3704b08
--- /dev/null
@@ -0,0 +1,434 @@
+/*
+ *  i386 helpers (without register variable usage)
+ * 
+ *  Copyright (c) 2003 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/*
+ * Main cpu loop for handling I/O requests coming from a virtual machine
+ * Copyright © 2004, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU Lesser General Public License,
+ * version 2.1, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA.
+ */
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include <signal.h>
+#include <assert.h>
+
+#include <limits.h>
+#include <fcntl.h>
+
+#include "xc.h"
+#include <io/ioreq.h>
+
+#include "cpu.h"
+#include "exec-all.h"
+
+//#define DEBUG_MMU
+
+#ifdef USE_CODE_COPY
+#include <asm/ldt.h>
+#include <linux/unistd.h>
+#include <linux/version.h>
+
+#include <sys/ioctl.h>
+/* According to POSIX 1003.1-2001 */
+#include <sys/select.h>
+
+/* According to earlier standards */
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <values.h>
+
+_syscall3(int, modify_ldt, int, func, void *, ptr, unsigned long, bytecount)
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 66)
+#define modify_ldt_ldt_s user_desc
+#endif
+#endif /* USE_CODE_COPY */
+
+void *shared_page;
+
+CPUX86State *cpu_86_init(void)
+{
+    CPUX86State *env;
+    static int inited;
+
+    cpu_exec_init();
+
+    env = malloc(sizeof(CPUX86State));
+    if (!env)
+        return NULL;
+    memset(env, 0, sizeof(CPUX86State));
+    /* init various static tables */
+    if (!inited) {
+        inited = 1;
+    }
+    cpu_single_env = env;
+    cpu_reset(env);
+    return env;
+}
+
+/* NOTE: must be called outside the CPU execute loop */
+void cpu_reset(CPUX86State *env)
+{
+}
+
+void cpu_x86_close(CPUX86State *env)
+{
+    free(env);
+}
+
+
+void cpu_dump_state(CPUState *env, FILE *f, 
+                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
+                    int flags)
+{
+}
+
+/***********************************************************/
+/* x86 mmu */
+/* XXX: add PGE support */
+
+void cpu_x86_set_a20(CPUX86State *env, int a20_state)
+{
+    a20_state = (a20_state != 0);
+    if (a20_state != ((env->a20_mask >> 20) & 1)) {
+#if defined(DEBUG_MMU)
+        printf("A20 update: a20=%d\n", a20_state);
+#endif
+        env->a20_mask = 0xffefffff | (a20_state << 20);
+    }
+}
+
+target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
+{
+        return addr;
+}
+
+//the evtchn fd for polling
+int evtchn_fd = -1;
+//the evtchn port for polling the notification, should be inputed as bochs's parameter
+u16 ioreq_port = 0;
+
+void *shared_page = NULL;
+
+//some functions to handle the io req packet
+
+//get the ioreq packets from share mem
+ioreq_t* __cpu_get_ioreq(void)
+{
+       ioreq_t *req;
+       req = &((vcpu_iodata_t *) shared_page)->vp_ioreq;
+       if (req->state == STATE_IOREQ_READY) {
+               req->state = STATE_IOREQ_INPROCESS;
+       } else {
+               fprintf(logfile, "False I/O requrest ... in-service already: %x, pvalid: %x,port: %llx, data: %llx, count: %llx, size: %llx\n", req->state, req->pdata_valid, req->addr, req->u.data, req->count, req->size);
+               req = NULL;
+       }
+
+       return req;
+}
+
+//use poll to get the port notification
+//ioreq_vec--out,the 
+//retval--the number of ioreq packet
+ioreq_t* cpu_get_ioreq(void)
+{
+       int rc;
+       u16 buf[2];
+       rc = read(evtchn_fd, buf, 2);
+       if (rc == 2 && buf[0] == ioreq_port){//got only one matched 16bit port index
+               // unmask the wanted port again
+               write(evtchn_fd, &ioreq_port, 2);
+
+               //get the io packet from shared memory
+               return __cpu_get_ioreq();
+       }
+
+       //read error or read nothing
+       return NULL;
+}
+
+unsigned long
+do_inp(CPUState *env, unsigned long addr, unsigned long size)
+{
+  switch(size) {
+      case 1:
+        return cpu_inb(env, addr);
+      case 2:
+        return cpu_inw(env, addr);
+      case 4:
+        return cpu_inl(env, addr);
+      default:
+       fprintf(logfile, "inp: bad size: %lx %lx\n", addr, size);
+        exit(-1);
+  }
+}
+
+void
+do_outp(CPUState *env, unsigned long addr, unsigned long size, 
+        unsigned long val)
+{
+  switch(size) {
+      case 1:
+        return cpu_outb(env, addr, val);
+      case 2:
+        return cpu_outw(env, addr, val);
+      case 4:
+        return cpu_outl(env, addr, val);
+      default:
+       fprintf(logfile, "outp: bad size: %lx %lx\n", addr, size);
+        exit(-1);
+  }
+}
+
+extern void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, 
+                                   int len, int is_write);
+
+static inline void
+read_physical(target_phys_addr_t addr, unsigned long size, void *val)
+{
+        return cpu_physical_memory_rw(addr, val, size, 0);
+}
+
+static inline void
+write_physical(target_phys_addr_t addr, unsigned long size, void *val)
+{
+        return cpu_physical_memory_rw(addr, val, size, 1);
+}
+
+//send the ioreq to device model
+void cpu_dispatch_ioreq(CPUState *env, ioreq_t *req)
+{
+       int i;
+       int sign;
+
+       sign = (req->df) ? -1 : 1;
+
+       if ((!req->pdata_valid) && (req->dir == IOREQ_WRITE)) {
+               if (req->size != 4) {
+                       // Bochs expects higher bits to be 0
+                       req->u.data &= (1UL << (8 * req->size))-1;
+               }
+       }
+
+       if (req->port_mm == 0){//port io
+               if(req->dir == IOREQ_READ){//read
+                       if (!req->pdata_valid) {
+                               req->u.data = do_inp(env, req->addr, req->size);
+                       } else {
+                               unsigned long tmp; 
+
+                               for (i = 0; i < req->count; i++) {
+                                       tmp = do_inp(env, req->addr, req->size);
+                                       write_physical((target_phys_addr_t)req->u.pdata + (sign * i * req->size), 
+                                                      req->size, &tmp);
+                               }
+                       }
+               } else if(req->dir == IOREQ_WRITE) {
+                       if (!req->pdata_valid) {
+                               do_outp(env, req->addr, req->size, req->u.data);
+                       } else {
+                               for (i = 0; i < req->count; i++) {
+                                       unsigned long tmp;
+
+                                       read_physical((target_phys_addr_t)req->u.pdata + (sign * i * req->size), req->size, 
+                                                     &tmp);
+                                       do_outp(env, req->addr, req->size, tmp);
+                               }
+                       }
+                       
+               }
+       } else if (req->port_mm == 1){//memory map io
+               if (!req->pdata_valid) {
+                       //handle stos
+                       if(req->dir == IOREQ_READ) { //read
+                               for (i = 0; i < req->count; i++) {
+                                       read_physical((target_phys_addr_t)req->addr + (sign * i * req->size), req->size, &req->u.data);
+                               }
+                       } else if(req->dir == IOREQ_WRITE) { //write
+                               for (i = 0; i < req->count; i++) {
+                                       write_physical((target_phys_addr_t)req->addr + (sign * i * req->size), req->size, &req->u.data);
+                               }
+                       }
+               } else {
+                       //handle movs
+                       unsigned long tmp;
+                       if (req->dir == IOREQ_READ) {
+                               for (i = 0; i < req->count; i++) {
+                                       read_physical((target_phys_addr_t)req->addr + (sign * i * req->size), req->size, &tmp);
+                                       write_physical((target_phys_addr_t)req->u.pdata + (sign * i * req->size), req->size, &tmp);
+                               }
+                       } else if (req->dir == IOREQ_WRITE) {
+                               for (i = 0; i < req->count; i++) {
+                                       read_physical((target_phys_addr_t)req->u.pdata + (sign * i * req->size), req->size, &tmp);
+                                       write_physical((target_phys_addr_t)req->addr + (sign * i * req->size), req->size, &tmp);
+                               }
+                       }
+               }
+       }
+        /* No state change if state = STATE_IORESP_HOOK */
+        if (req->state == STATE_IOREQ_INPROCESS)
+                req->state = STATE_IORESP_READY;
+       env->send_event = 1;
+}
+
+void
+cpu_handle_ioreq(CPUState *env)
+{
+       ioreq_t *req = cpu_get_ioreq();
+       if (req)
+               cpu_dispatch_ioreq(env, req);
+}
+
+void
+cpu_timer_handler(CPUState *env)
+{
+       cpu_handle_ioreq(env);
+}
+
+int xc_handle;
+
+#include <asm/bitops.h>
+
+void
+do_interrupt(CPUState *env, int vector)
+{
+       unsigned long *intr;
+
+       // Send a message on the event channel. Add the vector to the shared mem
+       // page.
+
+       intr = &(((vcpu_iodata_t *) shared_page)->vp_intr[0]);
+       set_bit(vector, intr);
+        fprintf(logfile, "injecting vector: %x\n", vector);
+       env->send_event = 1;
+}
+
+//static unsigned long tsc_per_tick = 1; /* XXX: calibrate */
+
+int main_loop(void)
+{
+       int vector;
+       fd_set rfds;
+       struct timeval tv;
+       extern CPUState *global_env;
+        extern int vm_running;
+        extern int shutdown_requested;
+       CPUState *env = global_env;
+       int retval;
+        extern void main_loop_wait(int);
+
+       /* Watch stdin (fd 0) to see when it has input. */
+       FD_ZERO(&rfds);
+
+       while (1) {
+            if (vm_running) {
+                if (shutdown_requested) {
+                    break;
+                }
+            }
+
+               /* Wait up to one seconds. */
+               tv.tv_sec = 0;
+               tv.tv_usec = 100000;
+               FD_SET(evtchn_fd, &rfds);
+
+               env->send_event = 0;
+               retval = select(evtchn_fd+1, &rfds, NULL, NULL, &tv);
+               if (retval == -1) {
+                       perror("select");
+                       return 0;
+               }
+
+#if __WORDSIZE == 32
+#define ULONGLONG_MAX   0xffffffffffffffffULL
+#else
+#define ULONGLONG_MAX   ULONG_MAX
+#endif
+
+               main_loop_wait(0);
+
+               cpu_timer_handler(env);
+               if (env->interrupt_request & CPU_INTERRUPT_HARD) {
+                        env->interrupt_request &= ~CPU_INTERRUPT_HARD;
+                       vector = cpu_get_pic_interrupt(env); 
+                       do_interrupt(env, vector);
+               }
+
+               if (env->send_event) {
+                       int ret;
+                       ret = xc_evtchn_send(xc_handle, ioreq_port);
+                       if (ret == -1) {
+                               fprintf(logfile, "evtchn_send failed on port: %d\n", ioreq_port);
+                       }
+               }
+       }
+       return 0;
+}
+
+CPUState *
+cpu_init()
+{
+       CPUX86State *env;
+      
+        cpu_exec_init();
+
+       env = malloc(sizeof(CPUX86State));
+       if (!env)
+               return NULL;
+       memset(env, 0, sizeof(CPUX86State));
+
+       cpu_single_env = env;
+
+       if (evtchn_fd != -1)//the evtchn has been opened by another cpu object
+               return NULL;
+
+       //use nonblock reading not polling, may change in future.
+       evtchn_fd = open("/dev/xen/evtchn", O_RDWR|O_NONBLOCK); 
+       if (evtchn_fd == -1) {
+               perror("open");
+               return NULL;
+       }
+
+       fprintf(logfile, "listening to port: %d\n", ioreq_port);
+       /*unmask the wanted port -- bind*/
+       if (ioctl(evtchn_fd, ('E'<<8)|2, ioreq_port) == -1) {
+               perror("ioctl");
+               return NULL;
+       }
+
+       return env;
+}
diff --git a/tools/ioemu/target-i386-dm/qemu-ifup b/tools/ioemu/target-i386-dm/qemu-ifup
new file mode 100755 (executable)
index 0000000..87bff34
--- /dev/null
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+#. /etc/rc.d/init.d/functions
+#ulimit -c unlimited
+
+echo 'config qemu network with xen bridge for '
+echo $*
+
+ifconfig $1 0.0.0.0 up
+brctl addif xen-br0 $1
diff --git a/tools/ioemu/target-i386-dm/qemu-vgaram-bin.gz b/tools/ioemu/target-i386-dm/qemu-vgaram-bin.gz
new file mode 100644 (file)
index 0000000..86e44ab
Binary files /dev/null and b/tools/ioemu/target-i386-dm/qemu-vgaram-bin.gz differ
diff --git a/tools/ioemu/tests/Makefile b/tools/ioemu/tests/Makefile
new file mode 100644 (file)
index 0000000..c0ee7b2
--- /dev/null
@@ -0,0 +1,84 @@
+-include ../config-host.mak
+
+CFLAGS=-Wall -O2 -g
+LDFLAGS=
+
+ifeq ($(ARCH),i386)
+TESTS=linux-test testthread sha1-i386 test-i386 runcom
+endif
+TESTS+=sha1# test_path
+#TESTS+=test_path
+
+QEMU=../i386-user/qemu-i386
+
+all: $(TESTS)
+
+hello-i386: hello-i386.c
+       $(CC) -nostdlib $(CFLAGS) -static $(LDFLAGS) -o $@ $<
+       strip $@
+
+testthread: testthread.c
+       $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -lpthread
+
+test_path: test_path.c
+       $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
+       ./$@ || { rm $@; exit 1; }
+
+# i386 emulation test (test various opcodes) */
+test-i386: test-i386.c test-i386-code16.S test-i386-vm86.S \
+           test-i386.h test-i386-shift.h test-i386-muldiv.h
+       $(CC) $(CFLAGS) $(LDFLAGS) -static -o $@ test-i386.c \
+              test-i386-code16.S test-i386-vm86.S -lm
+
+ifeq ($(ARCH),i386)
+test: test-i386
+       ./test-i386 > test-i386.ref
+else
+test:
+endif
+       $(QEMU) test-i386 > test-i386.out
+       @if diff -u test-i386.ref test-i386.out ; then echo "Auto Test OK"; fi
+ifeq ($(ARCH),i386)
+       $(QEMU) -no-code-copy test-i386 > test-i386.out
+       @if diff -u test-i386.ref test-i386.out ; then echo "Auto Test OK (no code copy)"; fi
+endif
+
+# generic Linux and CPU test
+linux-test: linux-test.c
+       $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -lm
+
+# speed test
+sha1-i386: sha1.c
+       $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
+
+sha1: sha1.c
+       $(HOST_CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
+
+speed: sha1 sha1-i386
+       time ./sha1
+       time $(QEMU) ./sha1-i386
+
+# vm86 test
+runcom: runcom.c
+       $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
+
+# NOTE: -fomit-frame-pointer is currently needed : this is a bug in libqemu
+qruncom: qruncom.c ../i386-user/libqemu.a
+       $(CC) $(CFLAGS) -fomit-frame-pointer $(LDFLAGS) -I../target-i386 -I.. -I../i386-user \
+              -o $@ $< -L../i386-user -lqemu -lm
+
+# arm test
+hello-arm: hello-arm.o
+       arm-linux-ld -o $@ $<
+
+hello-arm.o: hello-arm.c
+       arm-linux-gcc -Wall -g -O2 -c -o $@ $<
+
+# XXX: find a way to compile easily a test for each arch
+test2:
+       @for arch in i386 arm sparc ppc; do \
+           ../$${arch}-user/qemu-$${arch} $${arch}/ls -l linux-test.c ; \
+        done
+
+clean:
+       rm -f *~ *.o test-i386.out test-i386.ref qruncom $(TESTS)
diff --git a/tools/ioemu/tests/hello-arm.c b/tools/ioemu/tests/hello-arm.c
new file mode 100644 (file)
index 0000000..f84e6cb
--- /dev/null
@@ -0,0 +1,113 @@
+#define __NR_SYSCALL_BASE      0x900000
+#define __NR_exit1                     (__NR_SYSCALL_BASE+  1)
+#define __NR_write                     (__NR_SYSCALL_BASE+  4)
+
+#define __sys2(x) #x
+#define __sys1(x) __sys2(x)
+
+#ifndef __syscall
+#define __syscall(name) "swi\t" __sys1(__NR_##name) "\n\t"
+#endif
+
+#define __syscall_return(type, res)                                    \
+do {                                                                   \
+       return (type) (res);                                            \
+} while (0)
+
+#define _syscall0(type,name)                                           \
+type name(void) {                                                      \
+  long __res;                                                          \
+  __asm__ __volatile__ (                                               \
+  __syscall(name)                                                      \
+  "mov %0,r0"                                                          \
+  :"=r" (__res) : : "r0","lr");                                                \
+  __syscall_return(type,__res);                                                \
+}
+
+#define _syscall1(type,name,type1,arg1)                                        \
+type name(type1 arg1) {                                                        \
+  long __res;                                                          \
+  __asm__ __volatile__ (                                               \
+  "mov\tr0,%1\n\t"                                                     \
+  __syscall(name)                                                      \
+  "mov %0,r0"                                                          \
+        : "=r" (__res)                                                 \
+        : "r" ((long)(arg1))                                           \
+       : "r0","lr");                                                   \
+  __syscall_return(type,__res);                                                \
+}
+
+#define _syscall2(type,name,type1,arg1,type2,arg2)                     \
+type name(type1 arg1,type2 arg2) {                                     \
+  long __res;                                                          \
+  __asm__ __volatile__ (                                               \
+  "mov\tr0,%1\n\t"                                                     \
+  "mov\tr1,%2\n\t"                                                     \
+  __syscall(name)                                                      \
+  "mov\t%0,r0"                                                         \
+        : "=r" (__res)                                                 \
+        : "r" ((long)(arg1)),"r" ((long)(arg2))                                \
+       : "r0","r1","lr");                                              \
+  __syscall_return(type,__res);                                                \
+}
+
+
+#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)          \
+type name(type1 arg1,type2 arg2,type3 arg3) {                          \
+  long __res;                                                          \
+  __asm__ __volatile__ (                                               \
+  "mov\tr0,%1\n\t"                                                     \
+  "mov\tr1,%2\n\t"                                                     \
+  "mov\tr2,%3\n\t"                                                     \
+  __syscall(name)                                                      \
+  "mov\t%0,r0"                                                         \
+        : "=r" (__res)                                                 \
+        : "r" ((long)(arg1)),"r" ((long)(arg2)),"r" ((long)(arg3))     \
+        : "r0","r1","r2","lr");                                                \
+  __syscall_return(type,__res);                                                \
+}
+
+
+#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)               \
+type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) {                            \
+  long __res;                                                                          \
+  __asm__ __volatile__ (                                                               \
+  "mov\tr0,%1\n\t"                                                                     \
+  "mov\tr1,%2\n\t"                                                                     \
+  "mov\tr2,%3\n\t"                                                                     \
+  "mov\tr3,%4\n\t"                                                                     \
+  __syscall(name)                                                                      \
+  "mov\t%0,r0"                                                                         \
+       : "=r" (__res)                                                                  \
+       : "r" ((long)(arg1)),"r" ((long)(arg2)),"r" ((long)(arg3)),"r" ((long)(arg4))   \
+       : "r0","r1","r2","r3","lr");                                                    \
+  __syscall_return(type,__res);                                                                \
+}
+  
+
+#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5)    \
+type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) {                        \
+  long __res;                                                                          \
+  __asm__ __volatile__ (                                                               \
+  "mov\tr0,%1\n\t"                                                                     \
+  "mov\tr1,%2\n\t"                                                                     \
+  "mov\tr2,%3\n\t"                                                                     \
+  "mov\tr3,%4\n\t"                                                                     \
+  "mov\tr4,%5\n\t"                                                                     \
+  __syscall(name)                                                                      \
+  "mov\t%0,r0"                                                                         \
+       : "=r" (__res)                                                                  \
+       : "r" ((long)(arg1)),"r" ((long)(arg2)),"r" ((long)(arg3)),"r" ((long)(arg4)),  \
+         "r" ((long)(arg5))                                                            \
+       : "r0","r1","r2","r3","r4","lr");                                               \
+  __syscall_return(type,__res);                                                                \
+}
+
+_syscall1(int,exit1,int,status);
+_syscall3(int,write,int,fd,const char *,buf, int, len);
+
+void _start(void)
+{
+    write(1, "Hello World\n", 12);
+    exit1(0);
+}
diff --git a/tools/ioemu/tests/hello-i386.c b/tools/ioemu/tests/hello-i386.c
new file mode 100644 (file)
index 0000000..e00245d
--- /dev/null
@@ -0,0 +1,26 @@
+#include <asm/unistd.h>
+
+extern inline volatile void exit(int status)
+{
+  int __res;
+  __asm__ volatile ("movl %%ecx,%%ebx\n"\
+                   "int $0x80" \
+                   :  "=a" (__res) : "0" (__NR_exit),"c" ((long)(status)));
+}
+
+extern inline int write(int fd, const char * buf, int len)
+{
+  int status;
+  __asm__ volatile ("pushl %%ebx\n"\
+                   "movl %%esi,%%ebx\n"\
+                   "int $0x80\n" \
+                   "popl %%ebx\n"\
+                   : "=a" (status) \
+                   : "0" (__NR_write),"S" ((long)(fd)),"c" ((long)(buf)),"d" ((long)(len)));
+}
+
+void _start(void)
+{
+    write(1, "Hello World\n", 12);
+    exit(0);
+}
diff --git a/tools/ioemu/tests/linux-test.c b/tools/ioemu/tests/linux-test.c
new file mode 100644 (file)
index 0000000..6ca9029
--- /dev/null
@@ -0,0 +1,536 @@
+/*
+ *  linux and CPU test
+ * 
+ *  Copyright (c) 2003 Fabrice Bellard
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include <utime.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/uio.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sched.h>
+#include <dirent.h>
+#include <setjmp.h>
+#include <sys/shm.h>
+
+#define TESTPATH "/tmp/linux-test.tmp"
+#define TESTPORT 7654
+#define STACK_SIZE 16384
+
+void error1(const char *filename, int line, const char *fmt, ...)
+{
+    va_list ap;
+    va_start(ap, fmt);
+    fprintf(stderr, "%s:%d: ", filename, line);
+    vfprintf(stderr, fmt, ap);
+    fprintf(stderr, "\n");
+    va_end(ap);
+    exit(1);
+}
+
+int __chk_error(const char *filename, int line, int ret)
+{
+    if (ret < 0) {
+        error1(filename, line, "%m (ret=%d, errno=%d)", 
+               ret, errno);
+    }
+    return ret;
+}
+
+#define error(fmt, args...) error1(__FILE__, __LINE__, fmt, ##args)
+
+#define chk_error(ret) __chk_error(__FILE__, __LINE__, (ret))
+
+/*******************************************************/
+
+#define FILE_BUF_SIZE 300
+
+void test_file(void)
+{
+    int fd, i, len, ret;
+    uint8_t buf[FILE_BUF_SIZE];
+    uint8_t buf2[FILE_BUF_SIZE];
+    uint8_t buf3[FILE_BUF_SIZE];
+    char cur_dir[1024];
+    struct stat st;
+    struct utimbuf tbuf;
+    struct iovec vecs[2];
+    DIR *dir;
+    struct dirent *de;
+
+    /* clean up, just in case */
+    unlink(TESTPATH "/file1");
+    unlink(TESTPATH "/file2");
+    unlink(TESTPATH "/file3");
+    rmdir(TESTPATH);
+
+    if (getcwd(cur_dir, sizeof(cur_dir)) == NULL)
+        error("getcwd");
+    
+    chk_error(mkdir(TESTPATH, 0755));
+    
+    chk_error(chdir(TESTPATH));
+    
+    /* open/read/write/close/readv/writev/lseek */
+
+    fd = chk_error(open("file1", O_WRONLY | O_TRUNC | O_CREAT, 0644));
+    for(i=0;i < FILE_BUF_SIZE; i++)
+        buf[i] = i;
+    len = chk_error(write(fd, buf, FILE_BUF_SIZE / 2));
+    if (len != (FILE_BUF_SIZE / 2))
+        error("write");
+    vecs[0].iov_base = buf + (FILE_BUF_SIZE / 2);
+    vecs[0].iov_len = 16;
+    vecs[1].iov_base = buf + (FILE_BUF_SIZE / 2) + 16;
+    vecs[1].iov_len = (FILE_BUF_SIZE / 2) - 16;
+    len = chk_error(writev(fd, vecs, 2));
+    if (len != (FILE_BUF_SIZE / 2))
+     error("writev");
+    chk_error(close(fd));
+
+    chk_error(rename("file1", "file2"));
+
+    fd = chk_error(open("file2", O_RDONLY));
+
+    len = chk_error(read(fd, buf2, FILE_BUF_SIZE));
+    if (len != FILE_BUF_SIZE)
+        error("read");
+    if (memcmp(buf, buf2, FILE_BUF_SIZE) != 0)
+        error("memcmp");
+    
+#define FOFFSET 16
+    ret = chk_error(lseek(fd, FOFFSET, SEEK_SET));
+    if (ret != 16)
+        error("lseek");
+    vecs[0].iov_base = buf3;
+    vecs[0].iov_len = 32;
+    vecs[1].iov_base = buf3 + 32;
+    vecs[1].iov_len = FILE_BUF_SIZE - FOFFSET - 32;
+    len = chk_error(readv(fd, vecs, 2));
+    if (len != FILE_BUF_SIZE - FOFFSET)
+        error("readv");
+    if (memcmp(buf + FOFFSET, buf3, FILE_BUF_SIZE - FOFFSET) != 0)
+        error("memcmp");
+    
+    chk_error(close(fd));
+
+    /* access */
+    chk_error(access("file2", R_OK));
+
+    /* stat/chmod/utime/truncate */
+
+    chk_error(chmod("file2", 0600));
+    tbuf.actime = 1001;
+    tbuf.modtime = 1000;
+    chk_error(truncate("file2", 100));
+    chk_error(utime("file2", &tbuf));
+    chk_error(stat("file2", &st));
+    if (st.st_size != 100)
+        error("stat size");
+    if (!S_ISREG(st.st_mode))
+        error("stat mode");
+    if ((st.st_mode & 0777) != 0600)
+        error("stat mode2");
+    if (st.st_atime != 1001 ||
+        st.st_mtime != 1000)
+        error("stat time");
+
+    chk_error(stat(TESTPATH, &st));
+    if (!S_ISDIR(st.st_mode))
+        error("stat mode");
+
+    /* fstat */
+    fd = chk_error(open("file2", O_RDWR));
+    chk_error(ftruncate(fd, 50));
+    chk_error(fstat(fd, &st));
+    chk_error(close(fd));
+    
+    if (st.st_size != 50)
+        error("stat size");
+    if (!S_ISREG(st.st_mode))
+        error("stat mode");
+    
+    /* symlink/lstat */
+    chk_error(symlink("file2", "file3"));
+    chk_error(lstat("file3", &st));
+    if (!S_ISLNK(st.st_mode))
+        error("stat mode");
+    
+    /* getdents */
+    dir = opendir(TESTPATH);
+    if (!dir)
+        error("opendir");
+    len = 0;
+    for(;;) {
+        de = readdir(dir);
+        if (!de)
+            break;
+        if (strcmp(de->d_name, ".") != 0 &&
+            strcmp(de->d_name, "..") != 0 &&
+            strcmp(de->d_name, "file2") != 0 &&
+            strcmp(de->d_name, "file3") != 0)
+            error("readdir");
+        len++;
+    }
+    closedir(dir);
+    if (len != 4)
+        error("readdir");
+
+    chk_error(unlink("file3"));
+    chk_error(unlink("file2"));
+    chk_error(chdir(cur_dir));
+    chk_error(rmdir(TESTPATH));
+}
+
+void test_fork(void)
+{
+    int pid, status;
+
+    pid = chk_error(fork());
+    if (pid == 0) {
+        /* child */
+        exit(2);
+    }
+    chk_error(waitpid(pid, &status, 0));
+    if (!WIFEXITED(status) || WEXITSTATUS(status) != 2)
+        error("waitpid status=0x%x", status);
+}
+
+void test_time(void)
+{
+    struct timeval tv, tv2;
+    struct timespec ts, rem;
+    struct rusage rusg1, rusg2;
+    int ti, i;
+
+    chk_error(gettimeofday(&tv, NULL));
+    rem.tv_sec = 1;
+    ts.tv_sec = 0;
+    ts.tv_nsec = 20 * 1000000;
+    chk_error(nanosleep(&ts, &rem));
+    if (rem.tv_sec != 1)
+        error("nanosleep");
+    chk_error(gettimeofday(&tv2, NULL));
+    ti = tv2.tv_sec - tv.tv_sec;
+    if (ti >= 2)
+        error("gettimeofday");
+    
+    chk_error(getrusage(RUSAGE_SELF, &rusg1));
+    for(i = 0;i < 10000; i++);
+    chk_error(getrusage(RUSAGE_SELF, &rusg2));
+    if ((rusg2.ru_utime.tv_sec - rusg1.ru_utime.tv_sec) < 0 ||
+        (rusg2.ru_stime.tv_sec - rusg1.ru_stime.tv_sec) < 0)
+        error("getrusage");
+}
+
+void pstrcpy(char *buf, int buf_size, const char *str)
+{
+    int c;
+    char *q = buf;
+
+    if (buf_size <= 0)
+        return;
+
+    for(;;) {
+        c = *str++;
+        if (c == 0 || q >= buf + buf_size - 1)
+            break;
+        *q++ = c;
+    }
+    *q = '\0';
+}
+
+/* strcat and truncate. */
+char *pstrcat(char *buf, int buf_size, const char *s)
+{
+    int len;
+    len = strlen(buf);
+    if (len < buf_size) 
+        pstrcpy(buf + len, buf_size - len, s);
+    return buf;
+}
+
+int server_socket(void)
+{
+    int val, fd;
+    struct sockaddr_in sockaddr;
+
+    /* server socket */
+    fd = chk_error(socket(PF_INET, SOCK_STREAM, 0));
+
+    val = 1;
+    chk_error(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)));
+
+    sockaddr.sin_family = AF_INET;
+    sockaddr.sin_port = htons(TESTPORT);
+    sockaddr.sin_addr.s_addr = 0;
+    chk_error(bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr)));
+    chk_error(listen(fd, 0));
+    return fd;
+
+}
+
+int client_socket(void)
+{
+    int fd;
+    struct sockaddr_in sockaddr;
+
+    /* server socket */
+    fd = chk_error(socket(PF_INET, SOCK_STREAM, 0));
+    sockaddr.sin_family = AF_INET;
+    sockaddr.sin_port = htons(TESTPORT);
+    inet_aton("127.0.0.1", &sockaddr.sin_addr);
+    chk_error(connect(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr)));
+    return fd;
+}
+
+const char socket_msg[] = "hello socket\n";
+
+void test_socket(void)
+{
+    int server_fd, client_fd, fd, pid, ret, val;
+    struct sockaddr_in sockaddr;
+    socklen_t len;
+    char buf[512];
+
+    server_fd = server_socket();
+
+    /* test a few socket options */
+    len = sizeof(val);
+    chk_error(getsockopt(server_fd, SOL_SOCKET, SO_TYPE, &val, &len));
+    if (val != SOCK_STREAM)
+        error("getsockopt");
+    
+    pid = chk_error(fork());
+    if (pid == 0) {
+        client_fd = client_socket();
+        send(client_fd, socket_msg, sizeof(socket_msg), 0);
+        close(client_fd);
+        exit(0);
+    }
+    len = sizeof(sockaddr);
+    fd = chk_error(accept(server_fd, (struct sockaddr *)&sockaddr, &len));
+
+    ret = chk_error(recv(fd, buf, sizeof(buf), 0));
+    if (ret != sizeof(socket_msg))
+        error("recv");
+    if (memcmp(buf, socket_msg, sizeof(socket_msg)) != 0)
+        error("socket_msg");
+    chk_error(close(fd));
+    chk_error(close(server_fd));
+}
+
+#define WCOUNT_MAX 512
+
+void test_pipe(void)
+{
+    fd_set rfds, wfds;
+    int fds[2], fd_max, ret;
+    uint8_t ch;
+    int wcount, rcount;
+
+    chk_error(pipe(fds));
+    chk_error(fcntl(fds[0], F_SETFL, O_NONBLOCK));
+    chk_error(fcntl(fds[1], F_SETFL, O_NONBLOCK));
+    wcount = 0;
+    rcount = 0;
+    for(;;) {
+        FD_ZERO(&rfds);
+        fd_max = fds[0];
+        FD_SET(fds[0], &rfds);
+
+        FD_ZERO(&wfds);
+        FD_SET(fds[1], &wfds);
+        if (fds[1] > fd_max)
+            fd_max = fds[1];
+
+        ret = chk_error(select(fd_max + 1, &rfds, &wfds, NULL, NULL));
+        if (ret > 0) {
+            if (FD_ISSET(fds[0], &rfds)) {
+                chk_error(read(fds[0], &ch, 1));
+                rcount++;
+                if (rcount >= WCOUNT_MAX)
+                    break;
+            }
+            if (FD_ISSET(fds[1], &wfds)) {
+                ch = 'a';
+                chk_error(write(fds[0], &ch, 1));
+                wcount++;
+            }
+        }
+    }
+    chk_error(close(fds[0]));
+    chk_error(close(fds[1]));
+}
+
+int thread1_res;
+int thread2_res;
+
+int thread1_func(void *arg)
+{
+    int i;
+    for(i=0;i<5;i++) {
+        thread1_res++;
+        usleep(10 * 1000);
+    }
+    return 0;
+}
+
+int thread2_func(void *arg)
+{
+    int i;
+    for(i=0;i<6;i++) {
+        thread2_res++;
+        usleep(10 * 1000);
+    }
+    return 0;
+}
+
+void test_clone(void)
+{
+    uint8_t *stack1, *stack2;
+    int pid1, pid2, status1, status2;
+
+    stack1 = malloc(STACK_SIZE);
+    pid1 = chk_error(clone(thread1_func, stack1 + STACK_SIZE, 
+                           CLONE_VM | CLONE_FS | CLONE_FILES | SIGCHLD, "hello1"));
+
+    stack2 = malloc(STACK_SIZE);
+    pid2 = chk_error(clone(thread2_func, stack2 + STACK_SIZE, 
+                           CLONE_VM | CLONE_FS | CLONE_FILES | SIGCHLD, "hello2"));
+
+    while (waitpid(pid1, &status1, 0) != pid1);
+    while (waitpid(pid2, &status2, 0) != pid2);
+    if (thread1_res != 5 ||
+        thread2_res != 6)
+        error("clone");
+}
+
+/***********************************/
+
+volatile int alarm_count;
+jmp_buf jmp_env;
+
+void sig_alarm(int sig)
+{
+    if (sig != SIGALRM)
+        error("signal");
+    alarm_count++;
+}
+
+void sig_segv(int sig, siginfo_t *info, void *puc)
+{
+    if (sig != SIGSEGV)
+        error("signal");
+    longjmp(jmp_env, 1);
+}
+
+void test_signal(void)
+{
+    struct sigaction act;
+    struct itimerval it, oit;
+
+    /* timer test */
+
+    alarm_count = 0;
+
+    act.sa_handler = sig_alarm;
+    sigemptyset(&act.sa_mask);
+    act.sa_flags = 0;
+    chk_error(sigaction(SIGALRM, &act, NULL));
+    
+    it.it_interval.tv_sec = 0;
+    it.it_interval.tv_usec = 10 * 1000;
+    it.it_value.tv_sec = 0;
+    it.it_value.tv_usec = 10 * 1000;
+    chk_error(setitimer(ITIMER_REAL, &it, NULL));
+    chk_error(getitimer(ITIMER_REAL, &oit));
+    if (oit.it_value.tv_sec != it.it_value.tv_sec ||
+        oit.it_value.tv_usec != it.it_value.tv_usec)
+        error("itimer");
+    
+    while (alarm_count < 5) {
+        usleep(10 * 1000);
+    }
+
+    it.it_interval.tv_sec = 0;
+    it.it_interval.tv_usec = 0;
+    it.it_value.tv_sec = 0;
+    it.it_value.tv_usec = 0;
+    memset(&oit, 0xff, sizeof(oit));
+    chk_error(setitimer(ITIMER_REAL, &it, &oit));
+    if (oit.it_value.tv_sec != 0 ||
+        oit.it_value.tv_usec != 10 * 1000)
+        error("setitimer");
+
+    /* SIGSEGV test */
+    act.sa_sigaction = sig_segv;
+    sigemptyset(&act.sa_mask);
+    act.sa_flags = SA_SIGINFO;
+    chk_error(sigaction(SIGSEGV, &act, NULL));
+    if (setjmp(jmp_env) == 0) {
+        *(uint8_t *)0 = 0;
+    }
+    
+    act.sa_handler = SIG_DFL;
+    sigemptyset(&act.sa_mask);
+    act.sa_flags = 0;
+    chk_error(sigaction(SIGSEGV, &act, NULL));
+}
+
+#define SHM_SIZE 32768
+
+void test_shm(void)
+{
+    void *ptr;
+    int shmid;
+
+    shmid = chk_error(shmget(IPC_PRIVATE, SHM_SIZE, IPC_CREAT | 0777));
+    ptr = shmat(shmid, NULL, 0);
+    if (!ptr)
+        error("shmat");
+
+    memset(ptr, 0, SHM_SIZE);
+
+    chk_error(shmctl(shmid, IPC_RMID, 0));
+    chk_error(shmdt(ptr));
+}
+
+int main(int argc, char **argv)
+{
+    test_file();
+    test_fork();
+    test_time();
+    test_socket();
+    //    test_clone();
+    test_signal();
+    test_shm();
+    return 0;
+}
diff --git a/tools/ioemu/tests/pi_10.com b/tools/ioemu/tests/pi_10.com
new file mode 100644 (file)
index 0000000..8993ba1
Binary files /dev/null and b/tools/ioemu/tests/pi_10.com differ
diff --git a/tools/ioemu/tests/qruncom.c b/tools/ioemu/tests/qruncom.c
new file mode 100644 (file)
index 0000000..fcc069f
--- /dev/null
@@ -0,0 +1,308 @@
+/*
+ * Example of use of user mode libqemu: launch a basic .com DOS
+ * executable
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <signal.h>
+
+#include "cpu.h"
+
+//#define SIGTEST
+
+CPUState *cpu_single_env = NULL;
+
+void cpu_outb(CPUState *env, int addr, int val)
+{
+    fprintf(stderr, "outb: port=0x%04x, data=%02x\n", addr, val);
+}
+
+void cpu_outw(CPUState *env, int addr, int val)
+{
+    fprintf(stderr, "outw: port=0x%04x, data=%04x\n", addr, val);
+}
+
+void cpu_outl(CPUState *env, int addr, int val)
+{
+    fprintf(stderr, "outl: port=0x%04x, data=%08x\n", addr, val);
+}
+
+int cpu_inb(CPUState *env, int addr)
+{
+    fprintf(stderr, "inb: port=0x%04x\n", addr);
+    return 0;
+}
+
+int cpu_inw(CPUState *env, int addr)
+{
+    fprintf(stderr, "inw: port=0x%04x\n", addr);
+    return 0;
+}
+
+int cpu_inl(CPUState *env, int addr)
+{
+    fprintf(stderr, "inl: port=0x%04x\n", addr);
+    return 0;
+}
+
+int cpu_get_pic_interrupt(CPUState *env)
+{
+    return -1;
+}
+
+uint64_t cpu_get_tsc(CPUState *env)
+{
+    return 0;
+}
+
+static void set_gate(void *ptr, unsigned int type, unsigned int dpl, 
+                     unsigned long addr, unsigned int sel)
+{
+    unsigned int e1, e2;
+    e1 = (addr & 0xffff) | (sel << 16);
+    e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8);
+    stl((uint8_t *)ptr, e1);
+    stl((uint8_t *)ptr + 4, e2);
+}
+
+uint64_t idt_table[256];
+
+/* only dpl matters as we do only user space emulation */
+static void set_idt(int n, unsigned int dpl)
+{
+    set_gate(idt_table + n, 0, dpl, 0, 0);
+}
+
+void qemu_free(void *ptr)
+{
+    free(ptr);
+}
+
+void *qemu_malloc(size_t size)
+{
+    return malloc(size);
+}
+
+void qemu_printf(const char *fmt, ...)
+{
+    va_list ap;
+    va_start(ap, fmt);
+    vprintf(fmt, ap);
+    va_end(ap);
+}
+
+/* XXX: this is a bug in helper2.c */
+int errno;
+
+/**********************************************/
+
+#define COM_BASE_ADDR    0x10100
+
+void usage(void)
+{
+    printf("qruncom version 0.1 (c) 2003 Fabrice Bellard\n"
+           "usage: qruncom file.com\n"
+           "user mode libqemu demo: run simple .com DOS executables\n");
+    exit(1);
+}
+
+static inline uint8_t *seg_to_linear(unsigned int seg, unsigned int reg)
+{
+    return (uint8_t *)((seg << 4) + (reg & 0xffff));
+}
+
+static inline void pushw(CPUState *env, int val)
+{
+    env->regs[R_ESP] = (env->regs[R_ESP] & ~0xffff) | ((env->regs[R_ESP] - 2) & 0xffff);
+    *(uint16_t *)seg_to_linear(env->segs[R_SS].selector, env->regs[R_ESP]) = val;
+}
+
+static void host_segv_handler(int host_signum, siginfo_t *info, 
+                              void *puc)
+{
+    if (cpu_signal_handler(host_signum, info, puc)) {
+        return;
+    }
+    abort();
+}
+
+int main(int argc, char **argv)
+{
+    uint8_t *vm86_mem;
+    const char *filename;
+    int fd, ret, seg;
+    CPUState *env;
+
+    if (argc != 2)
+        usage();
+    filename = argv[1];
+    
+    vm86_mem = mmap((void *)0x00000000, 0x110000, 
+                    PROT_WRITE | PROT_READ | PROT_EXEC, 
+                    MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0);
+    if (vm86_mem == MAP_FAILED) {
+        perror("mmap");
+        exit(1);
+    }
+
+    /* load the MSDOS .com executable */
+    fd = open(filename, O_RDONLY);
+    if (fd < 0) {
+        perror(filename);
+        exit(1);
+    }
+    ret = read(fd, vm86_mem + COM_BASE_ADDR, 65536 - 256);
+    if (ret < 0) {
+        perror("read");
+        exit(1);
+    }
+    close(fd);
+
+    /* install exception handler for CPU emulator */
+    {
+        struct sigaction act;
+        
+        sigfillset(&act.sa_mask);
+        act.sa_flags = SA_SIGINFO;
+        //        act.sa_flags |= SA_ONSTACK;
+
+        act.sa_sigaction = host_segv_handler;
+        sigaction(SIGSEGV, &act, NULL);
+        sigaction(SIGBUS, &act, NULL);
+#if defined (TARGET_I386) && defined(USE_CODE_COPY)
+        sigaction(SIGFPE, &act, NULL);
+#endif
+    }
+
+    //    cpu_set_log(CPU_LOG_TB_IN_ASM | CPU_LOG_TB_OUT_ASM | CPU_LOG_EXEC);
+
+    env = cpu_init();
+
+    /* disable code copy to simplify debugging */
+    code_copy_enabled = 0;
+
+    /* set user mode state (XXX: should be done automatically by
+       cpu_init ?) */
+    env->user_mode_only = 1;
+
+    cpu_x86_set_cpl(env, 3);
+
+    env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
+    /* NOTE: hflags duplicates some of the virtual CPU state */
+    env->hflags |= HF_PE_MASK | VM_MASK;
+
+    /* flags setup : we activate the IRQs by default as in user
+       mode. We also activate the VM86 flag to run DOS code */
+    env->eflags |= IF_MASK | VM_MASK;
+    
+    /* init basic registers */
+    env->eip = 0x100;
+    env->regs[R_ESP] = 0xfffe;
+    seg = (COM_BASE_ADDR - 0x100) >> 4;
+
+    cpu_x86_load_seg_cache(env, R_CS, seg, 
+                           (uint8_t *)(seg << 4), 0xffff, 0);
+    cpu_x86_load_seg_cache(env, R_SS, seg, 
+                           (uint8_t *)(seg << 4), 0xffff, 0);
+    cpu_x86_load_seg_cache(env, R_DS, seg, 
+                           (uint8_t *)(seg << 4), 0xffff, 0);
+    cpu_x86_load_seg_cache(env, R_ES, seg, 
+                           (uint8_t *)(seg << 4), 0xffff, 0);
+    cpu_x86_load_seg_cache(env, R_FS, seg, 
+                           (uint8_t *)(seg << 4), 0xffff, 0);
+    cpu_x86_load_seg_cache(env, R_GS, seg, 
+                           (uint8_t *)(seg << 4), 0xffff, 0);
+
+    /* exception support */
+    env->idt.base = (void *)idt_table;
+    env->idt.limit = sizeof(idt_table) - 1;
+    set_idt(0, 0);
+    set_idt(1, 0);
+    set_idt(2, 0);
+    set_idt(3, 3);
+    set_idt(4, 3);
+    set_idt(5, 3);
+    set_idt(6, 0);
+    set_idt(7, 0);
+    set_idt(8, 0);
+    set_idt(9, 0);
+    set_idt(10, 0);
+    set_idt(11, 0);
+    set_idt(12, 0);
+    set_idt(13, 0);
+    set_idt(14, 0);
+    set_idt(15, 0);
+    set_idt(16, 0);
+    set_idt(17, 0);
+    set_idt(18, 0);
+    set_idt(19, 0);
+        
+    /* put return code */
+    *seg_to_linear(env->segs[R_CS].selector, 0) = 0xb4; /* mov ah, $0 */
+    *seg_to_linear(env->segs[R_CS].selector, 1) = 0x00;
+    *seg_to_linear(env->segs[R_CS].selector, 2) = 0xcd; /* int $0x21 */
+    *seg_to_linear(env->segs[R_CS].selector, 3) = 0x21;
+    pushw(env, 0x0000);
+
+    /* the value of these registers seem to be assumed by pi_10.com */
+    env->regs[R_ESI] = 0x100;
+    env->regs[R_ECX] = 0xff;
+    env->regs[R_EBP] = 0x0900;
+    env->regs[R_EDI] = 0xfffe;
+
+    /* inform the emulator of the mmaped memory */
+    page_set_flags(0x00000000, 0x110000, 
+                   PAGE_WRITE | PAGE_READ | PAGE_EXEC | PAGE_VALID);
+
+    for(;;) {
+        ret = cpu_x86_exec(env);
+        switch(ret) {
+        case EXCP0D_GPF:
+            {
+                int int_num, ah;
+                int_num = *(env->segs[R_CS].base + env->eip + 1);
+                if (int_num != 0x21)
+                    goto unknown_int;
+                ah = (env->regs[R_EAX] >> 8) & 0xff;
+                switch(ah) {
+                case 0x00: /* exit */
+                    exit(0);
+                case 0x02: /* write char */
+                    {
+                        uint8_t c = env->regs[R_EDX];
+                        write(1, &c, 1);
+                    }
+                    break;
+                case 0x09: /* write string */
+                    {
+                        uint8_t c;
+                        for(;;) {
+                            c = *seg_to_linear(env->segs[R_DS].selector, env->regs[R_EAX]);
+                            if (c == '$')
+                                break;
+                            write(1, &c, 1);
+                        }
+                        env->regs[R_EAX] = (env->regs[R_EAX] & ~0xff) | '$';
+                    }
+                    break;
+                default:
+                unknown_int:
+                    fprintf(stderr, "unsupported int 0x%02x\n", int_num);
+                    cpu_dump_state(env, stderr, 0);
+                    //                    exit(1);
+                }
+                env->eip += 2;
+            }
+            break;
+        default:
+            fprintf(stderr, "unhandled cpu_exec return code (0x%x)\n", ret);
+            cpu_dump_state(env, stderr, 0);
+            exit(1);
+        }
+    }
+}
diff --git a/tools/ioemu/tests/runcom.c b/tools/ioemu/tests/runcom.c
new file mode 100644 (file)
index 0000000..43deeca
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ * Simple example of use of vm86: launch a basic .com DOS executable
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <signal.h>
+
+#include <linux/unistd.h>
+#include <asm/vm86.h>
+
+//#define SIGTEST
+
+#undef __syscall_return
+#define __syscall_return(type, res) \
+do { \
+       return (type) (res); \
+} while (0)
+
+_syscall2(int, vm86, int, func, struct vm86plus_struct *, v86)
+
+#define COM_BASE_ADDR    0x10100
+
+void usage(void)
+{
+    printf("runcom version 0.1 (c) 2003 Fabrice Bellard\n"
+           "usage: runcom file.com\n"
+           "VM86 Run simple .com DOS executables (linux vm86 test mode)\n");
+    exit(1);
+}
+
+static inline void set_bit(uint8_t *a, unsigned int bit)
+{
+    a[bit / 8] |= (1 << (bit % 8));
+}
+
+static inline uint8_t *seg_to_linear(unsigned int seg, unsigned int reg)
+{
+    return (uint8_t *)((seg << 4) + (reg & 0xffff));
+}
+
+static inline void pushw(struct vm86_regs *r, int val)
+{
+    r->esp = (r->esp & ~0xffff) | ((r->esp - 2) & 0xffff);
+    *(uint16_t *)seg_to_linear(r->ss, r->esp) = val;
+}
+
+void dump_regs(struct vm86_regs *r)
+{
+    fprintf(stderr, 
+            "EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx\n"
+            "ESI=%08lx EDI=%08lx EBP=%08lx ESP=%08lx\n"
+            "EIP=%08lx EFL=%08lx\n"
+            "CS=%04x DS=%04x ES=%04x SS=%04x FS=%04x GS=%04x\n",
+            r->eax, r->ebx, r->ecx, r->edx, r->esi, r->edi, r->ebp, r->esp,
+            r->eip, r->eflags,
+            r->cs, r->ds, r->es, r->ss, r->fs, r->gs);
+}
+
+#ifdef SIGTEST
+void alarm_handler(int sig)
+{
+    fprintf(stderr, "alarm signal=%d\n", sig);
+    alarm(1);
+}
+#endif
+
+int main(int argc, char **argv)
+{
+    uint8_t *vm86_mem;
+    const char *filename;
+    int fd, ret, seg;
+    struct vm86plus_struct ctx;
+    struct vm86_regs *r;
+
+    if (argc != 2)
+        usage();
+    filename = argv[1];
+    
+    vm86_mem = mmap((void *)0x00000000, 0x110000, 
+                    PROT_WRITE | PROT_READ | PROT_EXEC, 
+                    MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0);
+    if (vm86_mem == MAP_FAILED) {
+        perror("mmap");
+        exit(1);
+    }
+#ifdef SIGTEST
+    {
+        struct sigaction act;
+
+        act.sa_handler = alarm_handler;
+        sigemptyset(&act.sa_mask);
+        act.sa_flags = 0;
+        sigaction(SIGALRM, &act, NULL);
+        alarm(1);
+    }
+#endif
+
+    /* load the MSDOS .com executable */
+    fd = open(filename, O_RDONLY);
+    if (fd < 0) {
+        perror(filename);
+        exit(1);
+    }
+    ret = read(fd, vm86_mem + COM_BASE_ADDR, 65536 - 256);
+    if (ret < 0) {
+        perror("read");
+        exit(1);
+    }
+    close(fd);
+
+    memset(&ctx, 0, sizeof(ctx));
+    /* init basic registers */
+    r = &ctx.regs;
+    r->eip = 0x100;
+    r->esp = 0xfffe;
+    seg = (COM_BASE_ADDR - 0x100) >> 4;
+    r->cs = seg;
+    r->ss = seg;
+    r->ds = seg;
+    r->es = seg;
+    r->fs = seg;
+    r->gs = seg;
+    r->eflags = VIF_MASK;
+
+    /* put return code */
+    set_bit((uint8_t *)&ctx.int_revectored, 0x21);
+    *seg_to_linear(r->cs, 0) = 0xb4; /* mov ah, $0 */
+    *seg_to_linear(r->cs, 1) = 0x00;
+    *seg_to_linear(r->cs, 2) = 0xcd; /* int $0x21 */
+    *seg_to_linear(r->cs, 3) = 0x21;
+    pushw(&ctx.regs, 0x0000);
+
+    /* the value of these registers seem to be assumed by pi_10.com */
+    r->esi = 0x100;
+    r->ecx = 0xff;
+    r->ebp = 0x0900;
+    r->edi = 0xfffe;
+
+    for(;;) {
+        ret = vm86(VM86_ENTER, &ctx);
+        switch(VM86_TYPE(ret)) {
+        case VM86_INTx:
+            {
+                int int_num, ah;
+                
+                int_num = VM86_ARG(ret);
+                if (int_num != 0x21)
+                    goto unknown_int;
+                ah = (r->eax >> 8) & 0xff;
+                switch(ah) {
+                case 0x00: /* exit */
+                    exit(0);
+                case 0x02: /* write char */
+                    {
+                        uint8_t c = r->edx;
+                        write(1, &c, 1);
+                    }
+                    break;
+                case 0x09: /* write string */
+                    {
+                        uint8_t c;
+                        for(;;) {
+                            c = *seg_to_linear(r->ds, r->edx);
+                            if (c == '$')
+                                break;
+                            write(1, &c, 1);
+                        }
+                        r->eax = (r->eax & ~0xff) | '$';
+                    }
+                    break;
+                default:
+                unknown_int:
+                    fprintf(stderr, "unsupported int 0x%02x\n", int_num);
+                    dump_regs(&ctx.regs);
+                    //                    exit(1);
+                }
+            }
+            break;
+        case VM86_SIGNAL:
+            /* a signal came, we just ignore that */
+            break;
+        case VM86_STI:
+            break;
+        default:
+            fprintf(stderr, "unhandled vm86 return code (0x%x)\n", ret);
+            dump_regs(&ctx.regs);
+            exit(1);
+        }
+    }
+}
diff --git a/tools/ioemu/tests/sha1.c b/tools/ioemu/tests/sha1.c
new file mode 100644 (file)
index 0000000..31b0019
--- /dev/null
@@ -0,0 +1,242 @@
+
+/* from valgrind tests */
+
+/* ================ sha1.c ================ */
+/*
+SHA-1 in C
+By Steve Reid <steve@edmweb.com>
+100% Public Domain
+
+Test Vectors (from FIPS PUB 180-1)
+"abc"
+  A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
+"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+  84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
+A million repetitions of "a"
+  34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
+*/
+
+/* #define LITTLE_ENDIAN * This should be #define'd already, if true. */
+/* #define SHA1HANDSOFF * Copies data before messing with it. */
+
+#define SHA1HANDSOFF
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h> /* for u_int*_t */
+
+/* ================ sha1.h ================ */
+/*
+SHA-1 in C
+By Steve Reid <steve@edmweb.com>
+100% Public Domain
+*/
+
+typedef struct {
+    u_int32_t state[5];
+    u_int32_t count[2];
+    unsigned char buffer[64];
+} SHA1_CTX;
+
+void SHA1Transform(u_int32_t state[5], const unsigned char buffer[64]);
+void SHA1Init(SHA1_CTX* context);
+void SHA1Update(SHA1_CTX* context, const unsigned char* data, u_int32_t len);
+void SHA1Final(unsigned char digest[20], SHA1_CTX* context);
+/* ================ end of sha1.h ================ */
+#include <endian.h>
+
+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
+
+/* blk0() and blk() perform the initial expand. */
+/* I got the idea of expanding during the round function from SSLeay */
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
+    |(rol(block->l[i],8)&0x00FF00FF))
+#elif BYTE_ORDER == BIG_ENDIAN
+#define blk0(i) block->l[i]
+#else
+#error "Endianness not defined!"
+#endif
+#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
+    ^block->l[(i+2)&15]^block->l[i&15],1))
+
+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
+#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
+#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
+#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
+
+
+/* Hash a single 512-bit block. This is the core of the algorithm. */
+
+void SHA1Transform(u_int32_t state[5], const unsigned char buffer[64])
+{
+u_int32_t a, b, c, d, e;
+typedef union {
+    unsigned char c[64];
+    u_int32_t l[16];
+} CHAR64LONG16;
+#ifdef SHA1HANDSOFF
+CHAR64LONG16 block[1];  /* use array to appear as a pointer */
+    memcpy(block, buffer, 64);
+#else
+    /* The following had better never be used because it causes the
+     * pointer-to-const buffer to be cast into a pointer to non-const.
+     * And the result is written through.  I threw a "const" in, hoping
+     * this will cause a diagnostic.
+     */
+CHAR64LONG16* block = (const CHAR64LONG16*)buffer;
+#endif
+    /* Copy context->state[] to working vars */
+    a = state[0];
+    b = state[1];
+    c = state[2];
+    d = state[3];
+    e = state[4];
+    /* 4 rounds of 20 operations each. Loop unrolled. */
+    R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
+    R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
+    R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
+    R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
+    R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
+    R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
+    R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
+    R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
+    R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
+    R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
+    R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
+    R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
+    R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
+    R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
+    R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
+    R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
+    R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
+    R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
+    R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
+    R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
+    /* Add the working vars back into context.state[] */
+    state[0] += a;
+    state[1] += b;
+    state[2] += c;
+    state[3] += d;
+    state[4] += e;
+    /* Wipe variables */
+    a = b = c = d = e = 0;
+#ifdef SHA1HANDSOFF
+    memset(block, '\0', sizeof(block));
+#endif
+}
+
+
+/* SHA1Init - Initialize new context */
+
+void SHA1Init(SHA1_CTX* context)
+{
+    /* SHA1 initialization constants */
+    context->state[0] = 0x67452301;
+    context->state[1] = 0xEFCDAB89;
+    context->state[2] = 0x98BADCFE;
+    context->state[3] = 0x10325476;
+    context->state[4] = 0xC3D2E1F0;
+    context->count[0] = context->count[1] = 0;
+}
+
+
+/* Run your data through this. */
+
+void SHA1Update(SHA1_CTX* context, const unsigned char* data, u_int32_t len)
+{
+u_int32_t i;
+u_int32_t j;
+
+    j = context->count[0];
+    if ((context->count[0] += len << 3) < j)
+       context->count[1]++;
+    context->count[1] += (len>>29);
+    j = (j >> 3) & 63;
+    if ((j + len) > 63) {
+        memcpy(&context->buffer[j], data, (i = 64-j));
+        SHA1Transform(context->state, context->buffer);
+        for ( ; i + 63 < len; i += 64) {
+            SHA1Transform(context->state, &data[i]);
+        }
+        j = 0;
+    }
+    else i = 0;
+    memcpy(&context->buffer[j], &data[i], len - i);
+}
+
+
+/* Add padding and return the message digest. */
+
+void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
+{
+unsigned i;
+unsigned char finalcount[8];
+unsigned char c;
+
+#if 0  /* untested "improvement" by DHR */
+    /* Convert context->count to a sequence of bytes
+     * in finalcount.  Second element first, but
+     * big-endian order within element.
+     * But we do it all backwards.
+     */
+    unsigned char *fcp = &finalcount[8];
+
+    for (i = 0; i < 2; i++)
+    {
+       u_int32_t t = context->count[i];
+       int j;
+
+       for (j = 0; j < 4; t >>= 8, j++)
+           *--fcp = (unsigned char) t
+    }
+#else
+    for (i = 0; i < 8; i++) {
+        finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
+         >> ((3-(i & 3)) * 8) ) & 255);  /* Endian independent */
+    }
+#endif
+    c = 0200;
+    SHA1Update(context, &c, 1);
+    while ((context->count[0] & 504) != 448) {
+       c = 0000;
+        SHA1Update(context, &c, 1);
+    }
+    SHA1Update(context, finalcount, 8);  /* Should cause a SHA1Transform() */
+    for (i = 0; i < 20; i++) {
+        digest[i] = (unsigned char)
+         ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
+    }
+    /* Wipe variables */
+    memset(context, '\0', sizeof(*context));
+    memset(&finalcount, '\0', sizeof(finalcount));
+}
+/* ================ end of sha1.c ================ */
+
+#define BUFSIZE 4096
+
+int
+main(int argc, char **argv)
+{
+    SHA1_CTX ctx;
+    unsigned char hash[20], buf[BUFSIZE];
+    int i;
+
+    for(i=0;i<BUFSIZE;i++)
+        buf[i] = i;
+
+    SHA1Init(&ctx);
+    for(i=0;i<1000;i++)
+        SHA1Update(&ctx, buf, BUFSIZE);
+    SHA1Final(hash, &ctx);
+
+    printf("SHA1=");
+    for(i=0;i<20;i++)
+        printf("%02x", hash[i]);
+    printf("\n");
+    return 0;
+}
+
+
diff --git a/tools/ioemu/tests/test-i386-code16.S b/tools/ioemu/tests/test-i386-code16.S
new file mode 100644 (file)
index 0000000..78ecc1f
--- /dev/null
@@ -0,0 +1,97 @@
+        .code16
+        .globl code16_start
+        .globl code16_end
+
+CS_SEG = 0xf
+
+code16_start:
+
+        .globl code16_func1
+        
+        /* basic test */
+code16_func1 = . - code16_start
+        mov $1, %eax
+        data32 lret
+
+/* test push/pop in 16 bit mode */
+        .globl code16_func2
+code16_func2 = . - code16_start
+        xor %eax, %eax
+        mov $0x12345678, %ebx
+        movl %esp, %ecx
+        push %bx
+        subl %esp, %ecx
+        pop %ax
+        data32 lret
+
+/* test various jmp opcodes */        
+        .globl code16_func3
+code16_func3 = . - code16_start
+        jmp 1f
+        nop
+1:
+        mov $4, %eax
+        mov $0x12345678, %ebx
+        xor %bx, %bx
+        jz 2f
+        add $2, %ax
+2:
+        
+        call myfunc
+        
+        lcall $CS_SEG, $(myfunc2 - code16_start)
+
+        ljmp $CS_SEG, $(myjmp1 - code16_start)
+myjmp1_next:
+
+        cs lcall myfunc2_addr - code16_start
+
+        cs ljmp myjmp2_addr - code16_start
+myjmp2_next:
+
+        data32 lret
+        
+myfunc2_addr:
+        .short myfunc2 - code16_start
+        .short CS_SEG
+
+myjmp2_addr:
+        .short myjmp2 - code16_start
+        .short CS_SEG
+
+myjmp1:
+        add $8, %ax
+        jmp myjmp1_next
+
+myjmp2:
+        add $16, %ax
+        jmp myjmp2_next
+
+myfunc:
+        add $1, %ax
+        ret
+
+myfunc2:
+        add $4, %ax
+        lret
+
+
+code16_end:
+
+
+/* other 32 bits tests */
+        .code32
+
+        .globl func_lret32
+func_lret32:
+        movl $0x87654321, %eax
+        lret
+
+        .globl func_iret32
+func_iret32:
+        movl $0xabcd4321, %eax
+        iret
+
+                
+
+        
\ No newline at end of file
diff --git a/tools/ioemu/tests/test-i386-muldiv.h b/tools/ioemu/tests/test-i386-muldiv.h
new file mode 100644 (file)
index 0000000..5dba315
--- /dev/null
@@ -0,0 +1,56 @@
+
+void glue(glue(test_, OP), b)(int op0, int op1) 
+{
+    int res, s1, s0, flags;
+    s0 = op0;
+    s1 = op1;
+    res = s0;
+    flags = 0;
+    asm ("push %4\n\t"
+         "popf\n\t"
+         stringify(OP)"b %b2\n\t" 
+         "pushf\n\t"
+         "popl %1\n\t"
+         : "=a" (res), "=g" (flags)
+         : "q" (s1), "0" (res), "1" (flags));
+    printf("%-10s A=%08x B=%08x R=%08x CC=%04x\n",
+           stringify(OP) "b", s0, s1, res, flags & CC_MASK);
+}
+
+void glue(glue(test_, OP), w)(int op0h, int op0, int op1) 
+{
+    int res, s1, flags, resh;
+    s1 = op1;
+    resh = op0h;
+    res = op0;
+    flags = 0;
+    asm ("push %5\n\t"
+         "popf\n\t"
+         stringify(OP) "w %w3\n\t" 
+         "pushf\n\t"
+         "popl %1\n\t"
+         : "=a" (res), "=g" (flags), "=d" (resh)
+         : "q" (s1), "0" (res), "1" (flags), "2" (resh));
+    printf("%-10s AH=%08x AL=%08x B=%08x RH=%08x RL=%08x CC=%04x\n",
+           stringify(OP) "w", op0h, op0, s1, resh, res, flags & CC_MASK);
+}
+
+void glue(glue(test_, OP), l)(int op0h, int op0, int op1) 
+{
+    int res, s1, flags, resh;
+    s1 = op1;
+    resh = op0h;
+    res = op0;
+    flags = 0;
+    asm ("push %5\n\t"
+         "popf\n\t"
+         stringify(OP) "l %3\n\t" 
+         "pushf\n\t"
+         "popl %1\n\t"
+         : "=a" (res), "=g" (flags), "=d" (resh)
+         : "q" (s1), "0" (res), "1" (flags), "2" (resh));
+    printf("%-10s AH=%08x AL=%08x B=%08x RH=%08x RL=%08x CC=%04x\n",
+           stringify(OP) "l", op0h, op0, s1, resh, res, flags & CC_MASK);
+}
+
+#undef OP
diff --git a/tools/ioemu/tests/test-i386-shift.h b/tools/ioemu/tests/test-i386-shift.h
new file mode 100644 (file)
index 0000000..c3d8793
--- /dev/null
@@ -0,0 +1,143 @@
+
+#define exec_op glue(exec_, OP)
+#define exec_opl glue(glue(exec_, OP), l)
+#define exec_opw glue(glue(exec_, OP), w)
+#define exec_opb glue(glue(exec_, OP), b)
+
+#ifndef OP_SHIFTD
+
+#ifdef OP_NOBYTE
+#define EXECSHIFT(size, res, s1, s2, flags) \
+    asm ("push %4\n\t"\
+         "popf\n\t"\
+         stringify(OP) size " %" size "2, %" size "0\n\t" \
+         "pushf\n\t"\
+         "popl %1\n\t"\
+         : "=g" (res), "=g" (flags)\
+         : "r" (s1), "0" (res), "1" (flags));
+#else
+#define EXECSHIFT(size, res, s1, s2, flags) \
+    asm ("push %4\n\t"\
+         "popf\n\t"\
+         stringify(OP) size " %%cl, %" size "0\n\t" \
+         "pushf\n\t"\
+         "popl %1\n\t"\
+         : "=q" (res), "=g" (flags)\
+         : "c" (s1), "0" (res), "1" (flags));
+#endif
+
+void exec_opl(int s2, int s0, int s1, int iflags)
+{
+    int res, flags;
+    res = s0;
+    flags = iflags;
+    EXECSHIFT("", res, s1, s2, flags);
+    /* overflow is undefined if count != 1 */
+    if (s1 != 1)
+      flags &= ~CC_O;
+    printf("%-10s A=%08x B=%08x R=%08x CCIN=%04x CC=%04x\n",
+           stringify(OP) "l", s0, s1, res, iflags, flags & CC_MASK);
+}
+
+void exec_opw(int s2, int s0, int s1, int iflags)
+{
+    int res, flags;
+    res = s0;
+    flags = iflags;
+    EXECSHIFT("w", res, s1, s2, flags);
+    /* overflow is undefined if count != 1 */
+    if (s1 != 1)
+      flags &= ~CC_O;
+    printf("%-10s A=%08x B=%08x R=%08x CCIN=%04x CC=%04x\n",
+           stringify(OP) "w", s0, s1, res, iflags, flags & CC_MASK);
+}
+
+#else
+#define EXECSHIFT(size, res, s1, s2, flags) \
+    asm ("push %4\n\t"\
+         "popf\n\t"\
+         stringify(OP) size " %%cl, %" size "5, %" size "0\n\t" \
+         "pushf\n\t"\
+         "popl %1\n\t"\
+         : "=g" (res), "=g" (flags)\
+         : "c" (s1), "0" (res), "1" (flags), "r" (s2));
+
+void exec_opl(int s2, int s0, int s1, int iflags)
+{
+    int res, flags;
+    res = s0;
+    flags = iflags;
+    EXECSHIFT("", res, s1, s2, flags);
+    /* overflow is undefined if count != 1 */
+    if (s1 != 1)
+      flags &= ~CC_O;
+    printf("%-10s A=%08x B=%08x C=%08x R=%08x CCIN=%04x CC=%04x\n",
+           stringify(OP) "l", s0, s2, s1, res, iflags, flags & CC_MASK);
+}
+
+void exec_opw(int s2, int s0, int s1, int iflags)
+{
+    int res, flags;
+    res = s0;
+    flags = iflags;
+    EXECSHIFT("w", res, s1, s2, flags);
+    /* overflow is undefined if count != 1 */
+    if (s1 != 1)
+      flags &= ~CC_O;
+    printf("%-10s A=%08x B=%08x C=%08x R=%08x CCIN=%04x CC=%04x\n",
+           stringify(OP) "w", s0, s2, s1, res, iflags, flags & CC_MASK);
+}
+
+#endif
+
+#ifndef OP_NOBYTE
+void exec_opb(int s0, int s1, int iflags)
+{
+    int res, flags;
+    res = s0;
+    flags = iflags;
+    EXECSHIFT("b", res, s1, 0, flags);
+    /* overflow is undefined if count != 1 */
+    if (s1 != 1)
+      flags &= ~CC_O;
+    printf("%-10s A=%08x B=%08x R=%08x CCIN=%04x CC=%04x\n",
+           stringify(OP) "b", s0, s1, res, iflags, flags & CC_MASK);
+}
+#endif
+
+void exec_op(int s2, int s0, int s1)
+{
+    exec_opl(s2, s0, s1, 0);
+#ifdef OP_SHIFTD
+    if (s1 <= 15)
+        exec_opw(s2, s0, s1, 0);
+#else
+    exec_opw(s2, s0, s1, 0);
+#endif
+#ifndef OP_NOBYTE
+    exec_opb(s0, s1, 0);
+#endif
+#ifdef OP_CC
+    exec_opl(s2, s0, s1, CC_C);
+    exec_opw(s2, s0, s1, CC_C);
+    exec_opb(s0, s1, CC_C);
+#endif
+}
+
+void glue(test_, OP)(void)
+{
+    int i;
+    for(i = 0; i < 32; i++)
+        exec_op(0x21ad3d34, 0x12345678, i);
+    for(i = 0; i < 32; i++)
+        exec_op(0x813f3421, 0x82345678, i);
+}
+
+void *glue(_test_, OP) __init_call = glue(test_, OP);
+
+#undef OP
+#undef OP_CC
+#undef OP_SHIFTD
+#undef OP_NOBYTE
+#undef EXECSHIFT
+
diff --git a/tools/ioemu/tests/test-i386-vm86.S b/tools/ioemu/tests/test-i386-vm86.S
new file mode 100644 (file)
index 0000000..a972f1b
--- /dev/null
@@ -0,0 +1,104 @@
+        .code16
+        .globl vm86_code_start
+        .globl vm86_code_end
+
+#define GET_OFFSET(x) ((x) - vm86_code_start + 0x100)
+
+vm86_code_start:
+        movw $GET_OFFSET(hello_world), %dx
+        movb $0x09, %ah
+        int $0x21
+
+        /* prepare int 0x90 vector */
+        xorw %ax, %ax
+        movw %ax, %es
+        es movw $GET_OFFSET(int90_test), 0x90 * 4
+        es movw %cs, 0x90 * 4 + 2
+        
+        /* launch int 0x90 */
+
+        int $0x90
+
+        /* test IF support */
+        movw $GET_OFFSET(IF_msg), %dx
+        movb $0x09, %ah
+        int $0x21
+
+        pushf 
+        popw %dx
+        movb $0xff, %ah
+        int $0x21
+
+        cli
+        pushf 
+        popw %dx
+        movb $0xff, %ah
+        int $0x21
+
+        sti        
+        pushfl 
+        popl %edx
+        movb $0xff, %ah
+        int $0x21
+        
+#if 0
+        movw $GET_OFFSET(IF_msg1), %dx
+        movb $0x09, %ah
+        int $0x21
+
+        pushf
+        movw %sp, %bx
+        andw $~0x200, (%bx)
+        popf
+#else
+        cli
+#endif
+
+        pushf 
+        popw %dx
+        movb $0xff, %ah
+        int $0x21
+        
+        pushfl
+        movw %sp, %bx
+        orw $0x200, (%bx)
+        popfl
+
+        pushfl
+        popl %edx
+        movb $0xff, %ah
+        int $0x21
+
+        movb $0x00, %ah
+        int $0x21
+
+int90_test:
+        pushf 
+        pop %dx
+        movb $0xff, %ah
+        int $0x21
+
+        movw %sp, %bx
+        movw 4(%bx), %dx
+        movb $0xff, %ah
+        int $0x21
+        
+        movw $GET_OFFSET(int90_msg), %dx
+        movb $0x09, %ah
+        int $0x21
+        iret
+                    
+int90_msg:
+        .string "INT90 started\n$"
+hello_world:
+        .string "Hello VM86 world\n$"
+
+IF_msg:
+        .string "VM86 IF test\n$"
+
+IF_msg1:
+        .string "If you see a diff here, your Linux kernel is buggy, please update to 2.4.20 kernel\n$"
+
+vm86_code_end:
+        
\ No newline at end of file
diff --git a/tools/ioemu/tests/test-i386.c b/tools/ioemu/tests/test-i386.c
new file mode 100644 (file)
index 0000000..a4bfa34
--- /dev/null
@@ -0,0 +1,1706 @@
+/*
+ *  x86 CPU test
+ * 
+ *  Copyright (c) 2003 Fabrice Bellard
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include <math.h>
+#include <signal.h>
+#include <setjmp.h>
+#include <errno.h>
+#include <sys/ucontext.h>
+#include <sys/mman.h>
+#include <asm/vm86.h>
+
+#define TEST_CMOV  0
+#define TEST_FCOMI 0
+//#define LINUX_VM86_IOPL_FIX
+//#define TEST_P4_FLAGS
+
+#define xglue(x, y) x ## y
+#define glue(x, y) xglue(x, y)
+#define stringify(s)   tostring(s)
+#define tostring(s)    #s
+
+#define CC_C           0x0001
+#define CC_P   0x0004
+#define CC_A   0x0010
+#define CC_Z   0x0040
+#define CC_S    0x0080
+#define CC_O    0x0800
+
+#define __init_call    __attribute__ ((unused,__section__ (".initcall.init")))
+
+static void *call_start __init_call = NULL;
+
+#define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A)
+
+#define OP add
+#include "test-i386.h"
+
+#define OP sub
+#include "test-i386.h"
+
+#define OP xor
+#include "test-i386.h"
+
+#define OP and
+#include "test-i386.h"
+
+#define OP or
+#include "test-i386.h"
+
+#define OP cmp
+#include "test-i386.h"
+
+#define OP adc
+#define OP_CC
+#include "test-i386.h"
+
+#define OP sbb
+#define OP_CC
+#include "test-i386.h"
+
+#define OP inc
+#define OP_CC
+#define OP1
+#include "test-i386.h"
+
+#define OP dec
+#define OP_CC
+#define OP1
+#include "test-i386.h"
+
+#define OP neg
+#define OP_CC
+#define OP1
+#include "test-i386.h"
+
+#define OP not
+#define OP_CC
+#define OP1
+#include "test-i386.h"
+
+#undef CC_MASK
+#define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O)
+
+#define OP shl
+#include "test-i386-shift.h"
+
+#define OP shr
+#include "test-i386-shift.h"
+
+#define OP sar
+#include "test-i386-shift.h"
+
+#define OP rol
+#include "test-i386-shift.h"
+
+#define OP ror
+#include "test-i386-shift.h"
+
+#define OP rcr
+#define OP_CC
+#include "test-i386-shift.h"
+
+#define OP rcl
+#define OP_CC
+#include "test-i386-shift.h"
+
+#define OP shld
+#define OP_SHIFTD
+#define OP_NOBYTE
+#include "test-i386-shift.h"
+
+#define OP shrd
+#define OP_SHIFTD
+#define OP_NOBYTE
+#include "test-i386-shift.h"
+
+/* XXX: should be more precise ? */
+#undef CC_MASK
+#define CC_MASK (CC_C)
+
+#define OP bt
+#define OP_NOBYTE
+#include "test-i386-shift.h"
+
+#define OP bts
+#define OP_NOBYTE
+#include "test-i386-shift.h"
+
+#define OP btr
+#define OP_NOBYTE
+#include "test-i386-shift.h"
+
+#define OP btc
+#define OP_NOBYTE
+#include "test-i386-shift.h"
+
+/* lea test (modrm support) */
+#define TEST_LEA(STR)\
+{\
+    asm("leal " STR ", %0"\
+        : "=r" (res)\
+        : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));\
+    printf("lea %s = %08x\n", STR, res);\
+}
+
+#define TEST_LEA16(STR)\
+{\
+    asm(".code16 ; .byte 0x67 ; leal " STR ", %0 ; .code32"\
+        : "=wq" (res)\
+        : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));\
+    printf("lea %s = %08x\n", STR, res);\
+}
+
+
+void test_lea(void)
+{
+    int eax, ebx, ecx, edx, esi, edi, res;
+    eax = 0x0001;
+    ebx = 0x0002;
+    ecx = 0x0004;
+    edx = 0x0008;
+    esi = 0x0010;
+    edi = 0x0020;
+
+    TEST_LEA("0x4000");
+
+    TEST_LEA("(%%eax)");
+    TEST_LEA("(%%ebx)");
+    TEST_LEA("(%%ecx)");
+    TEST_LEA("(%%edx)");
+    TEST_LEA("(%%esi)");
+    TEST_LEA("(%%edi)");
+
+    TEST_LEA("0x40(%%eax)");
+    TEST_LEA("0x40(%%ebx)");
+    TEST_LEA("0x40(%%ecx)");
+    TEST_LEA("0x40(%%edx)");
+    TEST_LEA("0x40(%%esi)");
+    TEST_LEA("0x40(%%edi)");
+
+    TEST_LEA("0x4000(%%eax)");
+    TEST_LEA("0x4000(%%ebx)");
+    TEST_LEA("0x4000(%%ecx)");
+    TEST_LEA("0x4000(%%edx)");
+    TEST_LEA("0x4000(%%esi)");
+    TEST_LEA("0x4000(%%edi)");
+
+    TEST_LEA("(%%eax, %%ecx)");
+    TEST_LEA("(%%ebx, %%edx)");
+    TEST_LEA("(%%ecx, %%ecx)");
+    TEST_LEA("(%%edx, %%ecx)");
+    TEST_LEA("(%%esi, %%ecx)");
+    TEST_LEA("(%%edi, %%ecx)");
+
+    TEST_LEA("0x40(%%eax, %%ecx)");
+    TEST_LEA("0x4000(%%ebx, %%edx)");
+
+    TEST_LEA("(%%ecx, %%ecx, 2)");
+    TEST_LEA("(%%edx, %%ecx, 4)");
+    TEST_LEA("(%%esi, %%ecx, 8)");
+
+    TEST_LEA("(,%%eax, 2)");
+    TEST_LEA("(,%%ebx, 4)");
+    TEST_LEA("(,%%ecx, 8)");
+
+    TEST_LEA("0x40(,%%eax, 2)");
+    TEST_LEA("0x40(,%%ebx, 4)");
+    TEST_LEA("0x40(,%%ecx, 8)");
+
+
+    TEST_LEA("-10(%%ecx, %%ecx, 2)");
+    TEST_LEA("-10(%%edx, %%ecx, 4)");
+    TEST_LEA("-10(%%esi, %%ecx, 8)");
+
+    TEST_LEA("0x4000(%%ecx, %%ecx, 2)");
+    TEST_LEA("0x4000(%%edx, %%ecx, 4)");
+    TEST_LEA("0x4000(%%esi, %%ecx, 8)");
+
+    /* limited 16 bit addressing test */
+    TEST_LEA16("0x4000");
+    TEST_LEA16("(%%bx)");
+    TEST_LEA16("(%%si)");
+    TEST_LEA16("(%%di)");
+    TEST_LEA16("0x40(%%bx)");
+    TEST_LEA16("0x40(%%si)");
+    TEST_LEA16("0x40(%%di)");
+    TEST_LEA16("0x4000(%%bx)");
+    TEST_LEA16("0x4000(%%si)");
+    TEST_LEA16("(%%bx,%%si)");
+    TEST_LEA16("(%%bx,%%di)");
+    TEST_LEA16("0x40(%%bx,%%si)");
+    TEST_LEA16("0x40(%%bx,%%di)");
+    TEST_LEA16("0x4000(%%bx,%%si)");
+    TEST_LEA16("0x4000(%%bx,%%di)");
+}
+
+#define TEST_JCC(JCC, v1, v2)\
+{\
+    int res;\
+    asm("movl $1, %0\n\t"\
+        "cmpl %2, %1\n\t"\
+        "j" JCC " 1f\n\t"\
+        "movl $0, %0\n\t"\
+        "1:\n\t"\
+        : "=r" (res)\
+        : "r" (v1), "r" (v2));\
+    printf("%-10s %d\n", "j" JCC, res);\
+\
+    asm("movl $0, %0\n\t"\
+        "cmpl %2, %1\n\t"\
+        "set" JCC " %b0\n\t"\
+        : "=r" (res)\
+        : "r" (v1), "r" (v2));\
+    printf("%-10s %d\n", "set" JCC, res);\
+ if (TEST_CMOV) {\
+    asm("movl $0x12345678, %0\n\t"\
+        "cmpl %2, %1\n\t"\
+        "cmov" JCC "l %3, %0\n\t"\
+        : "=r" (res)\
+        : "r" (v1), "r" (v2), "m" (1));\
+        printf("%-10s R=0x%08x\n", "cmov" JCC "l", res);\
+    asm("movl $0x12345678, %0\n\t"\
+        "cmpl %2, %1\n\t"\
+        "cmov" JCC "w %w3, %w0\n\t"\
+        : "=r" (res)\
+        : "r" (v1), "r" (v2), "r" (1));\
+        printf("%-10s R=0x%08x\n", "cmov" JCC "w", res);\
+ } \
+}
+
+/* various jump tests */
+void test_jcc(void)
+{
+    TEST_JCC("ne", 1, 1);
+    TEST_JCC("ne", 1, 0);
+
+    TEST_JCC("e", 1, 1);
+    TEST_JCC("e", 1, 0);
+
+    TEST_JCC("l", 1, 1);
+    TEST_JCC("l", 1, 0);
+    TEST_JCC("l", 1, -1);
+
+    TEST_JCC("le", 1, 1);
+    TEST_JCC("le", 1, 0);
+    TEST_JCC("le", 1, -1);
+
+    TEST_JCC("ge", 1, 1);
+    TEST_JCC("ge", 1, 0);
+    TEST_JCC("ge", -1, 1);
+
+    TEST_JCC("g", 1, 1);
+    TEST_JCC("g", 1, 0);
+    TEST_JCC("g", 1, -1);
+
+    TEST_JCC("b", 1, 1);
+    TEST_JCC("b", 1, 0);
+    TEST_JCC("b", 1, -1);
+
+    TEST_JCC("be", 1, 1);
+    TEST_JCC("be", 1, 0);
+    TEST_JCC("be", 1, -1);
+
+    TEST_JCC("ae", 1, 1);
+    TEST_JCC("ae", 1, 0);
+    TEST_JCC("ae", 1, -1);
+
+    TEST_JCC("a", 1, 1);
+    TEST_JCC("a", 1, 0);
+    TEST_JCC("a", 1, -1);
+
+
+    TEST_JCC("p", 1, 1);
+    TEST_JCC("p", 1, 0);
+
+    TEST_JCC("np", 1, 1);
+    TEST_JCC("np", 1, 0);
+
+    TEST_JCC("o", 0x7fffffff, 0);
+    TEST_JCC("o", 0x7fffffff, -1);
+
+    TEST_JCC("no", 0x7fffffff, 0);
+    TEST_JCC("no", 0x7fffffff, -1);
+
+    TEST_JCC("s", 0, 1);
+    TEST_JCC("s", 0, -1);
+    TEST_JCC("s", 0, 0);
+
+    TEST_JCC("ns", 0, 1);
+    TEST_JCC("ns", 0, -1);
+    TEST_JCC("ns", 0, 0);
+}
+
+#undef CC_MASK
+#ifdef TEST_P4_FLAGS
+#define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A)
+#else
+#define CC_MASK (CC_O | CC_C)
+#endif
+
+#define OP mul
+#include "test-i386-muldiv.h"
+
+#define OP imul
+#include "test-i386-muldiv.h"
+
+void test_imulw2(int op0, int op1) 
+{
+    int res, s1, s0, flags;
+    s0 = op0;
+    s1 = op1;
+    res = s0;
+    flags = 0;
+    asm ("push %4\n\t"
+         "popf\n\t"
+         "imulw %w2, %w0\n\t" 
+         "pushf\n\t"
+         "popl %1\n\t"
+         : "=q" (res), "=g" (flags)
+         : "q" (s1), "0" (res), "1" (flags));
+    printf("%-10s A=%08x B=%08x R=%08x CC=%04x\n",
+           "imulw", s0, s1, res, flags & CC_MASK);
+}
+
+void test_imull2(int op0, int op1) 
+{
+    int res, s1, s0, flags;
+    s0 = op0;
+    s1 = op1;
+    res = s0;
+    flags = 0;
+    asm ("push %4\n\t"
+         "popf\n\t"
+         "imull %2, %0\n\t" 
+         "pushf\n\t"
+         "popl %1\n\t"
+         : "=q" (res), "=g" (flags)
+         : "q" (s1), "0" (res), "1" (flags));
+    printf("%-10s A=%08x B=%08x R=%08x CC=%04x\n",
+           "imull", s0, s1, res, flags & CC_MASK);
+}
+
+#define TEST_IMUL_IM(size, size1, op0, op1)\
+{\
+    int res, flags;\
+    flags = 0;\
+    res = 0;\
+    asm ("push %3\n\t"\
+         "popf\n\t"\
+         "imul" size " $" #op0 ", %" size1 "2, %" size1 "0\n\t" \
+         "pushf\n\t"\
+         "popl %1\n\t"\
+         : "=r" (res), "=g" (flags)\
+         : "r" (op1), "1" (flags), "0" (res));\
+    printf("%-10s A=%08x B=%08x R=%08x CC=%04x\n",\
+           "imul" size, op0, op1, res, flags & CC_MASK);\
+}
+
+
+#undef CC_MASK
+#define CC_MASK (0)
+
+#define OP div
+#include "test-i386-muldiv.h"
+
+#define OP idiv
+#include "test-i386-muldiv.h"
+
+void test_mul(void)
+{
+    test_imulb(0x1234561d, 4);
+    test_imulb(3, -4);
+    test_imulb(0x80, 0x80);
+    test_imulb(0x10, 0x10);
+
+    test_imulw(0, 0x1234001d, 45);
+    test_imulw(0, 23, -45);
+    test_imulw(0, 0x8000, 0x8000);
+    test_imulw(0, 0x100, 0x100);
+
+    test_imull(0, 0x1234001d, 45);
+    test_imull(0, 23, -45);
+    test_imull(0, 0x80000000, 0x80000000);
+    test_imull(0, 0x10000, 0x10000);
+
+    test_mulb(0x1234561d, 4);
+    test_mulb(3, -4);
+    test_mulb(0x80, 0x80);
+    test_mulb(0x10, 0x10);
+
+    test_mulw(0, 0x1234001d, 45);
+    test_mulw(0, 23, -45);
+    test_mulw(0, 0x8000, 0x8000);
+    test_mulw(0, 0x100, 0x100);
+
+    test_mull(0, 0x1234001d, 45);
+    test_mull(0, 23, -45);
+    test_mull(0, 0x80000000, 0x80000000);
+    test_mull(0, 0x10000, 0x10000);
+
+    test_imulw2(0x1234001d, 45);
+    test_imulw2(23, -45);
+    test_imulw2(0x8000, 0x8000);
+    test_imulw2(0x100, 0x100);
+
+    test_imull2(0x1234001d, 45);
+    test_imull2(23, -45);
+    test_imull2(0x80000000, 0x80000000);
+    test_imull2(0x10000, 0x10000);
+
+    TEST_IMUL_IM("w", "w", 45, 0x1234);
+    TEST_IMUL_IM("w", "w", -45, 23);
+    TEST_IMUL_IM("w", "w", 0x8000, 0x80000000);
+    TEST_IMUL_IM("w", "w", 0x7fff, 0x1000);
+
+    TEST_IMUL_IM("l", "", 45, 0x1234);
+    TEST_IMUL_IM("l", "", -45, 23);
+    TEST_IMUL_IM("l", "", 0x8000, 0x80000000);
+    TEST_IMUL_IM("l", "", 0x7fff, 0x1000);
+
+    test_idivb(0x12341678, 0x127e);
+    test_idivb(0x43210123, -5);
+    test_idivb(0x12340004, -1);
+
+    test_idivw(0, 0x12345678, 12347);
+    test_idivw(0, -23223, -45);
+    test_idivw(0, 0x12348000, -1);
+    test_idivw(0x12343, 0x12345678, 0x81238567);
+
+    test_idivl(0, 0x12345678, 12347);
+    test_idivl(0, -233223, -45);
+    test_idivl(0, 0x80000000, -1);
+    test_idivl(0x12343, 0x12345678, 0x81234567);
+
+    test_divb(0x12341678, 0x127e);
+    test_divb(0x43210123, -5);
+    test_divb(0x12340004, -1);
+
+    test_divw(0, 0x12345678, 12347);
+    test_divw(0, -23223, -45);
+    test_divw(0, 0x12348000, -1);
+    test_divw(0x12343, 0x12345678, 0x81238567);
+
+    test_divl(0, 0x12345678, 12347);
+    test_divl(0, -233223, -45);
+    test_divl(0, 0x80000000, -1);
+    test_divl(0x12343, 0x12345678, 0x81234567);
+}
+
+#define TEST_BSX(op, size, op0)\
+{\
+    int res, val, resz;\
+    val = op0;\
+    asm("xorl %1, %1\n"\
+        "movl $0x12345678, %0\n"\
+        #op " %" size "2, %" size "0 ; setz %b1" \
+        : "=r" (res), "=q" (resz)\
+        : "g" (val));\
+    printf("%-10s A=%08x R=%08x %d\n", #op, val, res, resz);\
+}
+
+void test_bsx(void)
+{
+    TEST_BSX(bsrw, "w", 0);
+    TEST_BSX(bsrw, "w", 0x12340128);
+    TEST_BSX(bsrl, "", 0);
+    TEST_BSX(bsrl, "", 0x00340128);
+    TEST_BSX(bsfw, "w", 0);
+    TEST_BSX(bsfw, "w", 0x12340128);
+    TEST_BSX(bsfl, "", 0);
+    TEST_BSX(bsfl, "", 0x00340128);
+}
+
+/**********************************************/
+
+void test_fops(double a, double b)
+{
+    printf("a=%f b=%f a+b=%f\n", a, b, a + b);
+    printf("a=%f b=%f a-b=%f\n", a, b, a - b);
+    printf("a=%f b=%f a*b=%f\n", a, b, a * b);
+    printf("a=%f b=%f a/b=%f\n", a, b, a / b);
+    printf("a=%f b=%f fmod(a, b)=%f\n", a, b, fmod(a, b));
+    printf("a=%f sqrt(a)=%f\n", a, sqrt(a));
+    printf("a=%f sin(a)=%f\n", a, sin(a));
+    printf("a=%f cos(a)=%f\n", a, cos(a));
+    printf("a=%f tan(a)=%f\n", a, tan(a));
+    printf("a=%f log(a)=%f\n", a, log(a));
+    printf("a=%f exp(a)=%f\n", a, exp(a));
+    printf("a=%f b=%f atan2(a, b)=%f\n", a, b, atan2(a, b));
+    /* just to test some op combining */
+    printf("a=%f asin(sin(a))=%f\n", a, asin(sin(a)));
+    printf("a=%f acos(cos(a))=%f\n", a, acos(cos(a)));
+    printf("a=%f atan(tan(a))=%f\n", a, atan(tan(a)));
+
+}
+
+void test_fcmp(double a, double b)
+{
+    printf("(%f<%f)=%d\n",
+           a, b, a < b);
+    printf("(%f<=%f)=%d\n",
+           a, b, a <= b);
+    printf("(%f==%f)=%d\n",
+           a, b, a == b);
+    printf("(%f>%f)=%d\n",
+           a, b, a > b);
+    printf("(%f<=%f)=%d\n",
+           a, b, a >= b);
+    if (TEST_FCOMI) {
+        unsigned int eflags;
+        /* test f(u)comi instruction */
+        asm("fcomi %2, %1\n"
+            "pushf\n"
+            "pop %0\n"
+            : "=r" (eflags)
+            : "t" (a), "u" (b));
+        printf("fcomi(%f %f)=%08x\n", a, b, eflags & (CC_Z | CC_P | CC_C));
+    }
+}
+
+void test_fcvt(double a)
+{
+    float fa;
+    long double la;
+    int16_t fpuc;
+    int i;
+    int64_t lla;
+    int ia;
+    int16_t wa;
+    double ra;
+
+    fa = a;
+    la = a;
+    printf("(float)%f = %f\n", a, fa);
+    printf("(long double)%f = %Lf\n", a, la);
+    printf("a=%016Lx\n", *(long long *)&a);
+    printf("la=%016Lx %04x\n", *(long long *)&la, 
+           *(unsigned short *)((char *)(&la) + 8));
+
+    /* test all roundings */
+    asm volatile ("fstcw %0" : "=m" (fpuc));
+    for(i=0;i<4;i++) {
+        asm volatile ("fldcw %0" : : "m" ((fpuc & ~0x0c00) | (i << 10)));
+        asm volatile ("fist %0" : "=m" (wa) : "t" (a));
+        asm volatile ("fistl %0" : "=m" (ia) : "t" (a));
+        asm volatile ("fistpll %0" : "=m" (lla) : "t" (a) : "st");
+        asm volatile ("frndint ; fstl %0" : "=m" (ra) : "t" (a));
+        asm volatile ("fldcw %0" : : "m" (fpuc));
+        printf("(short)a = %d\n", wa);
+        printf("(int)a = %d\n", ia);
+        printf("(int64_t)a = %Ld\n", lla);
+        printf("rint(a) = %f\n", ra);
+    }
+}
+
+#define TEST(N) \
+    asm("fld" #N : "=t" (a)); \
+    printf("fld" #N "= %f\n", a);
+
+void test_fconst(void)
+{
+    double a;
+    TEST(1);
+    TEST(l2t);
+    TEST(l2e);
+    TEST(pi);
+    TEST(lg2);
+    TEST(ln2);
+    TEST(z);
+}
+
+void test_fbcd(double a)
+{
+    unsigned short bcd[5];
+    double b;
+
+    asm("fbstp %0" : "=m" (bcd[0]) : "t" (a) : "st");
+    asm("fbld %1" : "=t" (b) : "m" (bcd[0]));
+    printf("a=%f bcd=%04x%04x%04x%04x%04x b=%f\n", 
+           a, bcd[4], bcd[3], bcd[2], bcd[1], bcd[0], b);
+}
+
+#define TEST_ENV(env, save, restore)\
+{\
+    memset((env), 0xaa, sizeof(*(env)));\
+    for(i=0;i<5;i++)\
+        asm volatile ("fldl %0" : : "m" (dtab[i]));\
+    asm(save " %0\n" : : "m" (*(env)));\
+    asm(restore " %0\n": : "m" (*(env)));\
+    for(i=0;i<5;i++)\
+        asm volatile ("fstpl %0" : "=m" (rtab[i]));\
+    for(i=0;i<5;i++)\
+        printf("res[%d]=%f\n", i, rtab[i]);\
+    printf("fpuc=%04x fpus=%04x fptag=%04x\n",\
+           (env)->fpuc,\
+           (env)->fpus & 0xff00,\
+           (env)->fptag);\
+}
+
+void test_fenv(void)
+{
+    struct __attribute__((packed)) {
+        uint16_t fpuc;
+        uint16_t dummy1;
+        uint16_t fpus;
+        uint16_t dummy2;
+        uint16_t fptag;
+        uint16_t dummy3;
+        uint32_t ignored[4];
+        long double fpregs[8];
+    } float_env32;
+    struct __attribute__((packed)) {
+        uint16_t fpuc;
+        uint16_t fpus;
+        uint16_t fptag;
+        uint16_t ignored[4];
+        long double fpregs[8];
+    } float_env16;
+    double dtab[8];
+    double rtab[8];
+    int i;
+
+    for(i=0;i<8;i++)
+        dtab[i] = i + 1;
+
+    TEST_ENV(&float_env16, "data16 fnstenv", "data16 fldenv");
+    TEST_ENV(&float_env16, "data16 fnsave", "data16 frstor");
+    TEST_ENV(&float_env32, "fnstenv", "fldenv");
+    TEST_ENV(&float_env32, "fnsave", "frstor");
+
+    /* test for ffree */
+    for(i=0;i<5;i++)
+        asm volatile ("fldl %0" : : "m" (dtab[i]));
+    asm volatile("ffree %st(2)");
+    asm volatile ("fnstenv %0\n" : : "m" (float_env32));
+    asm volatile ("fninit");
+    printf("fptag=%04x\n", float_env32.fptag);
+}
+
+
+#define TEST_FCMOV(a, b, eflags, CC)\
+{\
+    double res;\
+    asm("push %3\n"\
+        "popf\n"\
+        "fcmov" CC " %2, %0\n"\
+        : "=t" (res)\
+        : "0" (a), "u" (b), "g" (eflags));\
+    printf("fcmov%s eflags=0x%04x-> %f\n", \
+           CC, eflags, res);\
+}
+
+void test_fcmov(void)
+{
+    double a, b;
+    int eflags, i;
+
+    a = 1.0;
+    b = 2.0;
+    for(i = 0; i < 4; i++) {
+        eflags = 0;
+        if (i & 1)
+            eflags |= CC_C;
+        if (i & 2)
+            eflags |= CC_Z;
+        TEST_FCMOV(a, b, eflags, "b");
+        TEST_FCMOV(a, b, eflags, "e");
+        TEST_FCMOV(a, b, eflags, "be");
+        TEST_FCMOV(a, b, eflags, "nb");
+        TEST_FCMOV(a, b, eflags, "ne");
+        TEST_FCMOV(a, b, eflags, "nbe");
+    }
+    TEST_FCMOV(a, b, 0, "u");
+    TEST_FCMOV(a, b, CC_P, "u");
+    TEST_FCMOV(a, b, 0, "nu");
+    TEST_FCMOV(a, b, CC_P, "nu");
+}
+
+void test_floats(void)
+{
+    test_fops(2, 3);
+    test_fops(1.4, -5);
+    test_fcmp(2, -1);
+    test_fcmp(2, 2);
+    test_fcmp(2, 3);
+    test_fcvt(0.5);
+    test_fcvt(-0.5);
+    test_fcvt(1.0/7.0);
+    test_fcvt(-1.0/9.0);
+    test_fcvt(32768);
+    test_fcvt(-1e20);
+    test_fconst();
+    test_fbcd(1234567890123456);
+    test_fbcd(-123451234567890);
+    test_fenv();
+    if (TEST_CMOV) {
+        test_fcmov();
+    }
+}
+
+/**********************************************/
+
+#define TEST_BCD(op, op0, cc_in, cc_mask)\
+{\
+    int res, flags;\
+    res = op0;\
+    flags = cc_in;\
+    asm ("push %3\n\t"\
+         "popf\n\t"\
+         #op "\n\t"\
+         "pushf\n\t"\
+         "popl %1\n\t"\
+        : "=a" (res), "=g" (flags)\
+        : "0" (res), "1" (flags));\
+    printf("%-10s A=%08x R=%08x CCIN=%04x CC=%04x\n",\
+           #op, op0, res, cc_in, flags & cc_mask);\
+}
+
+void test_bcd(void)
+{
+    TEST_BCD(daa, 0x12340503, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
+    TEST_BCD(daa, 0x12340506, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
+    TEST_BCD(daa, 0x12340507, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
+    TEST_BCD(daa, 0x12340559, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
+    TEST_BCD(daa, 0x12340560, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
+    TEST_BCD(daa, 0x1234059f, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
+    TEST_BCD(daa, 0x123405a0, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
+    TEST_BCD(daa, 0x12340503, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A));
+    TEST_BCD(daa, 0x12340506, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A));
+    TEST_BCD(daa, 0x12340503, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A));
+    TEST_BCD(daa, 0x12340506, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A));
+    TEST_BCD(daa, 0x12340503, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
+    TEST_BCD(daa, 0x12340506, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
+
+    TEST_BCD(das, 0x12340503, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
+    TEST_BCD(das, 0x12340506, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
+    TEST_BCD(das, 0x12340507, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
+    TEST_BCD(das, 0x12340559, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
+    TEST_BCD(das, 0x12340560, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
+    TEST_BCD(das, 0x1234059f, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
+    TEST_BCD(das, 0x123405a0, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
+    TEST_BCD(das, 0x12340503, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A));
+    TEST_BCD(das, 0x12340506, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A));
+    TEST_BCD(das, 0x12340503, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A));
+    TEST_BCD(das, 0x12340506, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A));
+    TEST_BCD(das, 0x12340503, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
+    TEST_BCD(das, 0x12340506, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
+
+    TEST_BCD(aaa, 0x12340205, CC_A, (CC_C | CC_A));
+    TEST_BCD(aaa, 0x12340306, CC_A, (CC_C | CC_A));
+    TEST_BCD(aaa, 0x1234040a, CC_A, (CC_C | CC_A));
+    TEST_BCD(aaa, 0x123405fa, CC_A, (CC_C | CC_A));
+    TEST_BCD(aaa, 0x12340205, 0, (CC_C | CC_A));
+    TEST_BCD(aaa, 0x12340306, 0, (CC_C | CC_A));
+    TEST_BCD(aaa, 0x1234040a, 0, (CC_C | CC_A));
+    TEST_BCD(aaa, 0x123405fa, 0, (CC_C | CC_A));
+    
+    TEST_BCD(aas, 0x12340205, CC_A, (CC_C | CC_A));
+    TEST_BCD(aas, 0x12340306, CC_A, (CC_C | CC_A));
+    TEST_BCD(aas, 0x1234040a, CC_A, (CC_C | CC_A));
+    TEST_BCD(aas, 0x123405fa, CC_A, (CC_C | CC_A));
+    TEST_BCD(aas, 0x12340205, 0, (CC_C | CC_A));
+    TEST_BCD(aas, 0x12340306, 0, (CC_C | CC_A));
+    TEST_BCD(aas, 0x1234040a, 0, (CC_C | CC_A));
+    TEST_BCD(aas, 0x123405fa, 0, (CC_C | CC_A));
+
+    TEST_BCD(aam, 0x12340547, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A));
+    TEST_BCD(aad, 0x12340407, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A));
+}
+
+#define TEST_XCHG(op, size, opconst)\
+{\
+    int op0, op1;\
+    op0 = 0x12345678;\
+    op1 = 0xfbca7654;\
+    asm(#op " %" size "0, %" size "1" \
+        : "=q" (op0), opconst (op1) \
+        : "0" (op0), "1" (op1));\
+    printf("%-10s A=%08x B=%08x\n",\
+           #op, op0, op1);\
+}
+
+#define TEST_CMPXCHG(op, size, opconst, eax)\
+{\
+    int op0, op1;\
+    op0 = 0x12345678;\
+    op1 = 0xfbca7654;\
+    asm(#op " %" size "0, %" size "1" \
+        : "=q" (op0), opconst (op1) \
+        : "0" (op0), "1" (op1), "a" (eax));\
+    printf("%-10s EAX=%08x A=%08x C=%08x\n",\
+           #op, eax, op0, op1);\
+}
+
+void test_xchg(void)
+{
+    TEST_XCHG(xchgl, "", "=q");
+    TEST_XCHG(xchgw, "w", "=q");
+    TEST_XCHG(xchgb, "b", "=q");
+
+    TEST_XCHG(xchgl, "", "=m");
+    TEST_XCHG(xchgw, "w", "=m");
+    TEST_XCHG(xchgb, "b", "=m");
+
+    TEST_XCHG(xaddl, "", "=q");
+    TEST_XCHG(xaddw, "w", "=q");
+    TEST_XCHG(xaddb, "b", "=q");
+
+    {
+        int res;
+        res = 0x12345678;
+        asm("xaddl %1, %0" : "=r" (res) : "0" (res));
+        printf("xaddl same res=%08x\n", res);
+    }
+
+    TEST_XCHG(xaddl, "", "=m");
+    TEST_XCHG(xaddw, "w", "=m");
+    TEST_XCHG(xaddb, "b", "=m");
+
+    TEST_CMPXCHG(cmpxchgl, "", "=q", 0xfbca7654);
+    TEST_CMPXCHG(cmpxchgw, "w", "=q", 0xfbca7654);
+    TEST_CMPXCHG(cmpxchgb, "b", "=q", 0xfbca7654);
+
+    TEST_CMPXCHG(cmpxchgl, "", "=q", 0xfffefdfc);
+    TEST_CMPXCHG(cmpxchgw, "w", "=q", 0xfffefdfc);
+    TEST_CMPXCHG(cmpxchgb, "b", "=q", 0xfffefdfc);
+
+    TEST_CMPXCHG(cmpxchgl, "", "=m", 0xfbca7654);
+    TEST_CMPXCHG(cmpxchgw, "w", "=m", 0xfbca7654);
+    TEST_CMPXCHG(cmpxchgb, "b", "=m", 0xfbca7654);
+
+    TEST_CMPXCHG(cmpxchgl, "", "=m", 0xfffefdfc);
+    TEST_CMPXCHG(cmpxchgw, "w", "=m", 0xfffefdfc);
+    TEST_CMPXCHG(cmpxchgb, "b", "=m", 0xfffefdfc);
+
+    {
+        uint64_t op0, op1, op2;
+        int i, eflags;
+
+        for(i = 0; i < 2; i++) {
+            op0 = 0x123456789abcd;
+            if (i == 0)
+                op1 = 0xfbca765423456;
+            else
+                op1 = op0;
+            op2 = 0x6532432432434;
+            asm("cmpxchg8b %1\n" 
+                "pushf\n"
+                "popl %2\n"
+                : "=A" (op0), "=m" (op1), "=g" (eflags)
+                : "0" (op0), "m" (op1), "b" ((int)op2), "c" ((int)(op2 >> 32)));
+            printf("cmpxchg8b: op0=%016llx op1=%016llx CC=%02x\n", 
+                    op0, op1, eflags & CC_Z);
+        }
+    }
+}
+
+/**********************************************/
+/* segmentation tests */
+
+#include <asm/ldt.h>
+#include <linux/unistd.h>
+#include <linux/version.h>
+
+_syscall3(int, modify_ldt, int, func, void *, ptr, unsigned long, bytecount)
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 66)
+#define modify_ldt_ldt_s user_desc
+#endif
+
+uint8_t seg_data1[4096];
+uint8_t seg_data2[4096];
+
+#define MK_SEL(n) (((n) << 3) | 7)
+
+#define TEST_LR(op, size, seg, mask)\
+{\
+    int res, res2;\
+    res = 0x12345678;\
+    asm (op " %" size "2, %" size "0\n" \
+         "movl $0, %1\n"\
+         "jnz 1f\n"\
+         "movl $1, %1\n"\
+         "1:\n"\
+         : "=r" (res), "=r" (res2) : "m" (seg), "0" (res));\
+    printf(op ": Z=%d %08x\n", res2, res & ~(mask));\
+}
+
+/* NOTE: we use Linux modify_ldt syscall */
+void test_segs(void)
+{
+    struct modify_ldt_ldt_s ldt;
+    long long ldt_table[3];
+    int res, res2;
+    char tmp;
+    struct {
+        uint32_t offset;
+        uint16_t seg;
+    } __attribute__((packed)) segoff;
+
+    ldt.entry_number = 1;
+    ldt.base_addr = (unsigned long)&seg_data1;
+    ldt.limit = (sizeof(seg_data1) + 0xfff) >> 12;
+    ldt.seg_32bit = 1;
+    ldt.contents = MODIFY_LDT_CONTENTS_DATA;
+    ldt.read_exec_only = 0;
+    ldt.limit_in_pages = 1;
+    ldt.seg_not_present = 0;
+    ldt.useable = 1;
+    modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */
+
+    ldt.entry_number = 2;
+    ldt.base_addr = (unsigned long)&seg_data2;
+    ldt.limit = (sizeof(seg_data2) + 0xfff) >> 12;
+    ldt.seg_32bit = 1;
+    ldt.contents = MODIFY_LDT_CONTENTS_DATA;
+    ldt.read_exec_only = 0;
+    ldt.limit_in_pages = 1;
+    ldt.seg_not_present = 0;
+    ldt.useable = 1;
+    modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */
+
+    modify_ldt(0, &ldt_table, sizeof(ldt_table)); /* read ldt entries */
+#if 0
+    {
+        int i;
+        for(i=0;i<3;i++)
+            printf("%d: %016Lx\n", i, ldt_table[i]);
+    }
+#endif
+    /* do some tests with fs or gs */
+    asm volatile ("movl %0, %%fs" : : "r" (MK_SEL(1)));
+
+    seg_data1[1] = 0xaa;
+    seg_data2[1] = 0x55;
+
+    asm volatile ("fs movzbl 0x1, %0" : "=r" (res));
+    printf("FS[1] = %02x\n", res);
+
+    asm volatile ("pushl %%gs\n"
+                  "movl %1, %%gs\n"
+                  "gs movzbl 0x1, %0\n"
+                  "popl %%gs\n"
+                  : "=r" (res)
+                  : "r" (MK_SEL(2)));
+    printf("GS[1] = %02x\n", res);
+
+    /* tests with ds/ss (implicit segment case) */
+    tmp = 0xa5;
+    asm volatile ("pushl %%ebp\n\t"
+                  "pushl %%ds\n\t"
+                  "movl %2, %%ds\n\t"
+                  "movl %3, %%ebp\n\t"
+                  "movzbl 0x1, %0\n\t"
+                  "movzbl (%%ebp), %1\n\t"
+                  "popl %%ds\n\t"
+                  "popl %%ebp\n\t"
+                  : "=r" (res), "=r" (res2)
+                  : "r" (MK_SEL(1)), "r" (&tmp));
+    printf("DS[1] = %02x\n", res);
+    printf("SS[tmp] = %02x\n", res2);
+
+    segoff.seg = MK_SEL(2);
+    segoff.offset = 0xabcdef12;
+    asm volatile("lfs %2, %0\n\t" 
+                 "movl %%fs, %1\n\t"
+                 : "=r" (res), "=g" (res2) 
+                 : "m" (segoff));
+    printf("FS:reg = %04x:%08x\n", res2, res);
+
+    TEST_LR("larw", "w", MK_SEL(2), 0x0100);
+    TEST_LR("larl", "", MK_SEL(2), 0x0100);
+    TEST_LR("lslw", "w", MK_SEL(2), 0);
+    TEST_LR("lsll", "", MK_SEL(2), 0);
+
+    TEST_LR("larw", "w", 0xfff8, 0);
+    TEST_LR("larl", "", 0xfff8, 0);
+    TEST_LR("lslw", "w", 0xfff8, 0);
+    TEST_LR("lsll", "", 0xfff8, 0);
+}
+
+/* 16 bit code test */
+extern char code16_start, code16_end;
+extern char code16_func1;
+extern char code16_func2;
+extern char code16_func3;
+
+void test_code16(void)
+{
+    struct modify_ldt_ldt_s ldt;
+    int res, res2;
+
+    /* build a code segment */
+    ldt.entry_number = 1;
+    ldt.base_addr = (unsigned long)&code16_start;
+    ldt.limit = &code16_end - &code16_start;
+    ldt.seg_32bit = 0;
+    ldt.contents = MODIFY_LDT_CONTENTS_CODE;
+    ldt.read_exec_only = 0;
+    ldt.limit_in_pages = 0;
+    ldt.seg_not_present = 0;
+    ldt.useable = 1;
+    modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */
+
+    /* call the first function */
+    asm volatile ("lcall %1, %2" 
+                  : "=a" (res)
+                  : "i" (MK_SEL(1)), "i" (&code16_func1): "memory", "cc");
+    printf("func1() = 0x%08x\n", res);
+    asm volatile ("lcall %2, %3" 
+                  : "=a" (res), "=c" (res2)
+                  : "i" (MK_SEL(1)), "i" (&code16_func2): "memory", "cc");
+    printf("func2() = 0x%08x spdec=%d\n", res, res2);
+    asm volatile ("lcall %1, %2" 
+                  : "=a" (res)
+                  : "i" (MK_SEL(1)), "i" (&code16_func3): "memory", "cc");
+    printf("func3() = 0x%08x\n", res);
+}
+
+extern char func_lret32;
+extern char func_iret32;
+
+void test_misc(void)
+{
+    char table[256];
+    int res, i;
+
+    for(i=0;i<256;i++) table[i] = 256 - i;
+    res = 0x12345678;
+    asm ("xlat" : "=a" (res) : "b" (table), "0" (res));
+    printf("xlat: EAX=%08x\n", res);
+
+    asm volatile ("pushl %%cs ; call %1" 
+                  : "=a" (res)
+                  : "m" (func_lret32): "memory", "cc");
+    printf("func_lret32=%x\n", res);
+
+    asm volatile ("pushfl ; pushl %%cs ; call %1" 
+                  : "=a" (res)
+                  : "m" (func_iret32): "memory", "cc");
+    printf("func_iret32=%x\n", res);
+
+    /* specific popl test */
+    asm volatile ("pushl $12345432 ; pushl $0x9abcdef ; popl (%%esp) ; popl %0"
+                  : "=g" (res));
+    printf("popl esp=%x\n", res);
+
+    /* specific popw test */
+    asm volatile ("pushl $12345432 ; pushl $0x9abcdef ; popw (%%esp) ; addl $2, %%esp ; popl %0"
+                  : "=g" (res));
+    printf("popw esp=%x\n", res);
+}
+
+uint8_t str_buffer[4096];
+
+#define TEST_STRING1(OP, size, DF, REP)\
+{\
+    int esi, edi, eax, ecx, eflags;\
+\
+    esi = (long)(str_buffer + sizeof(str_buffer) / 2);\
+    edi = (long)(str_buffer + sizeof(str_buffer) / 2) + 16;\
+    eax = 0x12345678;\
+    ecx = 17;\
+\
+    asm volatile ("pushl $0\n\t"\
+                  "popf\n\t"\
+                  DF "\n\t"\
+                  REP #OP size "\n\t"\
+                  "cld\n\t"\
+                  "pushf\n\t"\
+                  "popl %4\n\t"\
+                  : "=S" (esi), "=D" (edi), "=a" (eax), "=c" (ecx), "=g" (eflags)\
+                  : "0" (esi), "1" (edi), "2" (eax), "3" (ecx));\
+    printf("%-10s ESI=%08x EDI=%08x EAX=%08x ECX=%08x EFL=%04x\n",\
+           REP #OP size, esi, edi, eax, ecx,\
+           eflags & (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A));\
+}
+
+#define TEST_STRING(OP, REP)\
+    TEST_STRING1(OP, "b", "", REP);\
+    TEST_STRING1(OP, "w", "", REP);\
+    TEST_STRING1(OP, "l", "", REP);\
+    TEST_STRING1(OP, "b", "std", REP);\
+    TEST_STRING1(OP, "w", "std", REP);\
+    TEST_STRING1(OP, "l", "std", REP)
+
+void test_string(void)
+{
+    int i;
+    for(i = 0;i < sizeof(str_buffer); i++)
+        str_buffer[i] = i + 0x56;
+   TEST_STRING(stos, "");
+   TEST_STRING(stos, "rep ");
+   TEST_STRING(lods, ""); /* to verify stos */
+   TEST_STRING(lods, "rep "); 
+   TEST_STRING(movs, "");
+   TEST_STRING(movs, "rep ");
+   TEST_STRING(lods, ""); /* to verify stos */
+
+   /* XXX: better tests */
+   TEST_STRING(scas, "");
+   TEST_STRING(scas, "repz ");
+   TEST_STRING(scas, "repnz ");
+   TEST_STRING(cmps, "");
+   TEST_STRING(cmps, "repz ");
+   TEST_STRING(cmps, "repnz ");
+}
+
+/* VM86 test */
+
+static inline void set_bit(uint8_t *a, unsigned int bit)
+{
+    a[bit / 8] |= (1 << (bit % 8));
+}
+
+static inline uint8_t *seg_to_linear(unsigned int seg, unsigned int reg)
+{
+    return (uint8_t *)((seg << 4) + (reg & 0xffff));
+}
+
+static inline void pushw(struct vm86_regs *r, int val)
+{
+    r->esp = (r->esp & ~0xffff) | ((r->esp - 2) & 0xffff);
+    *(uint16_t *)seg_to_linear(r->ss, r->esp) = val;
+}
+
+#undef __syscall_return
+#define __syscall_return(type, res) \
+do { \
+       return (type) (res); \
+} while (0)
+
+_syscall2(int, vm86, int, func, struct vm86plus_struct *, v86)
+
+extern char vm86_code_start;
+extern char vm86_code_end;
+
+#define VM86_CODE_CS 0x100
+#define VM86_CODE_IP 0x100
+
+void test_vm86(void)
+{
+    struct vm86plus_struct ctx;
+    struct vm86_regs *r;
+    uint8_t *vm86_mem;
+    int seg, ret;
+
+    vm86_mem = mmap((void *)0x00000000, 0x110000, 
+                    PROT_WRITE | PROT_READ | PROT_EXEC, 
+                    MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0);
+    if (vm86_mem == MAP_FAILED) {
+        printf("ERROR: could not map vm86 memory");
+        return;
+    }
+    memset(&ctx, 0, sizeof(ctx));
+
+    /* init basic registers */
+    r = &ctx.regs;
+    r->eip = VM86_CODE_IP;
+    r->esp = 0xfffe;
+    seg = VM86_CODE_CS;
+    r->cs = seg;
+    r->ss = seg;
+    r->ds = seg;
+    r->es = seg;
+    r->fs = seg;
+    r->gs = seg;
+    r->eflags = VIF_MASK;
+
+    /* move code to proper address. We use the same layout as a .com
+       dos program. */
+    memcpy(vm86_mem + (VM86_CODE_CS << 4) + VM86_CODE_IP, 
+           &vm86_code_start, &vm86_code_end - &vm86_code_start);
+
+    /* mark int 0x21 as being emulated */
+    set_bit((uint8_t *)&ctx.int_revectored, 0x21);
+
+    for(;;) {
+        ret = vm86(VM86_ENTER, &ctx);
+        switch(VM86_TYPE(ret)) {
+        case VM86_INTx:
+            {
+                int int_num, ah, v;
+                
+                int_num = VM86_ARG(ret);
+                if (int_num != 0x21)
+                    goto unknown_int;
+                ah = (r->eax >> 8) & 0xff;
+                switch(ah) {
+                case 0x00: /* exit */
+                    goto the_end;
+                case 0x02: /* write char */
+                    {
+                        uint8_t c = r->edx;
+                        putchar(c);
+                    }
+                    break;
+                case 0x09: /* write string */
+                    {
+                        uint8_t c, *ptr;
+                        ptr = seg_to_linear(r->ds, r->edx);
+                        for(;;) {
+                            c = *ptr++;
+                            if (c == '$')
+                                break;
+                            putchar(c);
+                        }
+                        r->eax = (r->eax & ~0xff) | '$';
+                    }
+                    break;
+                case 0xff: /* extension: write eflags number in edx */
+                    v = (int)r->edx;
+#ifndef LINUX_VM86_IOPL_FIX
+                    v &= ~0x3000;
+#endif
+                    printf("%08x\n", v);
+                    break;
+                default:
+                unknown_int:
+                    printf("unsupported int 0x%02x\n", int_num);
+                    goto the_end;
+                }
+            }
+            break;
+        case VM86_SIGNAL:
+            /* a signal came, we just ignore that */
+            break;
+        case VM86_STI:
+            break;
+        default:
+            printf("ERROR: unhandled vm86 return code (0x%x)\n", ret);
+            goto the_end;
+        }
+    }
+ the_end:
+    printf("VM86 end\n");
+    munmap(vm86_mem, 0x110000);
+}
+
+/* exception tests */
+#ifndef REG_EAX
+#define REG_EAX EAX
+#define REG_EBX EBX
+#define REG_ECX ECX
+#define REG_EDX EDX
+#define REG_ESI ESI
+#define REG_EDI EDI
+#define REG_EBP EBP
+#define REG_ESP ESP
+#define REG_EIP EIP
+#define REG_EFL EFL
+#define REG_TRAPNO TRAPNO
+#define REG_ERR ERR
+#endif
+
+jmp_buf jmp_env;
+int v1;
+int tab[2];
+
+void sig_handler(int sig, siginfo_t *info, void *puc)
+{
+    struct ucontext *uc = puc;
+
+    printf("si_signo=%d si_errno=%d si_code=%d",
+           info->si_signo, info->si_errno, info->si_code);
+    printf(" si_addr=0x%08lx",
+           (unsigned long)info->si_addr);
+    printf("\n");
+
+    printf("trapno=0x%02x err=0x%08x",
+           uc->uc_mcontext.gregs[REG_TRAPNO],
+           uc->uc_mcontext.gregs[REG_ERR]);
+    printf(" EIP=0x%08x", uc->uc_mcontext.gregs[REG_EIP]);
+    printf("\n");
+    longjmp(jmp_env, 1);
+}
+
+void test_exceptions(void)
+{
+    struct modify_ldt_ldt_s ldt;
+    struct sigaction act;
+    volatile int val;
+    
+    act.sa_sigaction = sig_handler;
+    sigemptyset(&act.sa_mask);
+    act.sa_flags = SA_SIGINFO;
+    sigaction(SIGFPE, &act, NULL);
+    sigaction(SIGILL, &act, NULL);
+    sigaction(SIGSEGV, &act, NULL);
+    sigaction(SIGBUS, &act, NULL);
+    sigaction(SIGTRAP, &act, NULL);
+
+    /* test division by zero reporting */
+    printf("DIVZ exception:\n");
+    if (setjmp(jmp_env) == 0) {
+        /* now divide by zero */
+        v1 = 0;
+        v1 = 2 / v1;
+    }
+
+    printf("BOUND exception:\n");
+    if (setjmp(jmp_env) == 0) {
+        /* bound exception */
+        tab[0] = 1;
+        tab[1] = 10;
+        asm volatile ("bound %0, %1" : : "r" (11), "m" (tab[0]));
+    }
+
+    printf("segment exceptions:\n");
+    if (setjmp(jmp_env) == 0) {
+        /* load an invalid segment */
+        asm volatile ("movl %0, %%fs" : : "r" ((0x1234 << 3) | 1));
+    }
+    if (setjmp(jmp_env) == 0) {
+        /* null data segment is valid */
+        asm volatile ("movl %0, %%fs" : : "r" (3));
+        /* null stack segment */
+        asm volatile ("movl %0, %%ss" : : "r" (3));
+    }
+
+    ldt.entry_number = 1;
+    ldt.base_addr = (unsigned long)&seg_data1;
+    ldt.limit = (sizeof(seg_data1) + 0xfff) >> 12;
+    ldt.seg_32bit = 1;
+    ldt.contents = MODIFY_LDT_CONTENTS_DATA;
+    ldt.read_exec_only = 0;
+    ldt.limit_in_pages = 1;
+    ldt.seg_not_present = 1;
+    ldt.useable = 1;
+    modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */
+
+    if (setjmp(jmp_env) == 0) {
+        /* segment not present */
+        asm volatile ("movl %0, %%fs" : : "r" (MK_SEL(1)));
+    }
+
+    /* test SEGV reporting */
+    printf("PF exception:\n");
+    if (setjmp(jmp_env) == 0) {
+        val = 1;
+        /* we add a nop to test a weird PC retrieval case */
+        asm volatile ("nop");
+        /* now store in an invalid address */
+        *(char *)0x1234 = 1;
+    }
+
+    /* test SEGV reporting */
+    printf("PF exception:\n");
+    if (setjmp(jmp_env) == 0) {
+        val = 1;
+        /* read from an invalid address */
+        v1 = *(char *)0x1234;
+    }
+    
+    /* test illegal instruction reporting */
+    printf("UD2 exception:\n");
+    if (setjmp(jmp_env) == 0) {
+        /* now execute an invalid instruction */
+        asm volatile("ud2");
+    }
+    printf("lock nop exception:\n");
+    if (setjmp(jmp_env) == 0) {
+        /* now execute an invalid instruction */
+        asm volatile("lock nop");
+    }
+    
+    printf("INT exception:\n");
+    if (setjmp(jmp_env) == 0) {
+        asm volatile ("int $0xfd");
+    }
+    if (setjmp(jmp_env) == 0) {
+        asm volatile ("int $0x01");
+    }
+    if (setjmp(jmp_env) == 0) {
+        asm volatile (".byte 0xcd, 0x03");
+    }
+    if (setjmp(jmp_env) == 0) {
+        asm volatile ("int $0x04");
+    }
+    if (setjmp(jmp_env) == 0) {
+        asm volatile ("int $0x05");
+    }
+
+    printf("INT3 exception:\n");
+    if (setjmp(jmp_env) == 0) {
+        asm volatile ("int3");
+    }
+
+    printf("CLI exception:\n");
+    if (setjmp(jmp_env) == 0) {
+        asm volatile ("cli");
+    }
+
+    printf("STI exception:\n");
+    if (setjmp(jmp_env) == 0) {
+        asm volatile ("cli");
+    }
+
+    printf("INTO exception:\n");
+    if (setjmp(jmp_env) == 0) {
+        /* overflow exception */
+        asm volatile ("addl $1, %0 ; into" : : "r" (0x7fffffff));
+    }
+
+    printf("OUTB exception:\n");
+    if (setjmp(jmp_env) == 0) {
+        asm volatile ("outb %%al, %%dx" : : "d" (0x4321), "a" (0));
+    }
+
+    printf("INB exception:\n");
+    if (setjmp(jmp_env) == 0) {
+        asm volatile ("inb %%dx, %%al" : "=a" (val) : "d" (0x4321));
+    }
+
+    printf("REP OUTSB exception:\n");
+    if (setjmp(jmp_env) == 0) {
+        asm volatile ("rep outsb" : : "d" (0x4321), "S" (tab), "c" (1));
+    }
+
+    printf("REP INSB exception:\n");
+    if (setjmp(jmp_env) == 0) {
+        asm volatile ("rep insb" : : "d" (0x4321), "D" (tab), "c" (1));
+    }
+
+    printf("HLT exception:\n");
+    if (setjmp(jmp_env) == 0) {
+        asm volatile ("hlt");
+    }
+
+    printf("single step exception:\n");
+    val = 0;
+    if (setjmp(jmp_env) == 0) {
+        asm volatile ("pushf\n"
+                      "orl $0x00100, (%%esp)\n"
+                      "popf\n"
+                      "movl $0xabcd, %0\n" 
+                      "movl $0x0, %0\n" : "=m" (val) : : "cc", "memory");
+    }
+    printf("val=0x%x\n", val);
+}
+
+/* specific precise single step test */
+void sig_trap_handler(int sig, siginfo_t *info, void *puc)
+{
+    struct ucontext *uc = puc;
+    printf("EIP=0x%08x\n", uc->uc_mcontext.gregs[REG_EIP]);
+}
+
+const uint8_t sstep_buf1[4] = { 1, 2, 3, 4};
+uint8_t sstep_buf2[4];
+
+void test_single_step(void)
+{
+    struct sigaction act;
+    volatile int val;
+    int i;
+
+    val = 0;
+    act.sa_sigaction = sig_trap_handler;
+    sigemptyset(&act.sa_mask);
+    act.sa_flags = SA_SIGINFO;
+    sigaction(SIGTRAP, &act, NULL);
+    asm volatile ("pushf\n"
+                  "orl $0x00100, (%%esp)\n"
+                  "popf\n"
+                  "movl $0xabcd, %0\n" 
+
+                  /* jmp test */
+                  "movl $3, %%ecx\n"
+                  "1:\n"
+                  "addl $1, %0\n"
+                  "decl %%ecx\n"
+                  "jnz 1b\n"
+
+                  /* movsb: the single step should stop at each movsb iteration */
+                  "movl $sstep_buf1, %%esi\n"
+                  "movl $sstep_buf2, %%edi\n"
+                  "movl $0, %%ecx\n"
+                  "rep movsb\n"
+                  "movl $3, %%ecx\n"
+                  "rep movsb\n"
+                  "movl $1, %%ecx\n"
+                  "rep movsb\n"
+
+                  /* cmpsb: the single step should stop at each cmpsb iteration */
+                  "movl $sstep_buf1, %%esi\n"
+                  "movl $sstep_buf2, %%edi\n"
+                  "movl $0, %%ecx\n"
+                  "rep cmpsb\n"
+                  "movl $4, %%ecx\n"
+                  "rep cmpsb\n"
+                  
+                  /* getpid() syscall: single step should skip one
+                     instruction */
+                  "movl $20, %%eax\n"
+                  "int $0x80\n"
+                  "movl $0, %%eax\n"
+                  
+                  /* when modifying SS, trace is not done on the next
+                     instruction */
+                  "movl %%ss, %%ecx\n"
+                  "movl %%ecx, %%ss\n"
+                  "addl $1, %0\n"
+                  "movl $1, %%eax\n"
+                  "movl %%ecx, %%ss\n"
+                  "jmp 1f\n"
+                  "addl $1, %0\n"
+                  "1:\n"
+                  "movl $1, %%eax\n"
+                  "pushl %%ecx\n"
+                  "popl %%ss\n"
+                  "addl $1, %0\n"
+                  "movl $1, %%eax\n"
+                  
+                  "pushf\n"
+                  "andl $~0x00100, (%%esp)\n"
+                  "popf\n"
+                  : "=m" (val) 
+                  : 
+                  : "cc", "memory", "eax", "ecx", "esi", "edi");
+    printf("val=%d\n", val);
+    for(i = 0; i < 4; i++)
+        printf("sstep_buf2[%d] = %d\n", i, sstep_buf2[i]);
+}
+
+/* self modifying code test */
+uint8_t code[] = {
+    0xb8, 0x1, 0x00, 0x00, 0x00, /* movl $1, %eax */
+    0xc3, /* ret */
+};
+
+asm("smc_code2:\n"
+    "movl 4(%esp), %eax\n"
+    "movl %eax, smc_patch_addr2 + 1\n"
+    "nop\n"
+    "nop\n"
+    "nop\n"
+    "nop\n"
+    "nop\n"
+    "nop\n"
+    "nop\n"
+    "nop\n"
+    "smc_patch_addr2:\n"
+    "movl $1, %eax\n"
+    "ret\n");
+
+typedef int FuncType(void);
+extern int smc_code2(int);
+void test_self_modifying_code(void)
+{
+    int i;
+
+    printf("self modifying code:\n");
+    printf("func1 = 0x%x\n", ((FuncType *)code)());
+    for(i = 2; i <= 4; i++) {
+        code[1] = i;
+        printf("func%d = 0x%x\n", i, ((FuncType *)code)());
+    }
+
+    /* more difficult test : the modified code is just after the
+       modifying instruction. It is forbidden in Intel specs, but it
+       is used by old DOS programs */
+    for(i = 2; i <= 4; i++) {
+        printf("smc_code2(%d) = %d\n", i, smc_code2(i));
+    }
+}
+
+int enter_stack[4096];
+
+#define TEST_ENTER(size, stack_type, level)\
+{\
+    int esp_save, esp_val, ebp_val, ebp_save, i;\
+    stack_type *ptr, *stack_end, *stack_ptr;\
+    memset(enter_stack, 0, sizeof(enter_stack));\
+    stack_end = stack_ptr = (stack_type *)(enter_stack + 4096);\
+    ebp_val = (long)stack_ptr;\
+    for(i=1;i<=32;i++)\
+       *--stack_ptr = i;\
+    esp_val = (long)stack_ptr;\
+    asm("movl %%esp, %[esp_save]\n"\
+        "movl %%ebp, %[ebp_save]\n"\
+        "movl %[esp_val], %%esp\n"\
+        "movl %[ebp_val], %%ebp\n"\
+        "enter" size " $12, $" #level "\n"\
+        "movl %%esp, %[esp_val]\n"\
+        "movl %%ebp, %[ebp_val]\n"\
+        "movl %[esp_save], %%esp\n"\
+        "movl %[ebp_save], %%ebp\n"\
+        : [esp_save] "=r" (esp_save),\
+        [ebp_save] "=r" (ebp_save),\
+        [esp_val] "=r" (esp_val),\
+        [ebp_val] "=r" (ebp_val)\
+        :  "[esp_val]" (esp_val),\
+        "[ebp_val]" (ebp_val));\
+    printf("level=%d:\n", level);\
+    printf("esp_val=0x%08lx\n", esp_val - (long)stack_end);\
+    printf("ebp_val=0x%08lx\n", ebp_val - (long)stack_end);\
+    for(ptr = (stack_type *)esp_val; ptr < stack_end; ptr++)\
+        printf("%08x\n", ptr[0]);\
+}
+
+static void test_enter(void)
+{
+    TEST_ENTER("l", uint32_t, 0);
+    TEST_ENTER("l", uint32_t, 1);
+    TEST_ENTER("l", uint32_t, 2);
+    TEST_ENTER("l", uint32_t, 31);
+
+    TEST_ENTER("w", uint16_t, 0);
+    TEST_ENTER("w", uint16_t, 1);
+    TEST_ENTER("w", uint16_t, 2);
+    TEST_ENTER("w", uint16_t, 31);
+}
+
+
+static void *call_end __init_call = NULL;
+
+int main(int argc, char **argv)
+{
+    void **ptr;
+    void (*func)(void);
+
+    ptr = &call_start + 1;
+    while (*ptr != NULL) {
+        func = *ptr++;
+        func();
+    }
+    test_bsx();
+    test_mul();
+    test_jcc();
+    test_floats();
+    test_bcd();
+    test_xchg();
+    test_string();
+    test_misc();
+    test_lea();
+    test_segs();
+    test_code16();
+    test_vm86();
+    test_exceptions();
+    test_self_modifying_code();
+    test_single_step();
+    test_enter();
+    return 0;
+}
diff --git a/tools/ioemu/tests/test-i386.h b/tools/ioemu/tests/test-i386.h
new file mode 100644 (file)
index 0000000..7d1812c
--- /dev/null
@@ -0,0 +1,131 @@
+
+#define exec_op glue(exec_, OP)
+#define exec_opl glue(glue(exec_, OP), l)
+#define exec_opw glue(glue(exec_, OP), w)
+#define exec_opb glue(glue(exec_, OP), b)
+
+#define EXECOP2(size, res, s1, flags) \
+    asm ("push %4\n\t"\
+         "popf\n\t"\
+         stringify(OP) size " %" size "2, %" size "0\n\t" \
+         "pushf\n\t"\
+         "popl %1\n\t"\
+         : "=q" (res), "=g" (flags)\
+         : "q" (s1), "0" (res), "1" (flags));
+
+#define EXECOP1(size, res, flags) \
+    asm ("push %3\n\t"\
+         "popf\n\t"\
+         stringify(OP) size " %" size "0\n\t" \
+         "pushf\n\t"\
+         "popl %1\n\t"\
+         : "=q" (res), "=g" (flags)\
+         : "0" (res), "1" (flags));
+
+#ifdef OP1
+void exec_opl(int s0, int s1, int iflags)
+{
+    int res, flags;
+    res = s0;
+    flags = iflags;
+    EXECOP1("", res, flags);
+    printf("%-10s A=%08x R=%08x CCIN=%04x CC=%04x\n",
+           stringify(OP) "l", s0, res, iflags, flags & CC_MASK);
+}
+
+void exec_opw(int s0, int s1, int iflags)
+{
+    int res, flags;
+    res = s0;
+    flags = iflags;
+    EXECOP1("w", res, flags);
+    printf("%-10s A=%08x R=%08x CCIN=%04x CC=%04x\n",
+           stringify(OP) "w", s0, res, iflags, flags & CC_MASK);
+}
+
+void exec_opb(int s0, int s1, int iflags)
+{
+    int res, flags;
+    res = s0;
+    flags = iflags;
+    EXECOP1("b", res, flags);
+    printf("%-10s A=%08x R=%08x CCIN=%04x CC=%04x\n",
+           stringify(OP) "b", s0, res, iflags, flags & CC_MASK);
+}
+#else
+void exec_opl(int s0, int s1, int iflags)
+{
+    int res, flags;
+    res = s0;
+    flags = iflags;
+    EXECOP2("", res, s1, flags);
+    printf("%-10s A=%08x B=%08x R=%08x CCIN=%04x CC=%04x\n",
+           stringify(OP) "l", s0, s1, res, iflags, flags & CC_MASK);
+}
+
+void exec_opw(int s0, int s1, int iflags)
+{
+    int res, flags;
+    res = s0;
+    flags = iflags;
+    EXECOP2("w", res, s1, flags);
+    printf("%-10s A=%08x B=%08x R=%08x CCIN=%04x CC=%04x\n",
+           stringify(OP) "w", s0, s1, res, iflags, flags & CC_MASK);
+}
+
+void exec_opb(int s0, int s1, int iflags)
+{
+    int res, flags;
+    res = s0;
+    flags = iflags;
+    EXECOP2("b", res, s1, flags);
+    printf("%-10s A=%08x B=%08x R=%08x CCIN=%04x CC=%04x\n",
+           stringify(OP) "b", s0, s1, res, iflags, flags & CC_MASK);
+}
+#endif
+
+void exec_op(int s0, int s1)
+{
+    exec_opl(s0, s1, 0);
+    exec_opw(s0, s1, 0);
+    exec_opb(s0, s1, 0);
+#ifdef OP_CC
+    exec_opl(s0, s1, CC_C);
+    exec_opw(s0, s1, CC_C);
+    exec_opb(s0, s1, CC_C);
+#endif
+}
+
+void glue(test_, OP)(void)
+{
+    exec_op(0x12345678, 0x812FADA);
+    exec_op(0x12341, 0x12341);
+    exec_op(0x12341, -0x12341);
+    exec_op(0xffffffff, 0);
+    exec_op(0xffffffff, -1);
+    exec_op(0xffffffff, 1);
+    exec_op(0xffffffff, 2);
+    exec_op(0x7fffffff, 0);
+    exec_op(0x7fffffff, 1);
+    exec_op(0x7fffffff, -1);
+    exec_op(0x80000000, -1);
+    exec_op(0x80000000, 1);
+    exec_op(0x80000000, -2);
+    exec_op(0x12347fff, 0);
+    exec_op(0x12347fff, 1);
+    exec_op(0x12347fff, -1);
+    exec_op(0x12348000, -1);
+    exec_op(0x12348000, 1);
+    exec_op(0x12348000, -2);
+    exec_op(0x12347f7f, 0);
+    exec_op(0x12347f7f, 1);
+    exec_op(0x12347f7f, -1);
+    exec_op(0x12348080, -1);
+    exec_op(0x12348080, 1);
+    exec_op(0x12348080, -2);
+}
+
+void *glue(_test_, OP) __init_call = glue(test_, OP);
+
+#undef OP
+#undef OP_CC
diff --git a/tools/ioemu/tests/test_path.c b/tools/ioemu/tests/test_path.c
new file mode 100644 (file)
index 0000000..a9b52de
--- /dev/null
@@ -0,0 +1,152 @@
+/* Test path override code */
+#define _GNU_SOURCE
+#include "../path.c"
+#include <stdarg.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+/* Any log message kills the test. */
+void gemu_log(const char *fmt, ...)
+{
+    va_list ap;
+
+    fprintf(stderr, "FATAL: ");
+    va_start(ap, fmt);
+    vfprintf(stderr, fmt, ap);
+    va_end(ap);
+    exit(1);
+}
+
+#define NO_CHANGE(_path)                                               \
+       do {                                                            \
+           if (strcmp(path(_path), _path) != 0) return __LINE__;       \
+       } while(0)
+
+#define CHANGE_TO(_path, _newpath)                                     \
+       do {                                                            \
+           if (strcmp(path(_path), _newpath) != 0) return __LINE__;    \
+       } while(0)
+
+static void cleanup(void)
+{
+    unlink("/tmp/qemu-test_path/DIR1/DIR2/FILE");
+    unlink("/tmp/qemu-test_path/DIR1/DIR2/FILE2");
+    unlink("/tmp/qemu-test_path/DIR1/DIR2/FILE3");
+    unlink("/tmp/qemu-test_path/DIR1/DIR2/FILE4");
+    unlink("/tmp/qemu-test_path/DIR1/DIR2/FILE5");
+    rmdir("/tmp/qemu-test_path/DIR1/DIR2");
+    rmdir("/tmp/qemu-test_path/DIR1/DIR3");
+    rmdir("/tmp/qemu-test_path/DIR1");
+    rmdir("/tmp/qemu-test_path");
+}
+
+static unsigned int do_test(void)
+{
+    if (mkdir("/tmp/qemu-test_path", 0700) != 0)
+       return __LINE__;
+
+    if (mkdir("/tmp/qemu-test_path/DIR1", 0700) != 0)
+       return __LINE__;
+
+    if (mkdir("/tmp/qemu-test_path/DIR1/DIR2", 0700) != 0)
+       return __LINE__;
+
+    if (mkdir("/tmp/qemu-test_path/DIR1/DIR3", 0700) != 0)
+       return __LINE__;
+
+    if (close(creat("/tmp/qemu-test_path/DIR1/DIR2/FILE", 0600)) != 0)
+       return __LINE__;
+
+    if (close(creat("/tmp/qemu-test_path/DIR1/DIR2/FILE2", 0600)) != 0)
+       return __LINE__;
+
+    if (close(creat("/tmp/qemu-test_path/DIR1/DIR2/FILE3", 0600)) != 0)
+       return __LINE__;
+
+    if (close(creat("/tmp/qemu-test_path/DIR1/DIR2/FILE4", 0600)) != 0)
+       return __LINE__;
+
+    if (close(creat("/tmp/qemu-test_path/DIR1/DIR2/FILE5", 0600)) != 0)
+       return __LINE__;
+
+    init_paths("/tmp/qemu-test_path");
+
+    NO_CHANGE("/tmp");
+    NO_CHANGE("/tmp/");
+    NO_CHANGE("/tmp/qemu-test_path");
+    NO_CHANGE("/tmp/qemu-test_path/");
+    NO_CHANGE("/tmp/qemu-test_path/D");
+    NO_CHANGE("/tmp/qemu-test_path/DI");
+    NO_CHANGE("/tmp/qemu-test_path/DIR");
+    NO_CHANGE("/tmp/qemu-test_path/DIR1");
+    NO_CHANGE("/tmp/qemu-test_path/DIR1/");
+
+    NO_CHANGE("/D");
+    NO_CHANGE("/DI");
+    NO_CHANGE("/DIR");
+    NO_CHANGE("/DIR2");
+    NO_CHANGE("/DIR1.");
+
+    CHANGE_TO("/DIR1", "/tmp/qemu-test_path/DIR1");
+    CHANGE_TO("/DIR1/", "/tmp/qemu-test_path/DIR1");
+
+    NO_CHANGE("/DIR1/D");
+    NO_CHANGE("/DIR1/DI");
+    NO_CHANGE("/DIR1/DIR");
+    NO_CHANGE("/DIR1/DIR1");
+
+    CHANGE_TO("/DIR1/DIR2", "/tmp/qemu-test_path/DIR1/DIR2");
+    CHANGE_TO("/DIR1/DIR2/", "/tmp/qemu-test_path/DIR1/DIR2");
+
+    CHANGE_TO("/DIR1/DIR3", "/tmp/qemu-test_path/DIR1/DIR3");
+    CHANGE_TO("/DIR1/DIR3/", "/tmp/qemu-test_path/DIR1/DIR3");
+
+    NO_CHANGE("/DIR1/DIR2/F");
+    NO_CHANGE("/DIR1/DIR2/FI");
+    NO_CHANGE("/DIR1/DIR2/FIL");
+    NO_CHANGE("/DIR1/DIR2/FIL.");
+
+    CHANGE_TO("/DIR1/DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE");
+    CHANGE_TO("/DIR1/DIR2/FILE2", "/tmp/qemu-test_path/DIR1/DIR2/FILE2");
+    CHANGE_TO("/DIR1/DIR2/FILE3", "/tmp/qemu-test_path/DIR1/DIR2/FILE3");
+    CHANGE_TO("/DIR1/DIR2/FILE4", "/tmp/qemu-test_path/DIR1/DIR2/FILE4");
+    CHANGE_TO("/DIR1/DIR2/FILE5", "/tmp/qemu-test_path/DIR1/DIR2/FILE5");
+
+    NO_CHANGE("/DIR1/DIR2/FILE6");
+    NO_CHANGE("/DIR1/DIR2/FILE/X");
+
+    CHANGE_TO("/DIR1/../DIR1", "/tmp/qemu-test_path/DIR1");
+    CHANGE_TO("/DIR1/../DIR1/", "/tmp/qemu-test_path/DIR1");
+    CHANGE_TO("/../DIR1", "/tmp/qemu-test_path/DIR1");
+    CHANGE_TO("/../DIR1/", "/tmp/qemu-test_path/DIR1");
+    CHANGE_TO("/DIR1/DIR2/../DIR2", "/tmp/qemu-test_path/DIR1/DIR2");
+    CHANGE_TO("/DIR1/DIR2/../DIR2/../../DIR1/DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE");
+    CHANGE_TO("/DIR1/DIR2/../DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE");
+
+    NO_CHANGE("/DIR1/DIR2/../DIR1");
+    NO_CHANGE("/DIR1/DIR2/../FILE");
+
+    CHANGE_TO("/./DIR1/DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE");
+    CHANGE_TO("/././DIR1/DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE");
+    CHANGE_TO("/DIR1/./DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE");
+    CHANGE_TO("/DIR1/././DIR2/FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE");
+    CHANGE_TO("/DIR1/DIR2/./FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE");
+    CHANGE_TO("/DIR1/DIR2/././FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE");
+    CHANGE_TO("/./DIR1/./DIR2/./FILE", "/tmp/qemu-test_path/DIR1/DIR2/FILE");
+
+    return 0;
+}
+
+int main(int argc, char *argv[])
+{
+    int ret;
+
+    ret = do_test();
+    cleanup();
+    if (ret) {
+       fprintf(stderr, "test_path: failed on line %i\n", ret);
+       return 1;
+    }
+    return 0;
+}
+       
diff --git a/tools/ioemu/tests/testthread.c b/tools/ioemu/tests/testthread.c
new file mode 100644 (file)
index 0000000..27e4825
--- /dev/null
@@ -0,0 +1,51 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+#include <unistd.h>
+#include <inttypes.h>
+#include <pthread.h>
+#include <sys/wait.h>
+#include <sched.h>
+
+void *thread1_func(void *arg)
+{
+    int i;
+    char buf[512];
+
+    for(i=0;i<10;i++) {
+        snprintf(buf, sizeof(buf), "thread1: %d %s\n", i, (char *)arg);
+        write(1, buf, strlen(buf));
+        usleep(100 * 1000);
+    }
+    return NULL;
+}
+
+void *thread2_func(void *arg)
+{
+    int i;
+    char buf[512];
+    for(i=0;i<20;i++) {
+        snprintf(buf, sizeof(buf), "thread2: %d %s\n", i, (char *)arg);
+        write(1, buf, strlen(buf));
+        usleep(150 * 1000);
+    }
+    return NULL;
+}
+
+void test_pthread(void)
+{
+    pthread_t tid1, tid2;
+
+    pthread_create(&tid1, NULL, thread1_func, "hello1");
+    pthread_create(&tid2, NULL, thread2_func, "hello2");
+    pthread_join(tid1, NULL);
+    pthread_join(tid2, NULL);
+    printf("End of pthread test.\n");
+}
+
+int main(int argc, char **argv)
+{
+    test_pthread();
+    return 0;
+}
diff --git a/tools/ioemu/texi2pod.pl b/tools/ioemu/texi2pod.pl
new file mode 100755 (executable)
index 0000000..176627e
--- /dev/null
@@ -0,0 +1,428 @@
+#! /usr/bin/perl -w
+
+#   Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
+
+# This file is part of GNU CC.
+
+# GNU CC is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# GNU CC is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GNU CC; see the file COPYING.  If not, write to
+# the Free Software Foundation, 59 Temple Place - Suite 330,
+# Boston MA 02111-1307, USA.
+
+# This does trivial (and I mean _trivial_) conversion of Texinfo
+# markup to Perl POD format.  It's intended to be used to extract
+# something suitable for a manpage from a Texinfo document.
+
+$output = 0;
+$skipping = 0;
+%sects = ();
+$section = "";
+@icstack = ();
+@endwstack = ();
+@skstack = ();
+@instack = ();
+$shift = "";
+%defs = ();
+$fnno = 1;
+$inf = "";
+$ibase = "";
+
+while ($_ = shift) {
+    if (/^-D(.*)$/) {
+       if ($1 ne "") {
+           $flag = $1;
+       } else {
+           $flag = shift;
+       }
+       $value = "";
+       ($flag, $value) = ($flag =~ /^([^=]+)(?:=(.+))?/);
+       die "no flag specified for -D\n"
+           unless $flag ne "";
+       die "flags may only contain letters, digits, hyphens, dashes and underscores\n"
+           unless $flag =~ /^[a-zA-Z0-9_-]+$/;
+       $defs{$flag} = $value;
+    } elsif (/^-/) {
+       usage();
+    } else {
+       $in = $_, next unless defined $in;
+       $out = $_, next unless defined $out;
+       usage();
+    }
+}
+
+if (defined $in) {
+    $inf = gensym();
+    open($inf, "<$in") or die "opening \"$in\": $!\n";
+    $ibase = $1 if $in =~ m|^(.+)/[^/]+$|;
+} else {
+    $inf = \*STDIN;
+}
+
+if (defined $out) {
+    open(STDOUT, ">$out") or die "opening \"$out\": $!\n";
+}
+
+while(defined $inf) {
+while(<$inf>) {
+    # Certain commands are discarded without further processing.
+    /^\@(?:
+        [a-z]+index            # @*index: useful only in complete manual
+        |need                  # @need: useful only in printed manual
+        |(?:end\s+)?group      # @group .. @end group: ditto
+        |page                  # @page: ditto
+        |node                  # @node: useful only in .info file
+        |(?:end\s+)?ifnottex   # @ifnottex .. @end ifnottex: use contents
+       )\b/x and next;
+
+    chomp;
+
+    # Look for filename and title markers.
+    /^\@setfilename\s+([^.]+)/ and $fn = $1, next;
+    /^\@settitle\s+([^.]+)/ and $tl = postprocess($1), next;
+
+    # Identify a man title but keep only the one we are interested in.
+    /^\@c\s+man\s+title\s+([A-Za-z0-9-]+)\s+(.+)/ and do {
+       if (exists $defs{$1}) {
+           $fn = $1;
+           $tl = postprocess($2);
+       }
+       next;
+    };
+
+    # Look for blocks surrounded by @c man begin SECTION ... @c man end.
+    # This really oughta be @ifman ... @end ifman and the like, but such
+    # would require rev'ing all other Texinfo translators.
+    /^\@c\s+man\s+begin\s+([A-Z]+)\s+([A-Za-z0-9-]+)/ and do {
+       $output = 1 if exists $defs{$2};
+        $sect = $1;
+       next;
+    };
+    /^\@c\s+man\s+begin\s+([A-Z]+)/ and $sect = $1, $output = 1, next;
+    /^\@c\s+man\s+end/ and do {
+       $sects{$sect} = "" unless exists $sects{$sect};
+       $sects{$sect} .= postprocess($section);
+       $section = "";
+       $output = 0;
+       next;
+    };
+
+    # handle variables
+    /^\@set\s+([a-zA-Z0-9_-]+)\s*(.*)$/ and do {
+       $defs{$1} = $2;
+       next;
+    };
+    /^\@clear\s+([a-zA-Z0-9_-]+)/ and do {
+       delete $defs{$1};
+       next;
+    };
+
+    next unless $output;
+
+    # Discard comments.  (Can't do it above, because then we'd never see
+    # @c man lines.)
+    /^\@c\b/ and next;
+
+    # End-block handler goes up here because it needs to operate even
+    # if we are skipping.
+    /^\@end\s+([a-z]+)/ and do {
+       # Ignore @end foo, where foo is not an operation which may
+       # cause us to skip, if we are presently skipping.
+       my $ended = $1;
+       next if $skipping && $ended !~ /^(?:ifset|ifclear|ignore|menu|iftex)$/;
+
+       die "\@end $ended without \@$ended at line $.\n" unless defined $endw;
+       die "\@$endw ended by \@end $ended at line $.\n" unless $ended eq $endw;
+
+       $endw = pop @endwstack;
+
+       if ($ended =~ /^(?:ifset|ifclear|ignore|menu|iftex)$/) {
+           $skipping = pop @skstack;
+           next;
+       } elsif ($ended =~ /^(?:example|smallexample|display)$/) {
+           $shift = "";
+           $_ = "";    # need a paragraph break
+       } elsif ($ended =~ /^(?:itemize|enumerate|[fv]?table)$/) {
+           $_ = "\n=back\n";
+           $ic = pop @icstack;
+       } else {
+           die "unknown command \@end $ended at line $.\n";
+       }
+    };
+
+    # We must handle commands which can cause skipping even while we
+    # are skipping, otherwise we will not process nested conditionals
+    # correctly.
+    /^\@ifset\s+([a-zA-Z0-9_-]+)/ and do {
+       push @endwstack, $endw;
+       push @skstack, $skipping;
+       $endw = "ifset";
+       $skipping = 1 unless exists $defs{$1};
+       next;
+    };
+
+    /^\@ifclear\s+([a-zA-Z0-9_-]+)/ and do {
+       push @endwstack, $endw;
+       push @skstack, $skipping;
+       $endw = "ifclear";
+       $skipping = 1 if exists $defs{$1};
+       next;
+    };
+
+    /^\@(ignore|menu|iftex)\b/ and do {
+       push @endwstack, $endw;
+       push @skstack, $skipping;
+       $endw = $1;
+       $skipping = 1;
+       next;
+    };
+
+    next if $skipping;
+
+    # Character entities.  First the ones that can be replaced by raw text
+    # or discarded outright:
+    s/\@copyright\{\}/(c)/g;
+    s/\@dots\{\}/.../g;
+    s/\@enddots\{\}/..../g;
+    s/\@([.!? ])/$1/g;
+    s/\@[:-]//g;
+    s/\@bullet(?:\{\})?/*/g;
+    s/\@TeX\{\}/TeX/g;
+    s/\@pounds\{\}/\#/g;
+    s/\@minus(?:\{\})?/-/g;
+    s/\\,/,/g;
+
+    # Now the ones that have to be replaced by special escapes
+    # (which will be turned back into text by unmunge())
+    s/&/&amp;/g;
+    s/\@\{/&lbrace;/g;
+    s/\@\}/&rbrace;/g;
+    s/\@\@/&at;/g;
+
+    # Inside a verbatim block, handle @var specially.
+    if ($shift ne "") {
+       s/\@var\{([^\}]*)\}/<$1>/g;
+    }
+
+    # POD doesn't interpret E<> inside a verbatim block.
+    if ($shift eq "") {
+       s/</&lt;/g;
+       s/>/&gt;/g;
+    } else {
+       s/</&LT;/g;
+       s/>/&GT;/g;
+    }
+
+    # Single line command handlers.
+
+    /^\@include\s+(.+)$/ and do {
+       push @instack, $inf;
+       $inf = gensym();
+
+       # Try cwd and $ibase.
+       open($inf, "<" . $1) 
+           or open($inf, "<" . $ibase . "/" . $1)
+               or die "cannot open $1 or $ibase/$1: $!\n";
+       next;
+    };
+
+    /^\@(?:section|unnumbered|unnumberedsec|center)\s+(.+)$/
+       and $_ = "\n=head2 $1\n";
+    /^\@subsection\s+(.+)$/
+       and $_ = "\n=head3 $1\n";
+
+    # Block command handlers:
+    /^\@itemize\s+(\@[a-z]+|\*|-)/ and do {
+       push @endwstack, $endw;
+       push @icstack, $ic;
+       $ic = $1;
+       $_ = "\n=over 4\n";
+       $endw = "itemize";
+    };
+
+    /^\@enumerate(?:\s+([a-zA-Z0-9]+))?/ and do {
+       push @endwstack, $endw;
+       push @icstack, $ic;
+       if (defined $1) {
+           $ic = $1 . ".";
+       } else {
+           $ic = "1.";
+       }
+       $_ = "\n=over 4\n";
+       $endw = "enumerate";
+    };
+
+    /^\@([fv]?table)\s+(\@[a-z]+)/ and do {
+       push @endwstack, $endw;
+       push @icstack, $ic;
+       $endw = $1;
+       $ic = $2;
+       $ic =~ s/\@(?:samp|strong|key|gcctabopt|option|env)/B/;
+       $ic =~ s/\@(?:code|kbd)/C/;
+       $ic =~ s/\@(?:dfn|var|emph|cite|i)/I/;
+       $ic =~ s/\@(?:file)/F/;
+       $_ = "\n=over 4\n";
+    };
+
+    /^\@((?:small)?example|display)/ and do {
+       push @endwstack, $endw;
+       $endw = $1;
+       $shift = "\t";
+       $_ = "";        # need a paragraph break
+    };
+
+    /^\@itemx?\s*(.+)?$/ and do {
+       if (defined $1) {
+           # Entity escapes prevent munging by the <> processing below.
+#            print "$ic\n";
+           $_ = "\n=item $ic\&LT;$1\&GT;\n";
+       } else {
+           $_ = "\n=item $ic\n";
+           $ic =~ y/A-Ya-y/B-Zb-z/;
+           $ic =~ s/(\d+)/$1 + 1/eg;
+       }
+    };
+
+    $section .= $shift.$_."\n";
+}
+# End of current file.
+close($inf);
+$inf = pop @instack;
+}
+
+die "No filename or title\n" unless defined $fn && defined $tl;
+
+$sects{NAME} = "$fn \- $tl\n";
+$sects{FOOTNOTES} .= "=back\n" if exists $sects{FOOTNOTES};
+
+for $sect (qw(NAME SYNOPSIS DESCRIPTION OPTIONS ENVIRONMENT FILES
+             BUGS NOTES FOOTNOTES SEEALSO AUTHOR COPYRIGHT)) {
+    if(exists $sects{$sect}) {
+       $head = $sect;
+       $head =~ s/SEEALSO/SEE ALSO/;
+       print "=head1 $head\n\n";
+       print scalar unmunge ($sects{$sect});
+       print "\n";
+    }
+}
+
+sub usage
+{
+    die "usage: $0 [-D toggle...] [infile [outfile]]\n";
+}
+
+sub postprocess
+{
+    local $_ = $_[0];
+
+    # @value{foo} is replaced by whatever 'foo' is defined as.
+    while (m/(\@value\{([a-zA-Z0-9_-]+)\})/g) {
+       if (! exists $defs{$2}) {
+           print STDERR "Option $2 not defined\n";
+           s/\Q$1\E//;
+       } else {
+           $value = $defs{$2};
+           s/\Q$1\E/$value/;
+       }
+    }
+
+    # Formatting commands.
+    # Temporary escape for @r.
+    s/\@r\{([^\}]*)\}/R<$1>/g;
+    s/\@(?:dfn|var|emph|cite|i)\{([^\}]*)\}/I<$1>/g;
+    s/\@(?:code|kbd)\{([^\}]*)\}/C<$1>/g;
+    s/\@(?:gccoptlist|samp|strong|key|option|env|command|b)\{([^\}]*)\}/B<$1>/g;
+    s/\@sc\{([^\}]*)\}/\U$1/g;
+    s/\@file\{([^\}]*)\}/F<$1>/g;
+    s/\@w\{([^\}]*)\}/S<$1>/g;
+    s/\@(?:dmn|math)\{([^\}]*)\}/$1/g;
+
+    # Cross references are thrown away, as are @noindent and @refill.
+    # (@noindent is impossible in .pod, and @refill is unnecessary.)
+    # @* is also impossible in .pod; we discard it and any newline that
+    # follows it.  Similarly, our macro @gol must be discarded.
+
+    s/\(?\@xref\{(?:[^\}]*)\}(?:[^.<]|(?:<[^<>]*>))*\.\)?//g;
+    s/\s+\(\@pxref\{(?:[^\}]*)\}\)//g;
+    s/;\s+\@pxref\{(?:[^\}]*)\}//g;
+    s/\@noindent\s*//g;
+    s/\@refill//g;
+    s/\@gol//g;
+    s/\@\*\s*\n?//g;
+
+    # @uref can take one, two, or three arguments, with different
+    # semantics each time.  @url and @email are just like @uref with
+    # one argument, for our purposes.
+    s/\@(?:uref|url|email)\{([^\},]*)\}/&lt;B<$1>&gt;/g;
+    s/\@uref\{([^\},]*),([^\},]*)\}/$2 (C<$1>)/g;
+    s/\@uref\{([^\},]*),([^\},]*),([^\},]*)\}/$3/g;
+
+    # Turn B<blah I<blah> blah> into B<blah> I<blah> B<blah> to
+    # match Texinfo semantics of @emph inside @samp.  Also handle @r
+    # inside bold.
+    s/&LT;/</g;
+    s/&GT;/>/g;
+    1 while s/B<((?:[^<>]|I<[^<>]*>)*)R<([^>]*)>/B<$1>${2}B</g;
+    1 while (s/B<([^<>]*)I<([^>]+)>/B<$1>I<$2>B</g);
+    1 while (s/I<([^<>]*)B<([^>]+)>/I<$1>B<$2>I</g);
+    s/[BI]<>//g;
+    s/([BI])<(\s+)([^>]+)>/$2$1<$3>/g;
+    s/([BI])<([^>]+?)(\s+)>/$1<$2>$3/g;
+
+    # Extract footnotes.  This has to be done after all other
+    # processing because otherwise the regexp will choke on formatting
+    # inside @footnote.
+    while (/\@footnote/g) {
+       s/\@footnote\{([^\}]+)\}/[$fnno]/;
+       add_footnote($1, $fnno);
+       $fnno++;
+    }
+
+    return $_;
+}
+
+sub unmunge
+{
+    # Replace escaped symbols with their equivalents.
+    local $_ = $_[0];
+
+    s/&lt;/E<lt>/g;
+    s/&gt;/E<gt>/g;
+    s/&lbrace;/\{/g;
+    s/&rbrace;/\}/g;
+    s/&at;/\@/g;
+    s/&amp;/&/g;
+    return $_;
+}
+
+sub add_footnote
+{
+    unless (exists $sects{FOOTNOTES}) {
+       $sects{FOOTNOTES} = "\n=over 4\n\n";
+    }
+
+    $sects{FOOTNOTES} .= "=item $fnno.\n\n"; $fnno++;
+    $sects{FOOTNOTES} .= $_[0];
+    $sects{FOOTNOTES} .= "\n\n";
+}
+
+# stolen from Symbol.pm
+{
+    my $genseq = 0;
+    sub gensym
+    {
+       my $name = "GEN" . $genseq++;
+       my $ref = \*{$name};
+       delete $::{$name};
+       return $ref;
+    }
+}
diff --git a/tools/ioemu/thunk.c b/tools/ioemu/thunk.c
new file mode 100644 (file)
index 0000000..2dbc378
--- /dev/null
@@ -0,0 +1,243 @@
+/*
+ *  Generic thunking code to convert data between host and target CPU
+ * 
+ *  Copyright (c) 2003 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "qemu.h"
+#include "thunk.h"
+
+//#define DEBUG
+
+#define MAX_STRUCTS 128
+
+/* XXX: make it dynamic */
+StructEntry struct_entries[MAX_STRUCTS];
+
+static inline const argtype *thunk_type_next(const argtype *type_ptr)
+{
+    int type;
+
+    type = *type_ptr++;
+    switch(type) {
+    case TYPE_CHAR:
+    case TYPE_SHORT:
+    case TYPE_INT:
+    case TYPE_LONGLONG:
+    case TYPE_ULONGLONG:
+    case TYPE_LONG:
+    case TYPE_ULONG:
+    case TYPE_PTRVOID:
+        return type_ptr;
+    case TYPE_PTR:
+        return thunk_type_next(type_ptr);
+    case TYPE_ARRAY:
+        return thunk_type_next(type_ptr + 1);
+    case TYPE_STRUCT:
+        return type_ptr + 1;
+    default:
+        return NULL;
+    }
+}
+
+void thunk_register_struct(int id, const char *name, const argtype *types)
+{
+    const argtype *type_ptr;
+    StructEntry *se;
+    int nb_fields, offset, max_align, align, size, i, j;
+
+    se = struct_entries + id;
+    
+    /* first we count the number of fields */
+    type_ptr = types;
+    nb_fields = 0;
+    while (*type_ptr != TYPE_NULL) {
+        type_ptr = thunk_type_next(type_ptr);
+        nb_fields++;
+    }
+    se->field_types = types;
+    se->nb_fields = nb_fields;
+    se->name = name;
+#ifdef DEBUG
+    printf("struct %s: id=%d nb_fields=%d\n", 
+           se->name, id, se->nb_fields);
+#endif
+    /* now we can alloc the data */
+
+    for(i = 0;i < 2; i++) {
+        offset = 0;
+        max_align = 1;
+        se->field_offsets[i] = malloc(nb_fields * sizeof(int));
+        type_ptr = se->field_types;
+        for(j = 0;j < nb_fields; j++) {
+            size = thunk_type_size(type_ptr, i);
+            align = thunk_type_align(type_ptr, i);
+            offset = (offset + align - 1) & ~(align - 1);
+            se->field_offsets[i][j] = offset;
+            offset += size;
+            if (align > max_align)
+                max_align = align;
+            type_ptr = thunk_type_next(type_ptr);
+        }
+        offset = (offset + max_align - 1) & ~(max_align - 1);
+        se->size[i] = offset;
+        se->align[i] = max_align;
+#ifdef DEBUG
+        printf("%s: size=%d align=%d\n", 
+               i == THUNK_HOST ? "host" : "target", offset, max_align);
+#endif
+    }
+}
+
+void thunk_register_struct_direct(int id, const char *name, StructEntry *se1)
+{
+    StructEntry *se;
+    se = struct_entries + id;
+    *se = *se1;
+    se->name = name;
+}
+
+
+/* now we can define the main conversion functions */
+const argtype *thunk_convert(void *dst, const void *src, 
+                             const argtype *type_ptr, int to_host)
+{
+    int type;
+
+    type = *type_ptr++;
+    switch(type) {
+    case TYPE_CHAR:
+        *(uint8_t *)dst = *(uint8_t *)src;
+        break;
+    case TYPE_SHORT:
+        *(uint16_t *)dst = tswap16(*(uint16_t *)src);
+        break;
+    case TYPE_INT:
+        *(uint32_t *)dst = tswap32(*(uint32_t *)src);
+        break;
+    case TYPE_LONGLONG:
+    case TYPE_ULONGLONG:
+        *(uint64_t *)dst = tswap64(*(uint64_t *)src);
+        break;
+#if HOST_LONG_BITS == 32 && TARGET_LONG_BITS == 32
+    case TYPE_LONG:
+    case TYPE_ULONG:
+    case TYPE_PTRVOID:
+        *(uint32_t *)dst = tswap32(*(uint32_t *)src);
+        break;
+#elif HOST_LONG_BITS == 64 && TARGET_LONG_BITS == 32
+    case TYPE_LONG:
+    case TYPE_ULONG:
+    case TYPE_PTRVOID:
+        if (to_host) {
+            *(uint64_t *)dst = tswap32(*(uint32_t *)src);
+        } else {
+            *(uint32_t *)dst = tswap32(*(uint64_t *)src & 0xffffffff);
+        }
+        break;
+#else
+#error unsupported conversion
+#endif
+    case TYPE_ARRAY:
+        {
+            int array_length, i, dst_size, src_size;
+            const uint8_t *s;
+            uint8_t  *d;
+
+            array_length = *type_ptr++;
+            dst_size = thunk_type_size(type_ptr, to_host);
+            src_size = thunk_type_size(type_ptr, 1 - to_host);
+            d = dst;
+            s = src;
+            for(i = 0;i < array_length; i++) {
+                thunk_convert(d, s, type_ptr, to_host);
+                d += dst_size;
+                s += src_size;
+            }
+            type_ptr = thunk_type_next(type_ptr);
+        }
+        break;
+    case TYPE_STRUCT:
+        {
+            int i;
+            const StructEntry *se;
+            const uint8_t *s;
+            uint8_t  *d;
+            const argtype *field_types;
+            const int *dst_offsets, *src_offsets;
+            
+            se = struct_entries + *type_ptr++;
+            if (se->convert[0] != NULL) {
+                /* specific conversion is needed */
+                (*se->convert[to_host])(dst, src);
+            } else {
+                /* standard struct conversion */
+                field_types = se->field_types;
+                dst_offsets = se->field_offsets[to_host];
+                src_offsets = se->field_offsets[1 - to_host];
+                d = dst;
+                s = src;
+                for(i = 0;i < se->nb_fields; i++) {
+                    field_types = thunk_convert(d + dst_offsets[i], 
+                                                s + src_offsets[i], 
+                                                field_types, to_host);
+                }
+            }
+        }
+        break;
+    default:
+        fprintf(stderr, "Invalid type 0x%x\n", type);
+        break;
+    }
+    return type_ptr;
+}
+
+/* from em86 */
+
+/* Utility function: Table-driven functions to translate bitmasks
+ * between X86 and Alpha formats...
+ */
+unsigned int target_to_host_bitmask(unsigned int x86_mask, 
+                                    bitmask_transtbl * trans_tbl)
+{
+    bitmask_transtbl * btp;
+    unsigned int       alpha_mask = 0;
+
+    for(btp = trans_tbl; btp->x86_mask && btp->alpha_mask; btp++) {
+       if((x86_mask & btp->x86_mask) == btp->x86_bits) {
+           alpha_mask |= btp->alpha_bits;
+       }
+    }
+    return(alpha_mask);
+}
+
+unsigned int host_to_target_bitmask(unsigned int alpha_mask, 
+                                    bitmask_transtbl * trans_tbl)
+{
+    bitmask_transtbl * btp;
+    unsigned int       x86_mask = 0;
+
+    for(btp = trans_tbl; btp->x86_mask && btp->alpha_mask; btp++) {
+       if((alpha_mask & btp->alpha_mask) == btp->alpha_bits) {
+           x86_mask |= btp->x86_bits;
+       }
+    }
+    return(x86_mask);
+}
diff --git a/tools/ioemu/thunk.h b/tools/ioemu/thunk.h
new file mode 100644 (file)
index 0000000..42fd96f
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ *  Generic thunking code to convert data between host and target CPU
+ * 
+ *  Copyright (c) 2003 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef THUNK_H
+#define THUNK_H
+
+#include <inttypes.h>
+#include "cpu.h"
+
+/* types enums definitions */
+
+typedef enum argtype {
+    TYPE_NULL,
+    TYPE_CHAR,
+    TYPE_SHORT,
+    TYPE_INT,
+    TYPE_LONG,
+    TYPE_ULONG,
+    TYPE_PTRVOID, /* pointer on unknown data */
+    TYPE_LONGLONG,
+    TYPE_ULONGLONG,
+    TYPE_PTR,
+    TYPE_ARRAY,
+    TYPE_STRUCT,
+} argtype;
+
+#define MK_PTR(type) TYPE_PTR, type
+#define MK_ARRAY(type, size) TYPE_ARRAY, size, type
+#define MK_STRUCT(id) TYPE_STRUCT, id
+
+#define THUNK_TARGET 0
+#define THUNK_HOST   1
+
+typedef struct {
+    /* standard struct handling */
+    const argtype *field_types;
+    int nb_fields;
+    int *field_offsets[2];
+    /* special handling */
+    void (*convert[2])(void *dst, const void *src);
+    int size[2];
+    int align[2];
+    const char *name;
+} StructEntry;
+
+/* Translation table for bitmasks... */
+typedef struct bitmask_transtbl {
+       unsigned int    x86_mask;
+       unsigned int    x86_bits;
+       unsigned int    alpha_mask;
+       unsigned int    alpha_bits;
+} bitmask_transtbl;
+
+void thunk_register_struct(int id, const char *name, const argtype *types);
+void thunk_register_struct_direct(int id, const char *name, StructEntry *se1);
+const argtype *thunk_convert(void *dst, const void *src, 
+                             const argtype *type_ptr, int to_host);
+#ifndef NO_THUNK_TYPE_SIZE
+
+extern StructEntry struct_entries[];
+
+static inline int thunk_type_size(const argtype *type_ptr, int is_host)
+{
+    int type, size;
+    const StructEntry *se;
+
+    type = *type_ptr;
+    switch(type) {
+    case TYPE_CHAR:
+        return 1;
+    case TYPE_SHORT:
+        return 2;
+    case TYPE_INT:
+        return 4;
+    case TYPE_LONGLONG:
+    case TYPE_ULONGLONG:
+        return 8;
+    case TYPE_LONG:
+    case TYPE_ULONG:
+    case TYPE_PTRVOID:
+    case TYPE_PTR:
+        if (is_host) {
+            return HOST_LONG_SIZE;
+        } else {
+            return TARGET_LONG_SIZE;
+        }
+        break;
+    case TYPE_ARRAY:
+        size = type_ptr[1];
+        return size * thunk_type_size(type_ptr + 2, is_host);
+    case TYPE_STRUCT:
+        se = struct_entries + type_ptr[1];
+        return se->size[is_host];
+    default:
+        return -1;
+    }
+}
+
+static inline int thunk_type_align(const argtype *type_ptr, int is_host)
+{
+    int type;
+    const StructEntry *se;
+
+    type = *type_ptr;
+    switch(type) {
+    case TYPE_CHAR:
+        return 1;
+    case TYPE_SHORT:
+        return 2;
+    case TYPE_INT:
+        return 4;
+    case TYPE_LONGLONG:
+    case TYPE_ULONGLONG:
+        return 8;
+    case TYPE_LONG:
+    case TYPE_ULONG:
+    case TYPE_PTRVOID:
+    case TYPE_PTR:
+        if (is_host) {
+            return HOST_LONG_SIZE;
+        } else {
+            return TARGET_LONG_SIZE;
+        }
+        break;
+    case TYPE_ARRAY:
+        return thunk_type_align(type_ptr + 2, is_host);
+    case TYPE_STRUCT:
+        se = struct_entries + type_ptr[1];
+        return se->align[is_host];
+    default:
+        return -1;
+    }
+}
+
+#endif /* NO_THUNK_TYPE_SIZE */
+
+unsigned int target_to_host_bitmask(unsigned int x86_mask, 
+                                    bitmask_transtbl * trans_tbl);
+unsigned int host_to_target_bitmask(unsigned int alpha_mask, 
+                                    bitmask_transtbl * trans_tbl);
+
+#endif
diff --git a/tools/ioemu/vgafont.h b/tools/ioemu/vgafont.h
new file mode 100644 (file)
index 0000000..bb75796
--- /dev/null
@@ -0,0 +1,4611 @@
+static uint8_t vgafont16[256 * 16] = {
+
+       /* 0 0x00 '^@' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 1 0x01 '^A' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7e, /* 01111110 */
+       0x81, /* 10000001 */
+       0xa5, /* 10100101 */
+       0x81, /* 10000001 */
+       0x81, /* 10000001 */
+       0xbd, /* 10111101 */
+       0x99, /* 10011001 */
+       0x81, /* 10000001 */
+       0x81, /* 10000001 */
+       0x7e, /* 01111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 2 0x02 '^B' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7e, /* 01111110 */
+       0xff, /* 11111111 */
+       0xdb, /* 11011011 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xc3, /* 11000011 */
+       0xe7, /* 11100111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0x7e, /* 01111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 3 0x03 '^C' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x6c, /* 01101100 */
+       0xfe, /* 11111110 */
+       0xfe, /* 11111110 */
+       0xfe, /* 11111110 */
+       0xfe, /* 11111110 */
+       0x7c, /* 01111100 */
+       0x38, /* 00111000 */
+       0x10, /* 00010000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 4 0x04 '^D' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x10, /* 00010000 */
+       0x38, /* 00111000 */
+       0x7c, /* 01111100 */
+       0xfe, /* 11111110 */
+       0x7c, /* 01111100 */
+       0x38, /* 00111000 */
+       0x10, /* 00010000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 5 0x05 '^E' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x3c, /* 00111100 */
+       0xe7, /* 11100111 */
+       0xe7, /* 11100111 */
+       0xe7, /* 11100111 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 6 0x06 '^F' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x7e, /* 01111110 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0x7e, /* 01111110 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 7 0x07 '^G' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x3c, /* 00111100 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 8 0x08 '^H' */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xe7, /* 11100111 */
+       0xc3, /* 11000011 */
+       0xc3, /* 11000011 */
+       0xe7, /* 11100111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+
+       /* 9 0x09 '^I' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x3c, /* 00111100 */
+       0x66, /* 01100110 */
+       0x42, /* 01000010 */
+       0x42, /* 01000010 */
+       0x66, /* 01100110 */
+       0x3c, /* 00111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 10 0x0a '^J' */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xc3, /* 11000011 */
+       0x99, /* 10011001 */
+       0xbd, /* 10111101 */
+       0xbd, /* 10111101 */
+       0x99, /* 10011001 */
+       0xc3, /* 11000011 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+
+       /* 11 0x0b '^K' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x1e, /* 00011110 */
+       0x0e, /* 00001110 */
+       0x1a, /* 00011010 */
+       0x32, /* 00110010 */
+       0x78, /* 01111000 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0x78, /* 01111000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 12 0x0c '^L' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x3c, /* 00111100 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x3c, /* 00111100 */
+       0x18, /* 00011000 */
+       0x7e, /* 01111110 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 13 0x0d '^M' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x3f, /* 00111111 */
+       0x33, /* 00110011 */
+       0x3f, /* 00111111 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x70, /* 01110000 */
+       0xf0, /* 11110000 */
+       0xe0, /* 11100000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 14 0x0e '^N' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7f, /* 01111111 */
+       0x63, /* 01100011 */
+       0x7f, /* 01111111 */
+       0x63, /* 01100011 */
+       0x63, /* 01100011 */
+       0x63, /* 01100011 */
+       0x63, /* 01100011 */
+       0x67, /* 01100111 */
+       0xe7, /* 11100111 */
+       0xe6, /* 11100110 */
+       0xc0, /* 11000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 15 0x0f '^O' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0xdb, /* 11011011 */
+       0x3c, /* 00111100 */
+       0xe7, /* 11100111 */
+       0x3c, /* 00111100 */
+       0xdb, /* 11011011 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 16 0x10 '^P' */
+       0x00, /* 00000000 */
+       0x80, /* 10000000 */
+       0xc0, /* 11000000 */
+       0xe0, /* 11100000 */
+       0xf0, /* 11110000 */
+       0xf8, /* 11111000 */
+       0xfe, /* 11111110 */
+       0xf8, /* 11111000 */
+       0xf0, /* 11110000 */
+       0xe0, /* 11100000 */
+       0xc0, /* 11000000 */
+       0x80, /* 10000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 17 0x11 '^Q' */
+       0x00, /* 00000000 */
+       0x02, /* 00000010 */
+       0x06, /* 00000110 */
+       0x0e, /* 00001110 */
+       0x1e, /* 00011110 */
+       0x3e, /* 00111110 */
+       0xfe, /* 11111110 */
+       0x3e, /* 00111110 */
+       0x1e, /* 00011110 */
+       0x0e, /* 00001110 */
+       0x06, /* 00000110 */
+       0x02, /* 00000010 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 18 0x12 '^R' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x7e, /* 01111110 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x7e, /* 01111110 */
+       0x3c, /* 00111100 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 19 0x13 '^S' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x00, /* 00000000 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 20 0x14 '^T' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7f, /* 01111111 */
+       0xdb, /* 11011011 */
+       0xdb, /* 11011011 */
+       0xdb, /* 11011011 */
+       0x7b, /* 01111011 */
+       0x1b, /* 00011011 */
+       0x1b, /* 00011011 */
+       0x1b, /* 00011011 */
+       0x1b, /* 00011011 */
+       0x1b, /* 00011011 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 21 0x15 '^U' */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0x60, /* 01100000 */
+       0x38, /* 00111000 */
+       0x6c, /* 01101100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x6c, /* 01101100 */
+       0x38, /* 00111000 */
+       0x0c, /* 00001100 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 22 0x16 '^V' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfe, /* 11111110 */
+       0xfe, /* 11111110 */
+       0xfe, /* 11111110 */
+       0xfe, /* 11111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 23 0x17 '^W' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x7e, /* 01111110 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x7e, /* 01111110 */
+       0x3c, /* 00111100 */
+       0x18, /* 00011000 */
+       0x7e, /* 01111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 24 0x18 '^X' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x7e, /* 01111110 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 25 0x19 '^Y' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x7e, /* 01111110 */
+       0x3c, /* 00111100 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 26 0x1a '^Z' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x0c, /* 00001100 */
+       0xfe, /* 11111110 */
+       0x0c, /* 00001100 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 27 0x1b '^[' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x30, /* 00110000 */
+       0x60, /* 01100000 */
+       0xfe, /* 11111110 */
+       0x60, /* 01100000 */
+       0x30, /* 00110000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 28 0x1c '^\' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xfe, /* 11111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 29 0x1d '^]' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x28, /* 00101000 */
+       0x6c, /* 01101100 */
+       0xfe, /* 11111110 */
+       0x6c, /* 01101100 */
+       0x28, /* 00101000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 30 0x1e '^^' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x10, /* 00010000 */
+       0x38, /* 00111000 */
+       0x38, /* 00111000 */
+       0x7c, /* 01111100 */
+       0x7c, /* 01111100 */
+       0xfe, /* 11111110 */
+       0xfe, /* 11111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 31 0x1f '^_' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfe, /* 11111110 */
+       0xfe, /* 11111110 */
+       0x7c, /* 01111100 */
+       0x7c, /* 01111100 */
+       0x38, /* 00111000 */
+       0x38, /* 00111000 */
+       0x10, /* 00010000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 32 0x20 ' ' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 33 0x21 '!' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x3c, /* 00111100 */
+       0x3c, /* 00111100 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 34 0x22 '"' */
+       0x00, /* 00000000 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x24, /* 00100100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 35 0x23 '#' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x6c, /* 01101100 */
+       0x6c, /* 01101100 */
+       0xfe, /* 11111110 */
+       0x6c, /* 01101100 */
+       0x6c, /* 01101100 */
+       0x6c, /* 01101100 */
+       0xfe, /* 11111110 */
+       0x6c, /* 01101100 */
+       0x6c, /* 01101100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 36 0x24 '$' */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xc2, /* 11000010 */
+       0xc0, /* 11000000 */
+       0x7c, /* 01111100 */
+       0x06, /* 00000110 */
+       0x06, /* 00000110 */
+       0x86, /* 10000110 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 37 0x25 '%' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xc2, /* 11000010 */
+       0xc6, /* 11000110 */
+       0x0c, /* 00001100 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x60, /* 01100000 */
+       0xc6, /* 11000110 */
+       0x86, /* 10000110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 38 0x26 '&' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x38, /* 00111000 */
+       0x6c, /* 01101100 */
+       0x6c, /* 01101100 */
+       0x38, /* 00111000 */
+       0x76, /* 01110110 */
+       0xdc, /* 11011100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0x76, /* 01110110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 39 0x27 ''' */
+       0x00, /* 00000000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x60, /* 01100000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 40 0x28 '(' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x0c, /* 00001100 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x18, /* 00011000 */
+       0x0c, /* 00001100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 41 0x29 ')' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x30, /* 00110000 */
+       0x18, /* 00011000 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 42 0x2a '*' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x66, /* 01100110 */
+       0x3c, /* 00111100 */
+       0xff, /* 11111111 */
+       0x3c, /* 00111100 */
+       0x66, /* 01100110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 43 0x2b '+' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x7e, /* 01111110 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 44 0x2c ',' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 45 0x2d '-' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfe, /* 11111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 46 0x2e '.' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 47 0x2f '/' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x02, /* 00000010 */
+       0x06, /* 00000110 */
+       0x0c, /* 00001100 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x60, /* 01100000 */
+       0xc0, /* 11000000 */
+       0x80, /* 10000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 48 0x30 '0' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x38, /* 00111000 */
+       0x6c, /* 01101100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xd6, /* 11010110 */
+       0xd6, /* 11010110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x6c, /* 01101100 */
+       0x38, /* 00111000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 49 0x31 '1' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x38, /* 00111000 */
+       0x78, /* 01111000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x7e, /* 01111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 50 0x32 '2' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0x06, /* 00000110 */
+       0x0c, /* 00001100 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x60, /* 01100000 */
+       0xc0, /* 11000000 */
+       0xc6, /* 11000110 */
+       0xfe, /* 11111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 51 0x33 '3' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0x06, /* 00000110 */
+       0x06, /* 00000110 */
+       0x3c, /* 00111100 */
+       0x06, /* 00000110 */
+       0x06, /* 00000110 */
+       0x06, /* 00000110 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 52 0x34 '4' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x0c, /* 00001100 */
+       0x1c, /* 00011100 */
+       0x3c, /* 00111100 */
+       0x6c, /* 01101100 */
+       0xcc, /* 11001100 */
+       0xfe, /* 11111110 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x1e, /* 00011110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 53 0x35 '5' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfe, /* 11111110 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xfc, /* 11111100 */
+       0x06, /* 00000110 */
+       0x06, /* 00000110 */
+       0x06, /* 00000110 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 54 0x36 '6' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x38, /* 00111000 */
+       0x60, /* 01100000 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xfc, /* 11111100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 55 0x37 '7' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfe, /* 11111110 */
+       0xc6, /* 11000110 */
+       0x06, /* 00000110 */
+       0x06, /* 00000110 */
+       0x0c, /* 00001100 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 56 0x38 '8' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 57 0x39 '9' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x7e, /* 01111110 */
+       0x06, /* 00000110 */
+       0x06, /* 00000110 */
+       0x06, /* 00000110 */
+       0x0c, /* 00001100 */
+       0x78, /* 01111000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 58 0x3a ':' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 59 0x3b ';' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 60 0x3c '<' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x06, /* 00000110 */
+       0x0c, /* 00001100 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x60, /* 01100000 */
+       0x30, /* 00110000 */
+       0x18, /* 00011000 */
+       0x0c, /* 00001100 */
+       0x06, /* 00000110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 61 0x3d '=' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7e, /* 01111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7e, /* 01111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 62 0x3e '>' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x60, /* 01100000 */
+       0x30, /* 00110000 */
+       0x18, /* 00011000 */
+       0x0c, /* 00001100 */
+       0x06, /* 00000110 */
+       0x0c, /* 00001100 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x60, /* 01100000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 63 0x3f '?' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x0c, /* 00001100 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 64 0x40 '@' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xde, /* 11011110 */
+       0xde, /* 11011110 */
+       0xde, /* 11011110 */
+       0xdc, /* 11011100 */
+       0xc0, /* 11000000 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 65 0x41 'A' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x10, /* 00010000 */
+       0x38, /* 00111000 */
+       0x6c, /* 01101100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xfe, /* 11111110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 66 0x42 'B' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfc, /* 11111100 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x7c, /* 01111100 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0xfc, /* 11111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 67 0x43 'C' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x3c, /* 00111100 */
+       0x66, /* 01100110 */
+       0xc2, /* 11000010 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc2, /* 11000010 */
+       0x66, /* 01100110 */
+       0x3c, /* 00111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 68 0x44 'D' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xf8, /* 11111000 */
+       0x6c, /* 01101100 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x6c, /* 01101100 */
+       0xf8, /* 11111000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 69 0x45 'E' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfe, /* 11111110 */
+       0x66, /* 01100110 */
+       0x62, /* 01100010 */
+       0x68, /* 01101000 */
+       0x78, /* 01111000 */
+       0x68, /* 01101000 */
+       0x60, /* 01100000 */
+       0x62, /* 01100010 */
+       0x66, /* 01100110 */
+       0xfe, /* 11111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 70 0x46 'F' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfe, /* 11111110 */
+       0x66, /* 01100110 */
+       0x62, /* 01100010 */
+       0x68, /* 01101000 */
+       0x78, /* 01111000 */
+       0x68, /* 01101000 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0xf0, /* 11110000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 71 0x47 'G' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x3c, /* 00111100 */
+       0x66, /* 01100110 */
+       0xc2, /* 11000010 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xde, /* 11011110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x66, /* 01100110 */
+       0x3a, /* 00111010 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 72 0x48 'H' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xfe, /* 11111110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 73 0x49 'I' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x3c, /* 00111100 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 74 0x4a 'J' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x1e, /* 00011110 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0x78, /* 01111000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 75 0x4b 'K' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xe6, /* 11100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x6c, /* 01101100 */
+       0x78, /* 01111000 */
+       0x78, /* 01111000 */
+       0x6c, /* 01101100 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0xe6, /* 11100110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 76 0x4c 'L' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xf0, /* 11110000 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0x62, /* 01100010 */
+       0x66, /* 01100110 */
+       0xfe, /* 11111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 77 0x4d 'M' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xc6, /* 11000110 */
+       0xee, /* 11101110 */
+       0xfe, /* 11111110 */
+       0xfe, /* 11111110 */
+       0xd6, /* 11010110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 78 0x4e 'N' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xc6, /* 11000110 */
+       0xe6, /* 11100110 */
+       0xf6, /* 11110110 */
+       0xfe, /* 11111110 */
+       0xde, /* 11011110 */
+       0xce, /* 11001110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 79 0x4f 'O' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 80 0x50 'P' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfc, /* 11111100 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x7c, /* 01111100 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0xf0, /* 11110000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 81 0x51 'Q' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xd6, /* 11010110 */
+       0xde, /* 11011110 */
+       0x7c, /* 01111100 */
+       0x0c, /* 00001100 */
+       0x0e, /* 00001110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 82 0x52 'R' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfc, /* 11111100 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x7c, /* 01111100 */
+       0x6c, /* 01101100 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0xe6, /* 11100110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 83 0x53 'S' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x60, /* 01100000 */
+       0x38, /* 00111000 */
+       0x0c, /* 00001100 */
+       0x06, /* 00000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 84 0x54 'T' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7e, /* 01111110 */
+       0x7e, /* 01111110 */
+       0x5a, /* 01011010 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 85 0x55 'U' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 86 0x56 'V' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x6c, /* 01101100 */
+       0x38, /* 00111000 */
+       0x10, /* 00010000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 87 0x57 'W' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xd6, /* 11010110 */
+       0xd6, /* 11010110 */
+       0xd6, /* 11010110 */
+       0xfe, /* 11111110 */
+       0xee, /* 11101110 */
+       0x6c, /* 01101100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 88 0x58 'X' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x6c, /* 01101100 */
+       0x7c, /* 01111100 */
+       0x38, /* 00111000 */
+       0x38, /* 00111000 */
+       0x7c, /* 01111100 */
+       0x6c, /* 01101100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 89 0x59 'Y' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x3c, /* 00111100 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 90 0x5a 'Z' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfe, /* 11111110 */
+       0xc6, /* 11000110 */
+       0x86, /* 10000110 */
+       0x0c, /* 00001100 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x60, /* 01100000 */
+       0xc2, /* 11000010 */
+       0xc6, /* 11000110 */
+       0xfe, /* 11111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 91 0x5b '[' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x3c, /* 00111100 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x3c, /* 00111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 92 0x5c '\' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x80, /* 10000000 */
+       0xc0, /* 11000000 */
+       0xe0, /* 11100000 */
+       0x70, /* 01110000 */
+       0x38, /* 00111000 */
+       0x1c, /* 00011100 */
+       0x0e, /* 00001110 */
+       0x06, /* 00000110 */
+       0x02, /* 00000010 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 93 0x5d ']' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x3c, /* 00111100 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x3c, /* 00111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 94 0x5e '^' */
+       0x10, /* 00010000 */
+       0x38, /* 00111000 */
+       0x6c, /* 01101100 */
+       0xc6, /* 11000110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 95 0x5f '_' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xff, /* 11111111 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 96 0x60 '`' */
+       0x00, /* 00000000 */
+       0x30, /* 00110000 */
+       0x18, /* 00011000 */
+       0x0c, /* 00001100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 97 0x61 'a' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x78, /* 01111000 */
+       0x0c, /* 00001100 */
+       0x7c, /* 01111100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0x76, /* 01110110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 98 0x62 'b' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xe0, /* 11100000 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0x78, /* 01111000 */
+       0x6c, /* 01101100 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 99 0x63 'c' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 100 0x64 'd' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x1c, /* 00011100 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x3c, /* 00111100 */
+       0x6c, /* 01101100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0x76, /* 01110110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 101 0x65 'e' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xfe, /* 11111110 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 102 0x66 'f' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x1c, /* 00011100 */
+       0x36, /* 00110110 */
+       0x32, /* 00110010 */
+       0x30, /* 00110000 */
+       0x78, /* 01111000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x78, /* 01111000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 103 0x67 'g' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x76, /* 01110110 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0x7c, /* 01111100 */
+       0x0c, /* 00001100 */
+       0xcc, /* 11001100 */
+       0x78, /* 01111000 */
+       0x00, /* 00000000 */
+
+       /* 104 0x68 'h' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xe0, /* 11100000 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0x6c, /* 01101100 */
+       0x76, /* 01110110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0xe6, /* 11100110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 105 0x69 'i' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x38, /* 00111000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 106 0x6a 'j' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x06, /* 00000110 */
+       0x06, /* 00000110 */
+       0x00, /* 00000000 */
+       0x0e, /* 00001110 */
+       0x06, /* 00000110 */
+       0x06, /* 00000110 */
+       0x06, /* 00000110 */
+       0x06, /* 00000110 */
+       0x06, /* 00000110 */
+       0x06, /* 00000110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x3c, /* 00111100 */
+       0x00, /* 00000000 */
+
+       /* 107 0x6b 'k' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xe0, /* 11100000 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0x66, /* 01100110 */
+       0x6c, /* 01101100 */
+       0x78, /* 01111000 */
+       0x78, /* 01111000 */
+       0x6c, /* 01101100 */
+       0x66, /* 01100110 */
+       0xe6, /* 11100110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 108 0x6c 'l' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x38, /* 00111000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 109 0x6d 'm' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xec, /* 11101100 */
+       0xfe, /* 11111110 */
+       0xd6, /* 11010110 */
+       0xd6, /* 11010110 */
+       0xd6, /* 11010110 */
+       0xd6, /* 11010110 */
+       0xc6, /* 11000110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 110 0x6e 'n' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xdc, /* 11011100 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 111 0x6f 'o' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 112 0x70 'p' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xdc, /* 11011100 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x7c, /* 01111100 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0xf0, /* 11110000 */
+       0x00, /* 00000000 */
+
+       /* 113 0x71 'q' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x76, /* 01110110 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0x7c, /* 01111100 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x1e, /* 00011110 */
+       0x00, /* 00000000 */
+
+       /* 114 0x72 'r' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xdc, /* 11011100 */
+       0x76, /* 01110110 */
+       0x66, /* 01100110 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0xf0, /* 11110000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 115 0x73 's' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0x60, /* 01100000 */
+       0x38, /* 00111000 */
+       0x0c, /* 00001100 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 116 0x74 't' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x10, /* 00010000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0xfc, /* 11111100 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x36, /* 00110110 */
+       0x1c, /* 00011100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 117 0x75 'u' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0x76, /* 01110110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 118 0x76 'v' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x6c, /* 01101100 */
+       0x38, /* 00111000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 119 0x77 'w' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xd6, /* 11010110 */
+       0xd6, /* 11010110 */
+       0xd6, /* 11010110 */
+       0xfe, /* 11111110 */
+       0x6c, /* 01101100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 120 0x78 'x' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xc6, /* 11000110 */
+       0x6c, /* 01101100 */
+       0x38, /* 00111000 */
+       0x38, /* 00111000 */
+       0x38, /* 00111000 */
+       0x6c, /* 01101100 */
+       0xc6, /* 11000110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 121 0x79 'y' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x7e, /* 01111110 */
+       0x06, /* 00000110 */
+       0x0c, /* 00001100 */
+       0xf8, /* 11111000 */
+       0x00, /* 00000000 */
+
+       /* 122 0x7a 'z' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfe, /* 11111110 */
+       0xcc, /* 11001100 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x60, /* 01100000 */
+       0xc6, /* 11000110 */
+       0xfe, /* 11111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 123 0x7b '{' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x0e, /* 00001110 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x70, /* 01110000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x0e, /* 00001110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 124 0x7c '|' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 125 0x7d '}' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x70, /* 01110000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x0e, /* 00001110 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x70, /* 01110000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 126 0x7e '~' */
+       0x00, /* 00000000 */
+       0x76, /* 01110110 */
+       0xdc, /* 11011100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 127 0x7f '\7f' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x10, /* 00010000 */
+       0x38, /* 00111000 */
+       0x6c, /* 01101100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xfe, /* 11111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 128 0x80 '\80' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x3c, /* 00111100 */
+       0x66, /* 01100110 */
+       0xc2, /* 11000010 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc2, /* 11000010 */
+       0x66, /* 01100110 */
+       0x3c, /* 00111100 */
+       0x18, /* 00011000 */
+       0x70, /* 01110000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 129 0x81 '\81' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xcc, /* 11001100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0x76, /* 01110110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 130 0x82 '\82' */
+       0x00, /* 00000000 */
+       0x0c, /* 00001100 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xfe, /* 11111110 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 131 0x83 '\83' */
+       0x00, /* 00000000 */
+       0x10, /* 00010000 */
+       0x38, /* 00111000 */
+       0x6c, /* 01101100 */
+       0x00, /* 00000000 */
+       0x78, /* 01111000 */
+       0x0c, /* 00001100 */
+       0x7c, /* 01111100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0x76, /* 01110110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 132 0x84 '\84' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xcc, /* 11001100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x78, /* 01111000 */
+       0x0c, /* 00001100 */
+       0x7c, /* 01111100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0x76, /* 01110110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 133 0x85 '\85' */
+       0x00, /* 00000000 */
+       0x60, /* 01100000 */
+       0x30, /* 00110000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x78, /* 01111000 */
+       0x0c, /* 00001100 */
+       0x7c, /* 01111100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0x76, /* 01110110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 134 0x86 '\86' */
+       0x00, /* 00000000 */
+       0x38, /* 00111000 */
+       0x6c, /* 01101100 */
+       0x38, /* 00111000 */
+       0x00, /* 00000000 */
+       0x78, /* 01111000 */
+       0x0c, /* 00001100 */
+       0x7c, /* 01111100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0x76, /* 01110110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 135 0x87 '\87' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x18, /* 00011000 */
+       0x70, /* 01110000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 136 0x88 '\88' */
+       0x00, /* 00000000 */
+       0x10, /* 00010000 */
+       0x38, /* 00111000 */
+       0x6c, /* 01101100 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xfe, /* 11111110 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 137 0x89 '\89' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xc6, /* 11000110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xfe, /* 11111110 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 138 0x8a '\8a' */
+       0x00, /* 00000000 */
+       0x60, /* 01100000 */
+       0x30, /* 00110000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xfe, /* 11111110 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 139 0x8b '\8b' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x66, /* 01100110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x38, /* 00111000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 140 0x8c '\8c' */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x66, /* 01100110 */
+       0x00, /* 00000000 */
+       0x38, /* 00111000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 141 0x8d '\8d' */
+       0x00, /* 00000000 */
+       0x60, /* 01100000 */
+       0x30, /* 00110000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x38, /* 00111000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 142 0x8e '\8e' */
+       0x00, /* 00000000 */
+       0xc6, /* 11000110 */
+       0x00, /* 00000000 */
+       0x10, /* 00010000 */
+       0x38, /* 00111000 */
+       0x6c, /* 01101100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xfe, /* 11111110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 143 0x8f '\8f' */
+       0x38, /* 00111000 */
+       0x6c, /* 01101100 */
+       0x38, /* 00111000 */
+       0x10, /* 00010000 */
+       0x38, /* 00111000 */
+       0x6c, /* 01101100 */
+       0xc6, /* 11000110 */
+       0xfe, /* 11111110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 144 0x90 '\90' */
+       0x0c, /* 00001100 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0xfe, /* 11111110 */
+       0x66, /* 01100110 */
+       0x62, /* 01100010 */
+       0x68, /* 01101000 */
+       0x78, /* 01111000 */
+       0x68, /* 01101000 */
+       0x62, /* 01100010 */
+       0x66, /* 01100110 */
+       0xfe, /* 11111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 145 0x91 '\91' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xec, /* 11101100 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x7e, /* 01111110 */
+       0xd8, /* 11011000 */
+       0xd8, /* 11011000 */
+       0x6e, /* 01101110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 146 0x92 '\92' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x3e, /* 00111110 */
+       0x6c, /* 01101100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xfe, /* 11111110 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xce, /* 11001110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 147 0x93 '\93' */
+       0x00, /* 00000000 */
+       0x10, /* 00010000 */
+       0x38, /* 00111000 */
+       0x6c, /* 01101100 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 148 0x94 '\94' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xc6, /* 11000110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 149 0x95 '\95' */
+       0x00, /* 00000000 */
+       0x60, /* 01100000 */
+       0x30, /* 00110000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 150 0x96 '\96' */
+       0x00, /* 00000000 */
+       0x30, /* 00110000 */
+       0x78, /* 01111000 */
+       0xcc, /* 11001100 */
+       0x00, /* 00000000 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0x76, /* 01110110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 151 0x97 '\97' */
+       0x00, /* 00000000 */
+       0x60, /* 01100000 */
+       0x30, /* 00110000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0x76, /* 01110110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 152 0x98 '\98' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xc6, /* 11000110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x7e, /* 01111110 */
+       0x06, /* 00000110 */
+       0x0c, /* 00001100 */
+       0x78, /* 01111000 */
+       0x00, /* 00000000 */
+
+       /* 153 0x99 '\99' */
+       0x00, /* 00000000 */
+       0xc6, /* 11000110 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 154 0x9a '\9a' */
+       0x00, /* 00000000 */
+       0xc6, /* 11000110 */
+       0x00, /* 00000000 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 155 0x9b '\9b' */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 156 0x9c '\9c' */
+       0x00, /* 00000000 */
+       0x38, /* 00111000 */
+       0x6c, /* 01101100 */
+       0x64, /* 01100100 */
+       0x60, /* 01100000 */
+       0xf0, /* 11110000 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0xe6, /* 11100110 */
+       0xfc, /* 11111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 157 0x9d '\9d' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x3c, /* 00111100 */
+       0x18, /* 00011000 */
+       0x7e, /* 01111110 */
+       0x18, /* 00011000 */
+       0x7e, /* 01111110 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 158 0x9e '\9e' */
+       0x00, /* 00000000 */
+       0xf8, /* 11111000 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xf8, /* 11111000 */
+       0xc4, /* 11000100 */
+       0xcc, /* 11001100 */
+       0xde, /* 11011110 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xc6, /* 11000110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 159 0x9f '\9f' */
+       0x00, /* 00000000 */
+       0x0e, /* 00001110 */
+       0x1b, /* 00011011 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x7e, /* 01111110 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0xd8, /* 11011000 */
+       0x70, /* 01110000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 160 0xa0 ' ' */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x60, /* 01100000 */
+       0x00, /* 00000000 */
+       0x78, /* 01111000 */
+       0x0c, /* 00001100 */
+       0x7c, /* 01111100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0x76, /* 01110110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 161 0xa1 '¡' */
+       0x00, /* 00000000 */
+       0x0c, /* 00001100 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x00, /* 00000000 */
+       0x38, /* 00111000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 162 0xa2 '¢' */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x60, /* 01100000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 163 0xa3 '£' */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x60, /* 01100000 */
+       0x00, /* 00000000 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0x76, /* 01110110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 164 0xa4 '¤' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x76, /* 01110110 */
+       0xdc, /* 11011100 */
+       0x00, /* 00000000 */
+       0xdc, /* 11011100 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 165 0xa5 '¥' */
+       0x76, /* 01110110 */
+       0xdc, /* 11011100 */
+       0x00, /* 00000000 */
+       0xc6, /* 11000110 */
+       0xe6, /* 11100110 */
+       0xf6, /* 11110110 */
+       0xfe, /* 11111110 */
+       0xde, /* 11011110 */
+       0xce, /* 11001110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 166 0xa6 '¦' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x3c, /* 00111100 */
+       0x6c, /* 01101100 */
+       0x6c, /* 01101100 */
+       0x3e, /* 00111110 */
+       0x00, /* 00000000 */
+       0x7e, /* 01111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 167 0xa7 '§' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x38, /* 00111000 */
+       0x6c, /* 01101100 */
+       0x6c, /* 01101100 */
+       0x38, /* 00111000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 168 0xa8 '¨' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x00, /* 00000000 */
+       0x30, /* 00110000 */
+       0x30, /* 00110000 */
+       0x60, /* 01100000 */
+       0xc0, /* 11000000 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x7c, /* 01111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 169 0xa9 '©' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfe, /* 11111110 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 170 0xaa 'ª' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfe, /* 11111110 */
+       0x06, /* 00000110 */
+       0x06, /* 00000110 */
+       0x06, /* 00000110 */
+       0x06, /* 00000110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 171 0xab '«' */
+       0x00, /* 00000000 */
+       0x60, /* 01100000 */
+       0xe0, /* 11100000 */
+       0x62, /* 01100010 */
+       0x66, /* 01100110 */
+       0x6c, /* 01101100 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x60, /* 01100000 */
+       0xdc, /* 11011100 */
+       0x86, /* 10000110 */
+       0x0c, /* 00001100 */
+       0x18, /* 00011000 */
+       0x3e, /* 00111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 172 0xac '¬' */
+       0x00, /* 00000000 */
+       0x60, /* 01100000 */
+       0xe0, /* 11100000 */
+       0x62, /* 01100010 */
+       0x66, /* 01100110 */
+       0x6c, /* 01101100 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x66, /* 01100110 */
+       0xce, /* 11001110 */
+       0x9a, /* 10011010 */
+       0x3f, /* 00111111 */
+       0x06, /* 00000110 */
+       0x06, /* 00000110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 173 0xad '­' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x3c, /* 00111100 */
+       0x3c, /* 00111100 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 174 0xae '®' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x36, /* 00110110 */
+       0x6c, /* 01101100 */
+       0xd8, /* 11011000 */
+       0x6c, /* 01101100 */
+       0x36, /* 00110110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 175 0xaf '¯' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xd8, /* 11011000 */
+       0x6c, /* 01101100 */
+       0x36, /* 00110110 */
+       0x6c, /* 01101100 */
+       0xd8, /* 11011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 176 0xb0 '°' */
+       0x11, /* 00010001 */
+       0x44, /* 01000100 */
+       0x11, /* 00010001 */
+       0x44, /* 01000100 */
+       0x11, /* 00010001 */
+       0x44, /* 01000100 */
+       0x11, /* 00010001 */
+       0x44, /* 01000100 */
+       0x11, /* 00010001 */
+       0x44, /* 01000100 */
+       0x11, /* 00010001 */
+       0x44, /* 01000100 */
+       0x11, /* 00010001 */
+       0x44, /* 01000100 */
+       0x11, /* 00010001 */
+       0x44, /* 01000100 */
+
+       /* 177 0xb1 '±' */
+       0x55, /* 01010101 */
+       0xaa, /* 10101010 */
+       0x55, /* 01010101 */
+       0xaa, /* 10101010 */
+       0x55, /* 01010101 */
+       0xaa, /* 10101010 */
+       0x55, /* 01010101 */
+       0xaa, /* 10101010 */
+       0x55, /* 01010101 */
+       0xaa, /* 10101010 */
+       0x55, /* 01010101 */
+       0xaa, /* 10101010 */
+       0x55, /* 01010101 */
+       0xaa, /* 10101010 */
+       0x55, /* 01010101 */
+       0xaa, /* 10101010 */
+
+       /* 178 0xb2 '²' */
+       0xdd, /* 11011101 */
+       0x77, /* 01110111 */
+       0xdd, /* 11011101 */
+       0x77, /* 01110111 */
+       0xdd, /* 11011101 */
+       0x77, /* 01110111 */
+       0xdd, /* 11011101 */
+       0x77, /* 01110111 */
+       0xdd, /* 11011101 */
+       0x77, /* 01110111 */
+       0xdd, /* 11011101 */
+       0x77, /* 01110111 */
+       0xdd, /* 11011101 */
+       0x77, /* 01110111 */
+       0xdd, /* 11011101 */
+       0x77, /* 01110111 */
+
+       /* 179 0xb3 '³' */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+
+       /* 180 0xb4 '´' */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0xf8, /* 11111000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+
+       /* 181 0xb5 'µ' */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0xf8, /* 11111000 */
+       0x18, /* 00011000 */
+       0xf8, /* 11111000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+
+       /* 182 0xb6 '¶' */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0xf6, /* 11110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+
+       /* 183 0xb7 '·' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfe, /* 11111110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+
+       /* 184 0xb8 '¸' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xf8, /* 11111000 */
+       0x18, /* 00011000 */
+       0xf8, /* 11111000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+
+       /* 185 0xb9 '¹' */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0xf6, /* 11110110 */
+       0x06, /* 00000110 */
+       0xf6, /* 11110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+
+       /* 186 0xba 'º' */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+
+       /* 187 0xbb '»' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfe, /* 11111110 */
+       0x06, /* 00000110 */
+       0xf6, /* 11110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+
+       /* 188 0xbc '¼' */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0xf6, /* 11110110 */
+       0x06, /* 00000110 */
+       0xfe, /* 11111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 189 0xbd '½' */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0xfe, /* 11111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 190 0xbe '¾' */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0xf8, /* 11111000 */
+       0x18, /* 00011000 */
+       0xf8, /* 11111000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 191 0xbf '¿' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xf8, /* 11111000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+
+       /* 192 0xc0 'À' */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x1f, /* 00011111 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 193 0xc1 'Á' */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0xff, /* 11111111 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 194 0xc2 'Â' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xff, /* 11111111 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+
+       /* 195 0xc3 'Ã' */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x1f, /* 00011111 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+
+       /* 196 0xc4 'Ä' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xff, /* 11111111 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 197 0xc5 'Å' */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0xff, /* 11111111 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+
+       /* 198 0xc6 'Æ' */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x1f, /* 00011111 */
+       0x18, /* 00011000 */
+       0x1f, /* 00011111 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+
+       /* 199 0xc7 'Ç' */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x37, /* 00110111 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+
+       /* 200 0xc8 'È' */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x37, /* 00110111 */
+       0x30, /* 00110000 */
+       0x3f, /* 00111111 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 201 0xc9 'É' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x3f, /* 00111111 */
+       0x30, /* 00110000 */
+       0x37, /* 00110111 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+
+       /* 202 0xca 'Ê' */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0xf7, /* 11110111 */
+       0x00, /* 00000000 */
+       0xff, /* 11111111 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 203 0xcb 'Ë' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xff, /* 11111111 */
+       0x00, /* 00000000 */
+       0xf7, /* 11110111 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+
+       /* 204 0xcc 'Ì' */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x37, /* 00110111 */
+       0x30, /* 00110000 */
+       0x37, /* 00110111 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+
+       /* 205 0xcd 'Í' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xff, /* 11111111 */
+       0x00, /* 00000000 */
+       0xff, /* 11111111 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 206 0xce 'Î' */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0xf7, /* 11110111 */
+       0x00, /* 00000000 */
+       0xf7, /* 11110111 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+
+       /* 207 0xcf 'Ï' */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0xff, /* 11111111 */
+       0x00, /* 00000000 */
+       0xff, /* 11111111 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 208 0xd0 'Ð' */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0xff, /* 11111111 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 209 0xd1 'Ñ' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xff, /* 11111111 */
+       0x00, /* 00000000 */
+       0xff, /* 11111111 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+
+       /* 210 0xd2 'Ò' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xff, /* 11111111 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+
+       /* 211 0xd3 'Ó' */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x3f, /* 00111111 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 212 0xd4 'Ô' */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x1f, /* 00011111 */
+       0x18, /* 00011000 */
+       0x1f, /* 00011111 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 213 0xd5 'Õ' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x1f, /* 00011111 */
+       0x18, /* 00011000 */
+       0x1f, /* 00011111 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+
+       /* 214 0xd6 'Ö' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x3f, /* 00111111 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+
+       /* 215 0xd7 '×' */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0xff, /* 11111111 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+
+       /* 216 0xd8 'Ø' */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0xff, /* 11111111 */
+       0x18, /* 00011000 */
+       0xff, /* 11111111 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+
+       /* 217 0xd9 'Ù' */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0xf8, /* 11111000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 218 0xda 'Ú' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x1f, /* 00011111 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+
+       /* 219 0xdb 'Û' */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+
+       /* 220 0xdc 'Ü' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+
+       /* 221 0xdd 'Ý' */
+       0xf0, /* 11110000 */
+       0xf0, /* 11110000 */
+       0xf0, /* 11110000 */
+       0xf0, /* 11110000 */
+       0xf0, /* 11110000 */
+       0xf0, /* 11110000 */
+       0xf0, /* 11110000 */
+       0xf0, /* 11110000 */
+       0xf0, /* 11110000 */
+       0xf0, /* 11110000 */
+       0xf0, /* 11110000 */
+       0xf0, /* 11110000 */
+       0xf0, /* 11110000 */
+       0xf0, /* 11110000 */
+       0xf0, /* 11110000 */
+       0xf0, /* 11110000 */
+
+       /* 222 0xde 'Þ' */
+       0x0f, /* 00001111 */
+       0x0f, /* 00001111 */
+       0x0f, /* 00001111 */
+       0x0f, /* 00001111 */
+       0x0f, /* 00001111 */
+       0x0f, /* 00001111 */
+       0x0f, /* 00001111 */
+       0x0f, /* 00001111 */
+       0x0f, /* 00001111 */
+       0x0f, /* 00001111 */
+       0x0f, /* 00001111 */
+       0x0f, /* 00001111 */
+       0x0f, /* 00001111 */
+       0x0f, /* 00001111 */
+       0x0f, /* 00001111 */
+       0x0f, /* 00001111 */
+
+       /* 223 0xdf 'ß' */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0xff, /* 11111111 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 224 0xe0 'à' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x76, /* 01110110 */
+       0xdc, /* 11011100 */
+       0xd8, /* 11011000 */
+       0xd8, /* 11011000 */
+       0xd8, /* 11011000 */
+       0xdc, /* 11011100 */
+       0x76, /* 01110110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 225 0xe1 'á' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x78, /* 01111000 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xcc, /* 11001100 */
+       0xd8, /* 11011000 */
+       0xcc, /* 11001100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xcc, /* 11001100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 226 0xe2 'â' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfe, /* 11111110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0xc0, /* 11000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 227 0xe3 'ã' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfe, /* 11111110 */
+       0x6c, /* 01101100 */
+       0x6c, /* 01101100 */
+       0x6c, /* 01101100 */
+       0x6c, /* 01101100 */
+       0x6c, /* 01101100 */
+       0x6c, /* 01101100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 228 0xe4 'ä' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfe, /* 11111110 */
+       0xc6, /* 11000110 */
+       0x60, /* 01100000 */
+       0x30, /* 00110000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x60, /* 01100000 */
+       0xc6, /* 11000110 */
+       0xfe, /* 11111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 229 0xe5 'å' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7e, /* 01111110 */
+       0xd8, /* 11011000 */
+       0xd8, /* 11011000 */
+       0xd8, /* 11011000 */
+       0xd8, /* 11011000 */
+       0xd8, /* 11011000 */
+       0x70, /* 01110000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 230 0xe6 'æ' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x7c, /* 01111100 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0xc0, /* 11000000 */
+       0x00, /* 00000000 */
+
+       /* 231 0xe7 'ç' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x76, /* 01110110 */
+       0xdc, /* 11011100 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 232 0xe8 'è' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7e, /* 01111110 */
+       0x18, /* 00011000 */
+       0x3c, /* 00111100 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x3c, /* 00111100 */
+       0x18, /* 00011000 */
+       0x7e, /* 01111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 233 0xe9 'é' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x38, /* 00111000 */
+       0x6c, /* 01101100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xfe, /* 11111110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x6c, /* 01101100 */
+       0x38, /* 00111000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 234 0xea 'ê' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x38, /* 00111000 */
+       0x6c, /* 01101100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x6c, /* 01101100 */
+       0x6c, /* 01101100 */
+       0x6c, /* 01101100 */
+       0x6c, /* 01101100 */
+       0xee, /* 11101110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 235 0xeb 'ë' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x1e, /* 00011110 */
+       0x30, /* 00110000 */
+       0x18, /* 00011000 */
+       0x0c, /* 00001100 */
+       0x3e, /* 00111110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x66, /* 01100110 */
+       0x3c, /* 00111100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 236 0xec 'ì' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7e, /* 01111110 */
+       0xdb, /* 11011011 */
+       0xdb, /* 11011011 */
+       0xdb, /* 11011011 */
+       0x7e, /* 01111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 237 0xed 'í' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x03, /* 00000011 */
+       0x06, /* 00000110 */
+       0x7e, /* 01111110 */
+       0xdb, /* 11011011 */
+       0xdb, /* 11011011 */
+       0xf3, /* 11110011 */
+       0x7e, /* 01111110 */
+       0x60, /* 01100000 */
+       0xc0, /* 11000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 238 0xee 'î' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x1c, /* 00011100 */
+       0x30, /* 00110000 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0x7c, /* 01111100 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0x60, /* 01100000 */
+       0x30, /* 00110000 */
+       0x1c, /* 00011100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 239 0xef 'ï' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7c, /* 01111100 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0xc6, /* 11000110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 240 0xf0 'ð' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfe, /* 11111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfe, /* 11111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0xfe, /* 11111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 241 0xf1 'ñ' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x7e, /* 01111110 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7e, /* 01111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 242 0xf2 'ò' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x30, /* 00110000 */
+       0x18, /* 00011000 */
+       0x0c, /* 00001100 */
+       0x06, /* 00000110 */
+       0x0c, /* 00001100 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x00, /* 00000000 */
+       0x7e, /* 01111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 243 0xf3 'ó' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x0c, /* 00001100 */
+       0x18, /* 00011000 */
+       0x30, /* 00110000 */
+       0x60, /* 01100000 */
+       0x30, /* 00110000 */
+       0x18, /* 00011000 */
+       0x0c, /* 00001100 */
+       0x00, /* 00000000 */
+       0x7e, /* 01111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 244 0xf4 'ô' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x0e, /* 00001110 */
+       0x1b, /* 00011011 */
+       0x1b, /* 00011011 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+
+       /* 245 0xf5 'õ' */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0xd8, /* 11011000 */
+       0xd8, /* 11011000 */
+       0xd8, /* 11011000 */
+       0x70, /* 01110000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 246 0xf6 'ö' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x7e, /* 01111110 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 247 0xf7 '÷' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x76, /* 01110110 */
+       0xdc, /* 11011100 */
+       0x00, /* 00000000 */
+       0x76, /* 01110110 */
+       0xdc, /* 11011100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 248 0xf8 'ø' */
+       0x00, /* 00000000 */
+       0x38, /* 00111000 */
+       0x6c, /* 01101100 */
+       0x6c, /* 01101100 */
+       0x38, /* 00111000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 249 0xf9 'ù' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 250 0xfa 'ú' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x18, /* 00011000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 251 0xfb 'û' */
+       0x00, /* 00000000 */
+       0x0f, /* 00001111 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0x0c, /* 00001100 */
+       0xec, /* 11101100 */
+       0x6c, /* 01101100 */
+       0x6c, /* 01101100 */
+       0x3c, /* 00111100 */
+       0x1c, /* 00011100 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 252 0xfc 'ü' */
+       0x00, /* 00000000 */
+       0x6c, /* 01101100 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x36, /* 00110110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 253 0xfd 'ý' */
+       0x00, /* 00000000 */
+       0x3c, /* 00111100 */
+       0x66, /* 01100110 */
+       0x0c, /* 00001100 */
+       0x18, /* 00011000 */
+       0x32, /* 00110010 */
+       0x7e, /* 01111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 254 0xfe 'þ' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x7e, /* 01111110 */
+       0x7e, /* 01111110 */
+       0x7e, /* 01111110 */
+       0x7e, /* 01111110 */
+       0x7e, /* 01111110 */
+       0x7e, /* 01111110 */
+       0x7e, /* 01111110 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+       /* 255 0xff 'ÿ' */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+       0x00, /* 00000000 */
+
+};
diff --git a/tools/ioemu/vl.c b/tools/ioemu/vl.c
new file mode 100644 (file)
index 0000000..f6c6e00
--- /dev/null
@@ -0,0 +1,2978 @@
+/*
+ * QEMU System Emulator
+ * 
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <time.h>
+#include <errno.h>
+#include <sys/time.h>
+
+#ifndef _WIN32
+#include <sys/times.h>
+#include <sys/wait.h>
+#include <termios.h>
+#include <sys/poll.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <dirent.h>
+#ifdef _BSD
+#include <sys/stat.h>
+#ifndef __APPLE__
+#include <libutil.h>
+#endif
+#else
+#include <linux/if.h>
+#include <linux/if_tun.h>
+#include <pty.h>
+#include <malloc.h>
+#include <linux/rtc.h>
+#endif
+#endif
+
+#if defined(CONFIG_SLIRP)
+#include "libslirp.h"
+#endif
+
+#ifdef _WIN32
+#include <malloc.h>
+#include <sys/timeb.h>
+#include <windows.h>
+#define getopt_long_only getopt_long
+#define memalign(align, size) malloc(size)
+#endif
+
+#ifdef CONFIG_SDL
+#ifdef __APPLE__
+#include <SDL/SDL.h>
+#endif
+#endif /* CONFIG_SDL */
+
+#include "xc.h"
+#include "exec-all.h"
+
+//#define DO_TB_FLUSH
+
+#define DEFAULT_NETWORK_SCRIPT "/etc/xen/qemu-ifup"
+
+#if !defined(CONFIG_SOFTMMU)
+#define PHYS_RAM_MAX_SIZE (256 * 1024 * 1024)
+#else
+#define PHYS_RAM_MAX_SIZE (2047 * 1024 * 1024)
+#endif
+
+#ifdef TARGET_PPC
+#define DEFAULT_RAM_SIZE 144
+#else
+#define DEFAULT_RAM_SIZE 128
+#endif
+/* in ms */
+#define GUI_REFRESH_INTERVAL 30
+#define POLLING_INTERVAL 5
+
+/* XXX: use a two level table to limit memory usage */
+#define MAX_IOPORTS 65536
+
+const char *bios_dir = CONFIG_QEMU_SHAREDIR;
+char phys_ram_file[1024];
+CPUState *global_env;
+CPUState *cpu_single_env;
+void *ioport_opaque[MAX_IOPORTS];
+IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS];
+IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];
+BlockDriverState *bs_table[MAX_DISKS], *fd_table[MAX_FD];
+int vga_ram_size;
+int bios_size;
+static DisplayState display_state;
+int nographic;
+int usevnc; /* 1=vnc only, 2=vnc and sdl */
+const char* keyboard_layout = 0;
+int64_t ticks_per_sec;
+int boot_device = 'c';
+int ram_size;
+int domid;
+static char network_script[1024];
+int pit_min_timer_count = 0;
+int nb_nics;
+NetDriverState nd_table[MAX_NICS];
+QEMUTimer *gui_timer;
+QEMUTimer *polling_timer;
+int vm_running;
+int audio_enabled = 0;
+int sb16_enabled = 1;
+int adlib_enabled = 1;
+int gus_enabled = 1;
+int pci_enabled = 1;
+int prep_enabled = 0;
+int rtc_utc = 1;
+int cirrus_vga_enabled = 1;
+int graphic_width = 800;
+int graphic_height = 600;
+int graphic_depth = 15;
+int full_screen = 0;
+TextConsole *vga_console;
+CharDriverState *serial_hds[MAX_SERIAL_PORTS];
+int xc_handle;
+
+/***********************************************************/
+/* x86 ISA bus support */
+
+target_phys_addr_t isa_mem_base = 0;
+
+uint32_t default_ioport_readb(void *opaque, uint32_t address)
+{
+#ifdef DEBUG_UNUSED_IOPORT
+    fprintf(stderr, "inb: port=0x%04x\n", address);
+#endif
+    return 0xff;
+}
+
+void default_ioport_writeb(void *opaque, uint32_t address, uint32_t data)
+{
+#ifdef DEBUG_UNUSED_IOPORT
+    fprintf(stderr, "outb: port=0x%04x data=0x%02x\n", address, data);
+#endif
+}
+
+/* default is to make two byte accesses */
+uint32_t default_ioport_readw(void *opaque, uint32_t address)
+{
+    uint32_t data;
+    data = ioport_read_table[0][address](ioport_opaque[address], address);
+    address = (address + 1) & (MAX_IOPORTS - 1);
+    data |= ioport_read_table[0][address](ioport_opaque[address], address) << 8;
+    return data;
+}
+
+void default_ioport_writew(void *opaque, uint32_t address, uint32_t data)
+{
+    ioport_write_table[0][address](ioport_opaque[address], address, data & 0xff);
+    address = (address + 1) & (MAX_IOPORTS - 1);
+    ioport_write_table[0][address](ioport_opaque[address], address, (data >> 8) & 0xff);
+}
+
+uint32_t default_ioport_readl(void *opaque, uint32_t address)
+{
+#ifdef DEBUG_UNUSED_IOPORT
+    fprintf(stderr, "inl: port=0x%04x\n", address);
+#endif
+    return 0xffffffff;
+}
+
+void default_ioport_writel(void *opaque, uint32_t address, uint32_t data)
+{
+#ifdef DEBUG_UNUSED_IOPORT
+    fprintf(stderr, "outl: port=0x%04x data=0x%02x\n", address, data);
+#endif
+}
+
+void init_ioports(void)
+{
+    int i;
+
+    for(i = 0; i < MAX_IOPORTS; i++) {
+        ioport_read_table[0][i] = default_ioport_readb;
+        ioport_write_table[0][i] = default_ioport_writeb;
+        ioport_read_table[1][i] = default_ioport_readw;
+        ioport_write_table[1][i] = default_ioport_writew;
+        ioport_read_table[2][i] = default_ioport_readl;
+        ioport_write_table[2][i] = default_ioport_writel;
+    }
+}
+
+/* size is the word size in byte */
+int register_ioport_read(int start, int length, int size, 
+                         IOPortReadFunc *func, void *opaque)
+{
+    int i, bsize;
+
+    if (size == 1) {
+        bsize = 0;
+    } else if (size == 2) {
+        bsize = 1;
+    } else if (size == 4) {
+        bsize = 2;
+    } else {
+        hw_error("register_ioport_read: invalid size");
+        return -1;
+    }
+    for(i = start; i < start + length; i += size) {
+        ioport_read_table[bsize][i] = func;
+        if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)
+            hw_error("register_ioport_read: invalid opaque");
+        ioport_opaque[i] = opaque;
+    }
+    return 0;
+}
+
+/* size is the word size in byte */
+int register_ioport_write(int start, int length, int size, 
+                          IOPortWriteFunc *func, void *opaque)
+{
+    int i, bsize;
+
+    if (size == 1) {
+        bsize = 0;
+    } else if (size == 2) {
+        bsize = 1;
+    } else if (size == 4) {
+        bsize = 2;
+    } else {
+        hw_error("register_ioport_write: invalid size");
+        return -1;
+    }
+    for(i = start; i < start + length; i += size) {
+        ioport_write_table[bsize][i] = func;
+        if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)
+            hw_error("register_ioport_read: invalid opaque");
+        ioport_opaque[i] = opaque;
+    }
+    return 0;
+}
+
+void isa_unassign_ioport(int start, int length)
+{
+    int i;
+
+    for(i = start; i < start + length; i++) {
+        ioport_read_table[0][i] = default_ioport_readb;
+        ioport_read_table[1][i] = default_ioport_readw;
+        ioport_read_table[2][i] = default_ioport_readl;
+
+        ioport_write_table[0][i] = default_ioport_writeb;
+        ioport_write_table[1][i] = default_ioport_writew;
+        ioport_write_table[2][i] = default_ioport_writel;
+    }
+}
+
+void pstrcpy(char *buf, int buf_size, const char *str)
+{
+    int c;
+    char *q = buf;
+
+    if (buf_size <= 0)
+        return;
+
+    for(;;) {
+        c = *str++;
+        if (c == 0 || q >= buf + buf_size - 1)
+            break;
+        *q++ = c;
+    }
+    *q = '\0';
+}
+
+/* strcat and truncate. */
+char *pstrcat(char *buf, int buf_size, const char *s)
+{
+    int len;
+    len = strlen(buf);
+    if (len < buf_size) 
+        pstrcpy(buf + len, buf_size - len, s);
+    return buf;
+}
+
+int strstart(const char *str, const char *val, const char **ptr)
+{
+    const char *p, *q;
+    p = str;
+    q = val;
+    while (*q != '\0') {
+        if (*p != *q)
+            return 0;
+        p++;
+        q++;
+    }
+    if (ptr)
+        *ptr = p;
+    return 1;
+}
+
+/* return the size or -1 if error */
+int get_image_size(const char *filename)
+{
+    int fd, size;
+    fd = open(filename, O_RDONLY | O_BINARY);
+    if (fd < 0)
+        return -1;
+    size = lseek(fd, 0, SEEK_END);
+    close(fd);
+    return size;
+}
+
+/* return the size or -1 if error */
+int load_image(const char *filename, uint8_t *addr)
+{
+    int fd, size;
+    fd = open(filename, O_RDONLY | O_BINARY);
+    if (fd < 0)
+        return -1;
+    size = lseek(fd, 0, SEEK_END);
+    lseek(fd, 0, SEEK_SET);
+    if (read(fd, addr, size) != size) {
+        close(fd);
+        return -1;
+    }
+    close(fd);
+    return size;
+}
+
+void cpu_outb(CPUState *env, int addr, int val)
+{
+#ifdef DEBUG_IOPORT
+    if (loglevel & CPU_LOG_IOPORT)
+        fprintf(logfile, "outb: %04x %02x\n", addr, val);
+#endif    
+    ioport_write_table[0][addr](ioport_opaque[addr], addr, val);
+}
+
+void cpu_outw(CPUState *env, int addr, int val)
+{
+#ifdef DEBUG_IOPORT
+    if (loglevel & CPU_LOG_IOPORT)
+        fprintf(logfile, "outw: %04x %04x\n", addr, val);
+#endif    
+    ioport_write_table[1][addr](ioport_opaque[addr], addr, val);
+}
+
+void cpu_outl(CPUState *env, int addr, int val)
+{
+#ifdef DEBUG_IOPORT
+    if (loglevel & CPU_LOG_IOPORT)
+        fprintf(logfile, "outl: %04x %08x\n", addr, val);
+#endif
+    ioport_write_table[2][addr](ioport_opaque[addr], addr, val);
+}
+
+int cpu_inb(CPUState *env, int addr)
+{
+    int val;
+    val = ioport_read_table[0][addr](ioport_opaque[addr], addr);
+#ifdef DEBUG_IOPORT
+    if (loglevel & CPU_LOG_IOPORT)
+        fprintf(logfile, "inb : %04x %02x\n", addr, val);
+#endif
+    return val;
+}
+
+int cpu_inw(CPUState *env, int addr)
+{
+    int val;
+    val = ioport_read_table[1][addr](ioport_opaque[addr], addr);
+#ifdef DEBUG_IOPORT
+    if (loglevel & CPU_LOG_IOPORT)
+        fprintf(logfile, "inw : %04x %04x\n", addr, val);
+#endif
+    return val;
+}
+
+int cpu_inl(CPUState *env, int addr)
+{
+    int val;
+    val = ioport_read_table[2][addr](ioport_opaque[addr], addr);
+#ifdef DEBUG_IOPORT
+    if (loglevel & CPU_LOG_IOPORT)
+        fprintf(logfile, "inl : %04x %08x\n", addr, val);
+#endif
+    return val;
+}
+
+/***********************************************************/
+void hw_error(const char *fmt, ...)
+{
+    va_list ap;
+
+    va_start(ap, fmt);
+    fprintf(stderr, "qemu: hardware error: ");
+    vfprintf(stderr, fmt, ap);
+    fprintf(stderr, "\n");
+    va_end(ap);
+    abort();
+}
+
+/***********************************************************/
+/* keyboard/mouse */
+
+static QEMUPutKBDEvent *qemu_put_kbd_event;
+static void *qemu_put_kbd_event_opaque;
+static QEMUPutMouseEvent *qemu_put_mouse_event;
+static void *qemu_put_mouse_event_opaque;
+
+void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
+{
+    qemu_put_kbd_event_opaque = opaque;
+    qemu_put_kbd_event = func;
+}
+
+void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque)
+{
+    qemu_put_mouse_event_opaque = opaque;
+    qemu_put_mouse_event = func;
+}
+
+void kbd_put_keycode(int keycode)
+{
+    if (qemu_put_kbd_event) {
+        qemu_put_kbd_event(qemu_put_kbd_event_opaque, keycode);
+    }
+}
+
+void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
+{
+    if (qemu_put_mouse_event) {
+        qemu_put_mouse_event(qemu_put_mouse_event_opaque, 
+                             dx, dy, dz, buttons_state);
+    }
+}
+
+/***********************************************************/
+/* timers */
+
+#if defined(__powerpc__)
+
+static inline uint32_t get_tbl(void) 
+{
+    uint32_t tbl;
+    asm volatile("mftb %0" : "=r" (tbl));
+    return tbl;
+}
+
+static inline uint32_t get_tbu(void) 
+{
+       uint32_t tbl;
+       asm volatile("mftbu %0" : "=r" (tbl));
+       return tbl;
+}
+
+int64_t cpu_get_real_ticks(void)
+{
+    uint32_t l, h, h1;
+    /* NOTE: we test if wrapping has occurred */
+    do {
+        h = get_tbu();
+        l = get_tbl();
+        h1 = get_tbu();
+    } while (h != h1);
+    return ((int64_t)h << 32) | l;
+}
+
+#elif defined(__i386__)
+
+int64_t cpu_get_real_ticks(void)
+{
+    int64_t val;
+    asm volatile ("rdtsc" : "=A" (val));
+    return val;
+}
+
+#elif defined(__x86_64__)
+
+int64_t cpu_get_real_ticks(void)
+{
+    uint32_t low,high;
+    int64_t val;
+    asm volatile("rdtsc" : "=a" (low), "=d" (high));
+    val = high;
+    val <<= 32;
+    val |= low;
+    return val;
+}
+
+#else
+#error unsupported CPU
+#endif
+
+static int64_t cpu_ticks_offset;
+static int cpu_ticks_enabled;
+int64_t cpu_virt_tsc;
+
+static inline int64_t cpu_get_ticks(void)
+{
+    if (!cpu_ticks_enabled) {
+        return cpu_ticks_offset;
+    } else {
+        return cpu_get_real_ticks() + cpu_ticks_offset;
+    }
+
+}
+
+/* enable cpu_get_ticks() */
+void cpu_enable_ticks(void)
+{
+    if (!cpu_ticks_enabled) {
+        cpu_ticks_offset -= cpu_get_real_ticks();
+        cpu_ticks_enabled = 1;
+    }
+}
+
+/* disable cpu_get_ticks() : the clock is stopped. You must not call
+   cpu_get_ticks() after that.  */
+void cpu_disable_ticks(void)
+{
+    if (cpu_ticks_enabled) {
+        cpu_ticks_offset = cpu_get_ticks();
+        cpu_ticks_enabled = 0;
+    }
+}
+
+static int64_t get_clock(void)
+{
+#ifdef _WIN32
+    struct _timeb tb;
+    _ftime(&tb);
+    return ((int64_t)tb.time * 1000 + (int64_t)tb.millitm) * 1000;
+#else
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+    return tv.tv_sec * 1000000LL + tv.tv_usec;
+#endif
+}
+
+void cpu_calibrate_ticks(void)
+{
+    int64_t usec, ticks;
+
+    usec = get_clock();
+    ticks = cpu_get_real_ticks();
+#ifdef _WIN32
+    Sleep(50);
+#else
+    usleep(50 * 1000);
+#endif
+    usec = get_clock() - usec;
+    ticks = cpu_get_real_ticks() - ticks;
+    ticks_per_sec = (ticks * 1000000LL + (usec >> 1)) / usec;
+}
+
+/* compute with 96 bit intermediate result: (a*b)/c */
+uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
+{
+    union {
+        uint64_t ll;
+        struct {
+#ifdef WORDS_BIGENDIAN
+            uint32_t high, low;
+#else
+            uint32_t low, high;
+#endif            
+        } l;
+    } u, res;
+    uint64_t rl, rh;
+
+    u.ll = a;
+    rl = (uint64_t)u.l.low * (uint64_t)b;
+    rh = (uint64_t)u.l.high * (uint64_t)b;
+    rh += (rl >> 32);
+    res.l.high = rh / c;
+    res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
+    return res.ll;
+}
+
+#define QEMU_TIMER_REALTIME 0
+#define QEMU_TIMER_VIRTUAL  1
+
+struct QEMUClock {
+    int type;
+    /* XXX: add frequency */
+};
+
+struct QEMUTimer {
+    QEMUClock *clock;
+    int64_t expire_time;
+    QEMUTimerCB *cb;
+    void *opaque;
+    struct QEMUTimer *next;
+};
+
+QEMUClock *rt_clock;
+QEMUClock *vm_clock;
+
+static QEMUTimer *active_timers[2];
+#ifdef _WIN32
+static MMRESULT timerID;
+#else
+/* frequency of the times() clock tick */
+static int timer_freq;
+#endif
+
+QEMUClock *qemu_new_clock(int type)
+{
+    QEMUClock *clock;
+    clock = qemu_mallocz(sizeof(QEMUClock));
+    if (!clock)
+        return NULL;
+    clock->type = type;
+    return clock;
+}
+
+QEMUTimer *qemu_new_timer(QEMUClock *clock, QEMUTimerCB *cb, void *opaque)
+{
+    QEMUTimer *ts;
+
+    ts = qemu_mallocz(sizeof(QEMUTimer));
+    ts->clock = clock;
+    ts->cb = cb;
+    ts->opaque = opaque;
+    return ts;
+}
+
+void qemu_free_timer(QEMUTimer *ts)
+{
+    qemu_free(ts);
+}
+
+/* stop a timer, but do not dealloc it */
+void qemu_del_timer(QEMUTimer *ts)
+{
+    QEMUTimer **pt, *t;
+
+    /* NOTE: this code must be signal safe because
+       qemu_timer_expired() can be called from a signal. */
+    pt = &active_timers[ts->clock->type];
+    for(;;) {
+        t = *pt;
+        if (!t)
+            break;
+        if (t == ts) {
+            *pt = t->next;
+            break;
+        }
+        pt = &t->next;
+    }
+}
+
+/* modify the current timer so that it will be fired when current_time
+   >= expire_time. The corresponding callback will be called. */
+void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
+{
+    QEMUTimer **pt, *t;
+
+    qemu_del_timer(ts);
+
+    /* add the timer in the sorted list */
+    /* NOTE: this code must be signal safe because
+       qemu_timer_expired() can be called from a signal. */
+    pt = &active_timers[ts->clock->type];
+    for(;;) {
+        t = *pt;
+        if (!t)
+            break;
+        if (t->expire_time > expire_time) 
+            break;
+        pt = &t->next;
+    }
+    ts->expire_time = expire_time;
+    ts->next = *pt;
+    *pt = ts;
+}
+
+int qemu_timer_pending(QEMUTimer *ts)
+{
+    QEMUTimer *t;
+    for(t = active_timers[ts->clock->type]; t != NULL; t = t->next) {
+        if (t == ts)
+            return 1;
+    }
+    return 0;
+}
+
+static inline int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time)
+{
+    if (!timer_head)
+        return 0;
+    return (timer_head->expire_time <= current_time);
+}
+
+static void qemu_run_timers(QEMUTimer **ptimer_head, int64_t current_time)
+{
+    QEMUTimer *ts;
+    
+    for(;;) {
+        ts = *ptimer_head;
+        if (!ts || ts->expire_time > current_time)
+            break;
+        /* remove timer from the list before calling the callback */
+        *ptimer_head = ts->next;
+        ts->next = NULL;
+        
+        /* run the callback (the timer list can be modified) */
+        ts->cb(ts->opaque);
+    }
+}
+
+int64_t qemu_get_clock(QEMUClock *clock)
+{
+    switch(clock->type) {
+    case QEMU_TIMER_REALTIME:
+#ifdef _WIN32
+        return GetTickCount();
+#else
+        {
+            struct tms tp;
+
+            /* Note that using gettimeofday() is not a good solution
+               for timers because its value change when the date is
+               modified. */
+            if (timer_freq == 100) {
+                return times(&tp) * 10;
+            } else {
+                return ((int64_t)times(&tp) * 1000) / timer_freq;
+            }
+        }
+#endif
+    default:
+    case QEMU_TIMER_VIRTUAL:
+        return cpu_get_ticks();
+    }
+}
+
+/* save a timer */
+void qemu_put_timer(QEMUFile *f, QEMUTimer *ts)
+{
+    uint64_t expire_time;
+
+    if (qemu_timer_pending(ts)) {
+        expire_time = ts->expire_time;
+    } else {
+        expire_time = -1;
+    }
+    qemu_put_be64(f, expire_time);
+}
+
+void qemu_get_timer(QEMUFile *f, QEMUTimer *ts)
+{
+    uint64_t expire_time;
+
+    expire_time = qemu_get_be64(f);
+    if (expire_time != -1) {
+        qemu_mod_timer(ts, expire_time);
+    } else {
+        qemu_del_timer(ts);
+    }
+}
+
+static void init_timers(void)
+{
+    rt_clock = qemu_new_clock(QEMU_TIMER_REALTIME);
+    vm_clock = qemu_new_clock(QEMU_TIMER_VIRTUAL);
+
+#ifdef _WIN32
+    {
+        int count=0;
+        timerID = timeSetEvent(10,    // interval (ms)
+                               0,     // resolution
+                               host_alarm_handler, // function
+                               (DWORD)&count,  // user parameter
+                               TIME_PERIODIC | TIME_CALLBACK_FUNCTION);
+       if( !timerID ) {
+            perror("failed timer alarm");
+            exit(1);
+       }
+    }
+    pit_min_timer_count = ((uint64_t)10000 * PIT_FREQ) / 1000000;
+#else
+    {
+        /* get times() syscall frequency */
+        timer_freq = sysconf(_SC_CLK_TCK);
+      
+#ifndef TARGET_VMX
+        /* timer signal */
+        sigfillset(&act.sa_mask);
+        act.sa_flags = 0;
+#if defined (TARGET_I386) && defined(USE_CODE_COPY)
+        act.sa_flags |= SA_ONSTACK;
+#endif
+        act.sa_handler = host_alarm_handler;
+        sigaction(SIGALRM, &act, NULL);
+
+        itv.it_interval.tv_sec = 0;
+        itv.it_interval.tv_usec = 1000;
+        itv.it_value.tv_sec = 0;
+        itv.it_value.tv_usec = 10 * 1000;
+        setitimer(ITIMER_REAL, &itv, NULL);
+        /* we probe the tick duration of the kernel to inform the user if
+           the emulated kernel requested a too high timer frequency */
+        getitimer(ITIMER_REAL, &itv);
+
+#if defined(__linux__)
+        if (itv.it_interval.tv_usec > 1000) {
+            /* try to use /dev/rtc to have a faster timer */
+            if (start_rtc_timer() < 0)
+                goto use_itimer;
+            /* disable itimer */
+            itv.it_interval.tv_sec = 0;
+            itv.it_interval.tv_usec = 0;
+            itv.it_value.tv_sec = 0;
+            itv.it_value.tv_usec = 0;
+            setitimer(ITIMER_REAL, &itv, NULL);
+
+            /* use the RTC */
+            sigaction(SIGIO, &act, NULL);
+            fcntl(rtc_fd, F_SETFL, O_ASYNC);
+            fcntl(rtc_fd, F_SETOWN, getpid());
+        } else 
+#endif /* defined(__linux__) */
+        {
+        use_itimer:
+            pit_min_timer_count = ((uint64_t)itv.it_interval.tv_usec * 
+                                   PIT_FREQ) / 1000000;
+        }
+#endif /* TARGET_VMX */
+    }
+#endif
+}
+
+void quit_timers(void)
+{
+#ifdef _WIN32
+    timeKillEvent(timerID);
+#endif
+}
+
+/***********************************************************/
+/* character device */
+
+int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len)
+{
+    return s->chr_write(s, buf, len);
+}
+
+void qemu_chr_printf(CharDriverState *s, const char *fmt, ...)
+{
+    char buf[4096];
+    va_list ap;
+    va_start(ap, fmt);
+    vsnprintf(buf, sizeof(buf), fmt, ap);
+    qemu_chr_write(s, buf, strlen(buf));
+    va_end(ap);
+}
+
+void qemu_chr_send_event(CharDriverState *s, int event)
+{
+    if (s->chr_send_event)
+        s->chr_send_event(s, event);
+}
+
+void qemu_chr_add_read_handler(CharDriverState *s, 
+                               IOCanRWHandler *fd_can_read, 
+                               IOReadHandler *fd_read, void *opaque)
+{
+    s->chr_add_read_handler(s, fd_can_read, fd_read, opaque);
+}
+             
+void qemu_chr_add_event_handler(CharDriverState *s, IOEventHandler *chr_event)
+{
+    s->chr_event = chr_event;
+}
+
+static int null_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
+{
+    return len;
+}
+
+static void null_chr_add_read_handler(CharDriverState *chr, 
+                                    IOCanRWHandler *fd_can_read, 
+                                    IOReadHandler *fd_read, void *opaque)
+{
+}
+
+CharDriverState *qemu_chr_open_null(void)
+{
+    CharDriverState *chr;
+
+    chr = qemu_mallocz(sizeof(CharDriverState));
+    if (!chr)
+        return NULL;
+    chr->chr_write = null_chr_write;
+    chr->chr_add_read_handler = null_chr_add_read_handler;
+    return chr;
+}
+
+#ifndef _WIN32
+
+typedef struct {
+    int fd_in, fd_out;
+    /* for nographic stdio only */
+    IOCanRWHandler *fd_can_read; 
+    IOReadHandler *fd_read;
+    void *fd_opaque;
+} FDCharDriver;
+
+#define STDIO_MAX_CLIENTS 2
+
+static int stdio_nb_clients;
+static CharDriverState *stdio_clients[STDIO_MAX_CLIENTS];
+
+static int unix_write(int fd, const uint8_t *buf, int len1)
+{
+    int ret, len;
+
+    len = len1;
+    while (len > 0) {
+        ret = write(fd, buf, len);
+        if (ret < 0) {
+            if (errno != EINTR && errno != EAGAIN)
+                return -1;
+        } else if (ret == 0) {
+            break;
+        } else {
+            buf += ret;
+            len -= ret;
+        }
+    }
+    return len1 - len;
+}
+
+static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
+{
+    FDCharDriver *s = chr->opaque;
+    return unix_write(s->fd_out, buf, len);
+}
+
+static void fd_chr_add_read_handler(CharDriverState *chr, 
+                                    IOCanRWHandler *fd_can_read, 
+                                    IOReadHandler *fd_read, void *opaque)
+{
+    FDCharDriver *s = chr->opaque;
+
+    if (nographic && s->fd_in == 0) {
+        s->fd_can_read = fd_can_read;
+        s->fd_read = fd_read;
+        s->fd_opaque = opaque;
+    } else {
+        qemu_add_fd_read_handler(s->fd_in, fd_can_read, fd_read, opaque);
+    }
+}
+
+/* open a character device to a unix fd */
+CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out)
+{
+    CharDriverState *chr;
+    FDCharDriver *s;
+
+    chr = qemu_mallocz(sizeof(CharDriverState));
+    if (!chr)
+        return NULL;
+    s = qemu_mallocz(sizeof(FDCharDriver));
+    if (!s) {
+        free(chr);
+        return NULL;
+    }
+    s->fd_in = fd_in;
+    s->fd_out = fd_out;
+    chr->opaque = s;
+    chr->chr_write = fd_chr_write;
+    chr->chr_add_read_handler = fd_chr_add_read_handler;
+    return chr;
+}
+
+/* for STDIO, we handle the case where several clients use it
+   (nographic mode) */
+
+#define TERM_ESCAPE 0x01 /* ctrl-a is used for escape */
+
+static int term_got_escape, client_index;
+
+void term_print_help(void)
+{
+    printf("\n"
+           "C-a h    print this help\n"
+           "C-a x    exit emulator\n"
+           "C-a s    save disk data back to file (if -snapshot)\n"
+           "C-a b    send break (magic sysrq)\n"
+           "C-a c    switch between console and monitor\n"
+           "C-a C-a  send C-a\n"
+           );
+}
+
+/* called when a char is received */
+static void stdio_received_byte(int ch)
+{
+    if (term_got_escape) {
+        term_got_escape = 0;
+        switch(ch) {
+        case 'h':
+            term_print_help();
+            break;
+        case 'x':
+            exit(0);
+            break;
+        case 's': 
+            {
+                int i;
+                for (i = 0; i < MAX_DISKS; i++) {
+                    if (bs_table[i])
+                        bdrv_commit(bs_table[i]);
+                }
+            }
+            break;
+        case 'b':
+            if (client_index < stdio_nb_clients) {
+                CharDriverState *chr;
+                FDCharDriver *s;
+
+                chr = stdio_clients[client_index];
+                s = chr->opaque;
+                chr->chr_event(s->fd_opaque, CHR_EVENT_BREAK);
+            }
+            break;
+        case 'c':
+            client_index++;
+            if (client_index >= stdio_nb_clients)
+                client_index = 0;
+            if (client_index == 0) {
+                /* send a new line in the monitor to get the prompt */
+                ch = '\r';
+                goto send_char;
+            }
+            break;
+        case TERM_ESCAPE:
+            goto send_char;
+        }
+    } else if (ch == TERM_ESCAPE) {
+        term_got_escape = 1;
+    } else {
+    send_char:
+        if (client_index < stdio_nb_clients) {
+            uint8_t buf[1];
+            CharDriverState *chr;
+            FDCharDriver *s;
+            
+            chr = stdio_clients[client_index];
+            s = chr->opaque;
+            buf[0] = ch;
+            /* XXX: should queue the char if the device is not
+               ready */
+            if (s->fd_can_read(s->fd_opaque) > 0) 
+                s->fd_read(s->fd_opaque, buf, 1);
+        }
+    }
+}
+
+static int stdio_can_read(void *opaque)
+{
+    /* XXX: not strictly correct */
+    return 1;
+}
+
+static void stdio_read(void *opaque, const uint8_t *buf, int size)
+{
+    int i;
+    for(i = 0; i < size; i++)
+        stdio_received_byte(buf[i]);
+}
+
+/* init terminal so that we can grab keys */
+static struct termios oldtty;
+static int old_fd0_flags;
+
+static void term_exit(void)
+{
+    tcsetattr (0, TCSANOW, &oldtty);
+    fcntl(0, F_SETFL, old_fd0_flags);
+}
+
+static void term_init(void)
+{
+    struct termios tty;
+
+    tcgetattr (0, &tty);
+    oldtty = tty;
+    old_fd0_flags = fcntl(0, F_GETFL);
+
+    tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
+                          |INLCR|IGNCR|ICRNL|IXON);
+    tty.c_oflag |= OPOST;
+    tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
+    /* if graphical mode, we allow Ctrl-C handling */
+    if (nographic)
+        tty.c_lflag &= ~ISIG;
+    tty.c_cflag &= ~(CSIZE|PARENB);
+    tty.c_cflag |= CS8;
+    tty.c_cc[VMIN] = 1;
+    tty.c_cc[VTIME] = 0;
+    
+    tcsetattr (0, TCSANOW, &tty);
+
+    atexit(term_exit);
+
+    fcntl(0, F_SETFL, O_NONBLOCK);
+}
+
+CharDriverState *qemu_chr_open_stdio(void)
+{
+    CharDriverState *chr;
+
+    if (nographic) {
+        if (stdio_nb_clients >= STDIO_MAX_CLIENTS)
+            return NULL;
+        chr = qemu_chr_open_fd(0, 1);
+        if (stdio_nb_clients == 0)
+            qemu_add_fd_read_handler(0, stdio_can_read, stdio_read, NULL);
+        client_index = stdio_nb_clients;
+    } else {
+        if (stdio_nb_clients != 0)
+            return NULL;
+        chr = qemu_chr_open_fd(0, 1);
+    }
+    stdio_clients[stdio_nb_clients++] = chr;
+    if (stdio_nb_clients == 1) {
+        /* set the terminal in raw mode */
+        term_init();
+    }
+    return chr;
+}
+
+#if defined(__linux__)
+CharDriverState *qemu_chr_open_pty(void)
+{
+    char slave_name[1024];
+    int master_fd, slave_fd;
+    
+    /* Not satisfying */
+    if (openpty(&master_fd, &slave_fd, slave_name, NULL, NULL) < 0) {
+        return NULL;
+    }
+    fprintf(stderr, "char device redirected to %s\n", slave_name);
+    return qemu_chr_open_fd(master_fd, master_fd);
+}
+#else
+CharDriverState *qemu_chr_open_pty(void)
+{
+    return NULL;
+}
+#endif
+
+#endif /* !defined(_WIN32) */
+
+CharDriverState *qemu_chr_open(const char *filename)
+{
+    if (!strcmp(filename, "vc")) {
+        return text_console_init(&display_state);
+    } else if (!strcmp(filename, "null")) {
+        return qemu_chr_open_null();
+    } else 
+#ifndef _WIN32
+    if (!strcmp(filename, "pty")) {
+        return qemu_chr_open_pty();
+    } else if (!strcmp(filename, "stdio")) {
+        return qemu_chr_open_stdio();
+    } else 
+#endif
+    {
+        return NULL;
+    }
+}
+
+/***********************************************************/
+/* Linux network device redirectors */
+
+void hex_dump(FILE *f, const uint8_t *buf, int size)
+{
+    int len, i, j, c;
+
+    for(i=0;i<size;i+=16) {
+        len = size - i;
+        if (len > 16)
+            len = 16;
+        fprintf(f, "%08x ", i);
+        for(j=0;j<16;j++) {
+            if (j < len)
+                fprintf(f, " %02x", buf[i+j]);
+            else
+                fprintf(f, "   ");
+        }
+        fprintf(f, " ");
+        for(j=0;j<len;j++) {
+            c = buf[i+j];
+            if (c < ' ' || c > '~')
+                c = '.';
+            fprintf(f, "%c", c);
+        }
+        fprintf(f, "\n");
+    }
+}
+
+void qemu_send_packet(NetDriverState *nd, const uint8_t *buf, int size)
+{
+    nd->send_packet(nd, buf, size);
+}
+
+void qemu_add_read_packet(NetDriverState *nd, IOCanRWHandler *fd_can_read, 
+                          IOReadHandler *fd_read, void *opaque)
+{
+    nd->add_read_packet(nd, fd_can_read, fd_read, opaque);
+}
+
+/* dummy network adapter */
+
+static void dummy_send_packet(NetDriverState *nd, const uint8_t *buf, int size)
+{
+}
+
+static void dummy_add_read_packet(NetDriverState *nd, 
+                                  IOCanRWHandler *fd_can_read, 
+                                  IOReadHandler *fd_read, void *opaque)
+{
+}
+
+static int net_dummy_init(NetDriverState *nd)
+{
+    nd->send_packet = dummy_send_packet;
+    nd->add_read_packet = dummy_add_read_packet;
+    pstrcpy(nd->ifname, sizeof(nd->ifname), "dummy");
+    return 0;
+}
+
+#if defined(CONFIG_SLIRP)
+
+/* slirp network adapter */
+
+static void *slirp_fd_opaque;
+static IOCanRWHandler *slirp_fd_can_read;
+static IOReadHandler *slirp_fd_read;
+static int slirp_inited;
+
+int slirp_can_output(void)
+{
+    return slirp_fd_can_read(slirp_fd_opaque);
+}
+
+void slirp_output(const uint8_t *pkt, int pkt_len)
+{
+#if 0
+    printf("output:\n");
+    hex_dump(stdout, pkt, pkt_len);
+#endif
+    slirp_fd_read(slirp_fd_opaque, pkt, pkt_len);
+}
+
+static void slirp_send_packet(NetDriverState *nd, const uint8_t *buf, int size)
+{
+#if 0
+    printf("input:\n");
+    hex_dump(stdout, buf, size);
+#endif
+    slirp_input(buf, size);
+}
+
+static void slirp_add_read_packet(NetDriverState *nd, 
+                                  IOCanRWHandler *fd_can_read, 
+                                  IOReadHandler *fd_read, void *opaque)
+{
+    slirp_fd_opaque = opaque;
+    slirp_fd_can_read = fd_can_read;
+    slirp_fd_read = fd_read;
+}
+
+static int net_slirp_init(NetDriverState *nd)
+{
+    if (!slirp_inited) {
+        slirp_inited = 1;
+        slirp_init();
+    }
+    nd->send_packet = slirp_send_packet;
+    nd->add_read_packet = slirp_add_read_packet;
+    pstrcpy(nd->ifname, sizeof(nd->ifname), "slirp");
+    return 0;
+}
+
+static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
+{
+    const char *p, *p1;
+    int len;
+    p = *pp;
+    p1 = strchr(p, sep);
+    if (!p1)
+        return -1;
+    len = p1 - p;
+    p1++;
+    if (buf_size > 0) {
+        if (len > buf_size - 1)
+            len = buf_size - 1;
+        memcpy(buf, p, len);
+        buf[len] = '\0';
+    }
+    *pp = p1;
+    return 0;
+}
+
+static void net_slirp_redir(const char *redir_str)
+{
+    int is_udp;
+    char buf[256], *r;
+    const char *p;
+    struct in_addr guest_addr;
+    int host_port, guest_port;
+    
+    if (!slirp_inited) {
+        slirp_inited = 1;
+        slirp_init();
+    }
+
+    p = redir_str;
+    if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
+        goto fail;
+    if (!strcmp(buf, "tcp")) {
+        is_udp = 0;
+    } else if (!strcmp(buf, "udp")) {
+        is_udp = 1;
+    } else {
+        goto fail;
+    }
+
+    if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
+        goto fail;
+    host_port = strtol(buf, &r, 0);
+    if (r == buf)
+        goto fail;
+
+    if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
+        goto fail;
+    if (buf[0] == '\0') {
+        pstrcpy(buf, sizeof(buf), "10.0.2.15");
+    }
+    if (!inet_aton(buf, &guest_addr))
+        goto fail;
+    
+    guest_port = strtol(p, &r, 0);
+    if (r == p)
+        goto fail;
+    
+    if (slirp_redir(is_udp, host_port, guest_addr, guest_port) < 0) {
+        fprintf(stderr, "qemu: could not set up redirection\n");
+        exit(1);
+    }
+    return;
+ fail:
+    fprintf(stderr, "qemu: syntax: -redir [tcp|udp]:host-port:[guest-host]:guest-port\n");
+    exit(1);
+}
+    
+#ifndef _WIN32
+
+char smb_dir[1024];
+
+static void smb_exit(void)
+{
+    DIR *d;
+    struct dirent *de;
+    char filename[1024];
+
+    /* erase all the files in the directory */
+    d = opendir(smb_dir);
+    for(;;) {
+        de = readdir(d);
+        if (!de)
+            break;
+        if (strcmp(de->d_name, ".") != 0 &&
+            strcmp(de->d_name, "..") != 0) {
+            snprintf(filename, sizeof(filename), "%s/%s", 
+                     smb_dir, de->d_name);
+            unlink(filename);
+        }
+    }
+    closedir(d);
+    rmdir(smb_dir);
+}
+
+/* automatic user mode samba server configuration */
+void net_slirp_smb(const char *exported_dir)
+{
+    char smb_conf[1024];
+    char smb_cmdline[1024];
+    FILE *f;
+
+    if (!slirp_inited) {
+        slirp_inited = 1;
+        slirp_init();
+    }
+
+    /* XXX: better tmp dir construction */
+    snprintf(smb_dir, sizeof(smb_dir), "/tmp/qemu-smb.%d", getpid());
+    if (mkdir(smb_dir, 0700) < 0) {
+        fprintf(stderr, "qemu: could not create samba server dir '%s'\n", smb_dir);
+        exit(1);
+    }
+    snprintf(smb_conf, sizeof(smb_conf), "%s/%s", smb_dir, "smb.conf");
+    
+    f = fopen(smb_conf, "w");
+    if (!f) {
+        fprintf(stderr, "qemu: could not create samba server configuration file '%s'\n", smb_conf);
+        exit(1);
+    }
+    fprintf(f, 
+            "[global]\n"
+            "pid directory=%s\n"
+            "lock directory=%s\n"
+            "log file=%s/log.smbd\n"
+            "smb passwd file=%s/smbpasswd\n"
+            "security = share\n"
+            "[qemu]\n"
+            "path=%s\n"
+            "read only=no\n"
+            "guest ok=yes\n",
+            smb_dir,
+            smb_dir,
+            smb_dir,
+            smb_dir,
+            exported_dir
+            );
+    fclose(f);
+    atexit(smb_exit);
+
+    snprintf(smb_cmdline, sizeof(smb_cmdline), "/usr/sbin/smbd -s %s",
+             smb_conf);
+    
+    slirp_add_exec(0, smb_cmdline, 4, 139);
+}
+
+#endif /* !defined(_WIN32) */
+
+#endif /* CONFIG_SLIRP */
+
+#if !defined(_WIN32)
+#ifdef _BSD
+static int tun_open(char *ifname, int ifname_size)
+{
+    int fd;
+    char *dev;
+    struct stat s;
+
+    fd = open("/dev/tap", O_RDWR);
+    if (fd < 0) {
+        fprintf(stderr, "warning: could not open /dev/tap: no virtual network emulation\n");
+        return -1;
+    }
+
+    fstat(fd, &s);
+    dev = devname(s.st_rdev, S_IFCHR);
+    pstrcpy(ifname, ifname_size, dev);
+
+    fcntl(fd, F_SETFL, O_NONBLOCK);
+    return fd;
+}
+#else
+static int tun_open(char *ifname, int ifname_size)
+{
+    struct ifreq ifr;
+    int fd, ret;
+    
+    fd = open("/dev/net/tun", O_RDWR);
+    if (fd < 0) {
+        fprintf(stderr, "warning: could not open /dev/net/tun: no virtual network emulation\n");
+        return -1;
+    }
+    memset(&ifr, 0, sizeof(ifr));
+    ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
+    pstrcpy(ifr.ifr_name, IFNAMSIZ, "tun%d");
+    ret = ioctl(fd, TUNSETIFF, (void *) &ifr);
+    if (ret != 0) {
+        fprintf(stderr, "warning: could not configure /dev/net/tun: no virtual network emulation\n");
+        close(fd);
+        return -1;
+    }
+    printf("Connected to host network interface: %s\n", ifr.ifr_name);
+    pstrcpy(ifname, ifname_size, ifr.ifr_name);
+    fcntl(fd, F_SETFL, O_NONBLOCK);
+    return fd;
+}
+#endif
+
+static void tun_send_packet(NetDriverState *nd, const uint8_t *buf, int size)
+{
+    write(nd->fd, buf, size);
+}
+
+static void tun_add_read_packet(NetDriverState *nd, 
+                                IOCanRWHandler *fd_can_read, 
+                                IOReadHandler *fd_read, void *opaque)
+{
+    qemu_add_fd_read_handler(nd->fd, fd_can_read, fd_read, opaque);
+}
+
+static int net_tun_init(NetDriverState *nd)
+{
+    int pid, status;
+    char *args[3];
+    char **parg;
+
+    nd->fd = tun_open(nd->ifname, sizeof(nd->ifname));
+    if (nd->fd < 0)
+        return -1;
+
+    /* try to launch network init script */
+    pid = fork();
+    if (pid >= 0) {
+        if (pid == 0) {
+            parg = args;
+            *parg++ = network_script;
+            *parg++ = nd->ifname;
+            *parg++ = NULL;
+            execv(network_script, args);
+            exit(1);
+        }
+        while (waitpid(pid, &status, 0) != pid);
+        if (!WIFEXITED(status) ||
+            WEXITSTATUS(status) != 0) {
+            fprintf(stderr, "%s: could not launch network script\n",
+                    network_script);
+        }
+    }
+    nd->send_packet = tun_send_packet;
+    nd->add_read_packet = tun_add_read_packet;
+    return 0;
+}
+
+static int net_fd_init(NetDriverState *nd, int fd)
+{
+    nd->fd = fd;
+    nd->send_packet = tun_send_packet;
+    nd->add_read_packet = tun_add_read_packet;
+    pstrcpy(nd->ifname, sizeof(nd->ifname), "tunfd");
+    return 0;
+}
+
+#endif /* !_WIN32 */
+
+/***********************************************************/
+/* dumb display */
+
+static void dumb_update(DisplayState *ds, int x, int y, int w, int h)
+{
+}
+
+static void dumb_resize(DisplayState *ds, int w, int h)
+{
+}
+
+static void dumb_refresh(DisplayState *ds)
+{
+    vga_update_display();
+}
+
+void dumb_display_init(DisplayState *ds)
+{
+    ds->data = NULL;
+    ds->linesize = 0;
+    ds->depth = 0;
+    ds->dpy_update = dumb_update;
+    ds->dpy_resize = dumb_resize;
+    ds->dpy_refresh = dumb_refresh;
+}
+
+#if !defined(CONFIG_SOFTMMU)
+/***********************************************************/
+/* cpu signal handler */
+static void host_segv_handler(int host_signum, siginfo_t *info, 
+                              void *puc)
+{
+    abort();
+}
+#endif
+
+/***********************************************************/
+/* I/O handling */
+
+#define MAX_IO_HANDLERS 64
+
+typedef struct IOHandlerRecord {
+    int fd;
+    IOCanRWHandler *fd_can_read;
+    IOReadHandler *fd_read;
+    void *opaque;
+    /* temporary data */
+    struct pollfd *ufd;
+    int max_size;
+    struct IOHandlerRecord *next;
+} IOHandlerRecord;
+
+static IOHandlerRecord *first_io_handler;
+
+int qemu_add_fd_read_handler(int fd, IOCanRWHandler *fd_can_read, 
+                             IOReadHandler *fd_read, void *opaque)
+{
+    IOHandlerRecord *ioh;
+
+    ioh = qemu_mallocz(sizeof(IOHandlerRecord));
+    if (!ioh)
+        return -1;
+    ioh->fd = fd;
+    ioh->fd_can_read = fd_can_read;
+    ioh->fd_read = fd_read;
+    ioh->opaque = opaque;
+    ioh->next = first_io_handler;
+    first_io_handler = ioh;
+    return 0;
+}
+
+void qemu_del_fd_read_handler(int fd)
+{
+    IOHandlerRecord **pioh, *ioh;
+
+    pioh = &first_io_handler;
+    for(;;) {
+        ioh = *pioh;
+        if (ioh == NULL)
+            break;
+        if (ioh->fd == fd) {
+            *pioh = ioh->next;
+            break;
+        }
+        pioh = &ioh->next;
+    }
+}
+
+/***********************************************************/
+/* savevm/loadvm support */
+
+void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size)
+{
+    fwrite(buf, 1, size, f);
+}
+
+void qemu_put_byte(QEMUFile *f, int v)
+{
+    fputc(v, f);
+}
+
+void qemu_put_be16(QEMUFile *f, unsigned int v)
+{
+    qemu_put_byte(f, v >> 8);
+    qemu_put_byte(f, v);
+}
+
+void qemu_put_be32(QEMUFile *f, unsigned int v)
+{
+    qemu_put_byte(f, v >> 24);
+    qemu_put_byte(f, v >> 16);
+    qemu_put_byte(f, v >> 8);
+    qemu_put_byte(f, v);
+}
+
+void qemu_put_be64(QEMUFile *f, uint64_t v)
+{
+    qemu_put_be32(f, v >> 32);
+    qemu_put_be32(f, v);
+}
+
+int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size)
+{
+    return fread(buf, 1, size, f);
+}
+
+int qemu_get_byte(QEMUFile *f)
+{
+    int v;
+    v = fgetc(f);
+    if (v == EOF)
+        return 0;
+    else
+        return v;
+}
+
+unsigned int qemu_get_be16(QEMUFile *f)
+{
+    unsigned int v;
+    v = qemu_get_byte(f) << 8;
+    v |= qemu_get_byte(f);
+    return v;
+}
+
+unsigned int qemu_get_be32(QEMUFile *f)
+{
+    unsigned int v;
+    v = qemu_get_byte(f) << 24;
+    v |= qemu_get_byte(f) << 16;
+    v |= qemu_get_byte(f) << 8;
+    v |= qemu_get_byte(f);
+    return v;
+}
+
+uint64_t qemu_get_be64(QEMUFile *f)
+{
+    uint64_t v;
+    v = (uint64_t)qemu_get_be32(f) << 32;
+    v |= qemu_get_be32(f);
+    return v;
+}
+
+int64_t qemu_ftell(QEMUFile *f)
+{
+    return ftell(f);
+}
+
+int64_t qemu_fseek(QEMUFile *f, int64_t pos, int whence)
+{
+    if (fseek(f, pos, whence) < 0)
+        return -1;
+    return ftell(f);
+}
+
+typedef struct SaveStateEntry {
+    char idstr[256];
+    int instance_id;
+    int version_id;
+    SaveStateHandler *save_state;
+    LoadStateHandler *load_state;
+    void *opaque;
+    struct SaveStateEntry *next;
+} SaveStateEntry;
+
+static SaveStateEntry *first_se;
+
+int register_savevm(const char *idstr, 
+                    int instance_id, 
+                    int version_id,
+                    SaveStateHandler *save_state,
+                    LoadStateHandler *load_state,
+                    void *opaque)
+{
+    SaveStateEntry *se, **pse;
+
+    se = qemu_malloc(sizeof(SaveStateEntry));
+    if (!se)
+        return -1;
+    pstrcpy(se->idstr, sizeof(se->idstr), idstr);
+    se->instance_id = instance_id;
+    se->version_id = version_id;
+    se->save_state = save_state;
+    se->load_state = load_state;
+    se->opaque = opaque;
+    se->next = NULL;
+
+    /* add at the end of list */
+    pse = &first_se;
+    while (*pse != NULL)
+        pse = &(*pse)->next;
+    *pse = se;
+    return 0;
+}
+
+#define QEMU_VM_FILE_MAGIC   0x5145564d
+#define QEMU_VM_FILE_VERSION 0x00000001
+
+int qemu_savevm(const char *filename)
+{
+    SaveStateEntry *se;
+    QEMUFile *f;
+    int len, len_pos, cur_pos, saved_vm_running, ret;
+
+    saved_vm_running = vm_running;
+    vm_stop(0);
+
+    f = fopen(filename, "wb");
+    if (!f) {
+        ret = -1;
+        goto the_end;
+    }
+
+    qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
+    qemu_put_be32(f, QEMU_VM_FILE_VERSION);
+
+    for(se = first_se; se != NULL; se = se->next) {
+        /* ID string */
+        len = strlen(se->idstr);
+        qemu_put_byte(f, len);
+        qemu_put_buffer(f, se->idstr, len);
+
+        qemu_put_be32(f, se->instance_id);
+        qemu_put_be32(f, se->version_id);
+
+        /* record size: filled later */
+        len_pos = ftell(f);
+        qemu_put_be32(f, 0);
+        
+        se->save_state(f, se->opaque);
+
+        /* fill record size */
+        cur_pos = ftell(f);
+        len = ftell(f) - len_pos - 4;
+        fseek(f, len_pos, SEEK_SET);
+        qemu_put_be32(f, len);
+        fseek(f, cur_pos, SEEK_SET);
+    }
+
+    fclose(f);
+    ret = 0;
+ the_end:
+    if (saved_vm_running)
+        vm_start();
+    return ret;
+}
+
+static SaveStateEntry *find_se(const char *idstr, int instance_id)
+{
+    SaveStateEntry *se;
+
+    for(se = first_se; se != NULL; se = se->next) {
+        if (!strcmp(se->idstr, idstr) && 
+            instance_id == se->instance_id)
+            return se;
+    }
+    return NULL;
+}
+
+int qemu_loadvm(const char *filename)
+{
+    SaveStateEntry *se;
+    QEMUFile *f;
+    int len, cur_pos, ret, instance_id, record_len, version_id;
+    int saved_vm_running;
+    unsigned int v;
+    char idstr[256];
+    
+    saved_vm_running = vm_running;
+    vm_stop(0);
+
+    f = fopen(filename, "rb");
+    if (!f) {
+        ret = -1;
+        goto the_end;
+    }
+
+    v = qemu_get_be32(f);
+    if (v != QEMU_VM_FILE_MAGIC)
+        goto fail;
+    v = qemu_get_be32(f);
+    if (v != QEMU_VM_FILE_VERSION) {
+    fail:
+        fclose(f);
+        ret = -1;
+        goto the_end;
+    }
+    for(;;) {
+#if defined (DO_TB_FLUSH)
+        tb_flush(global_env);
+#endif
+        len = qemu_get_byte(f);
+        if (feof(f))
+            break;
+        qemu_get_buffer(f, idstr, len);
+        idstr[len] = '\0';
+        instance_id = qemu_get_be32(f);
+        version_id = qemu_get_be32(f);
+        record_len = qemu_get_be32(f);
+#if 0
+        printf("idstr=%s instance=0x%x version=%d len=%d\n", 
+               idstr, instance_id, version_id, record_len);
+#endif
+        cur_pos = ftell(f);
+        se = find_se(idstr, instance_id);
+        if (!se) {
+            fprintf(stderr, "qemu: warning: instance 0x%x of device '%s' not present in current VM\n", 
+                    instance_id, idstr);
+        } else {
+            ret = se->load_state(f, se->opaque, version_id);
+            if (ret < 0) {
+                fprintf(stderr, "qemu: warning: error while loading state for instance 0x%x of device '%s'\n", 
+                        instance_id, idstr);
+            }
+        }
+        /* always seek to exact end of record */
+        qemu_fseek(f, cur_pos + record_len, SEEK_SET);
+    }
+    fclose(f);
+    ret = 0;
+ the_end:
+    if (saved_vm_running)
+        vm_start();
+    return ret;
+}
+
+/***********************************************************/
+/* main execution loop */
+
+void gui_update(void *opaque)
+{
+    display_state.dpy_refresh(&display_state);
+    qemu_mod_timer(gui_timer, GUI_REFRESH_INTERVAL + qemu_get_clock(rt_clock));
+}
+void polling_handler(void *opaque)
+{
+#ifndef _WIN32
+    struct pollfd ufds[MAX_IO_HANDLERS + 1], *pf;
+    IOHandlerRecord *ioh, *ioh_next;
+    uint8_t buf[4096];
+    int n, max_size;
+#endif
+    int timeout = 0;
+    int ret;
+
+#ifdef _WIN32
+        if (timeout > 0)
+            Sleep(timeout);
+#else
+        /* poll any events */
+        /* XXX: separate device handlers from system ones */
+        pf = ufds;
+        for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) {
+            if (!ioh->fd_can_read) {
+                max_size = 0;
+                pf->fd = ioh->fd;
+                pf->events = POLLIN;
+                ioh->ufd = pf;
+                pf++;
+            } else {
+                max_size = ioh->fd_can_read(ioh->opaque);
+                if (max_size > 0) {
+                    if (max_size > sizeof(buf))
+                        max_size = sizeof(buf);
+                    pf->fd = ioh->fd;
+                    pf->events = POLLIN;
+                    ioh->ufd = pf;
+                    pf++;
+                } else {
+                    ioh->ufd = NULL;
+                }
+            }
+            ioh->max_size = max_size;
+        }
+        
+        ret = poll(ufds, pf - ufds, timeout);
+        if (ret > 0) {
+            /* XXX: better handling of removal */
+            for(ioh = first_io_handler; ioh != NULL; ioh = ioh_next) {
+                ioh_next = ioh->next;
+                pf = ioh->ufd;
+                if (pf) {
+                    if (pf->revents & POLLIN) {
+                        if (ioh->max_size == 0) {
+                            /* just a read event */
+                            ioh->fd_read(ioh->opaque, NULL, 0);
+                        } else {
+                            n = read(ioh->fd, buf, ioh->max_size);
+                            if (n >= 0) {
+                                ioh->fd_read(ioh->opaque, buf, n);
+                            } else if (errno != EAGAIN) {
+                                ioh->fd_read(ioh->opaque, NULL, -errno);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+#endif /* !defined(_WIN32) */
+
+    qemu_mod_timer(polling_timer, POLLING_INTERVAL + qemu_get_clock(rt_clock));
+}
+
+
+/* XXX: support several handlers */
+VMStopHandler *vm_stop_cb;
+VMStopHandler *vm_stop_opaque;
+
+int qemu_add_vm_stop_handler(VMStopHandler *cb, void *opaque)
+{
+    vm_stop_cb = cb;
+    vm_stop_opaque = opaque;
+    return 0;
+}
+
+void qemu_del_vm_stop_handler(VMStopHandler *cb, void *opaque)
+{
+    vm_stop_cb = NULL;
+}
+
+void vm_start(void)
+{
+    if (!vm_running) {
+        cpu_enable_ticks();
+        vm_running = 1;
+    }
+}
+
+void vm_stop(int reason) 
+{
+    if (vm_running) {
+        cpu_disable_ticks();
+        vm_running = 0;
+        if (reason != 0) {
+            if (vm_stop_cb) {
+                vm_stop_cb(vm_stop_opaque, reason);
+            }
+        }
+    }
+}
+
+/* reset/shutdown handler */
+
+typedef struct QEMUResetEntry {
+    QEMUResetHandler *func;
+    void *opaque;
+    struct QEMUResetEntry *next;
+} QEMUResetEntry;
+
+static QEMUResetEntry *first_reset_entry;
+static int reset_requested;
+int shutdown_requested;
+
+void qemu_register_reset(QEMUResetHandler *func, void *opaque)
+{
+    QEMUResetEntry **pre, *re;
+
+    pre = &first_reset_entry;
+    while (*pre != NULL)
+        pre = &(*pre)->next;
+    re = qemu_mallocz(sizeof(QEMUResetEntry));
+    re->func = func;
+    re->opaque = opaque;
+    re->next = NULL;
+    *pre = re;
+}
+
+void qemu_system_reset(void)
+{
+    QEMUResetEntry *re;
+
+    /* reset all devices */
+    for(re = first_reset_entry; re != NULL; re = re->next) {
+        re->func(re->opaque);
+    }
+}
+
+void qemu_system_reset_request(void)
+{
+    reset_requested = 1;
+    cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
+}
+
+void qemu_system_shutdown_request(void)
+{
+    shutdown_requested = 1;
+    cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
+}
+
+void main_loop_wait(int timeout)
+{
+        if (vm_running) {
+            qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL], 
+                            qemu_get_clock(vm_clock));
+            /* run dma transfers, if any */
+            DMA_run();
+        }
+
+        /* real time timers */
+        qemu_run_timers(&active_timers[QEMU_TIMER_REALTIME], 
+                        qemu_get_clock(rt_clock));
+}
+
+void help(void)
+{
+    printf("QEMU PC emulator version " QEMU_VERSION ", Copyright (c) 2003-2004 Fabrice Bellard\n"
+           "usage: %s [options] [disk_image]\n"
+           "\n"
+           "'disk_image' is a raw hard image image for IDE hard disk 0\n"
+           "\n"
+           "Standard options:\n"
+           "-fda/-fdb file  use 'file' as floppy disk 0/1 image\n"
+           "-hda/-hdb file  use 'file' as IDE hard disk 0/1 image\n"
+           "-hdc/-hdd file  use 'file' as IDE hard disk 2/3 image\n"
+           "-cdrom file     use 'file' as IDE cdrom image (cdrom is ide1 master)\n"
+           "-boot [a|c|d]   boot on floppy (a), hard disk (c) or CD-ROM (d)\n"
+          "-snapshot       write to temporary files instead of disk image files\n"
+           "-m megs         set virtual RAM size to megs MB [default=%d]\n"
+           "-nographic      disable graphical output and redirect serial I/Os to console\n"
+#ifdef CONFIG_VNC
+          "-vnc            use vnc instead of sdl\n"
+#ifdef CONFIG_SDL
+          "-vnc-and-sdl    use vnc and sdl simultaneously\n"
+#endif
+#endif
+          "-k <language>   use keyboard layout (for example \"fr\" for french)\n"
+           "-enable-audio   enable audio support\n"
+           "-localtime      set the real time clock to local time [default=utc]\n"
+           "-full-screen    start in full screen\n"
+#ifdef TARGET_PPC
+           "-prep           Simulate a PREP system (default is PowerMAC)\n"
+           "-g WxH[xDEPTH]  Set the initial VGA graphic mode\n"
+#endif
+           "\n"
+           "Network options:\n"
+           "-nics n         simulate 'n' network cards [default=1]\n"
+           "-macaddr addr   set the mac address of the first interface\n"
+           "-n script       set tap/tun network init script [default=%s]\n"
+           "-tun-fd fd      use this fd as already opened tap/tun interface\n"
+#ifdef CONFIG_SLIRP
+           "-user-net       use user mode network stack [default if no tap/tun script]\n"
+           "-tftp prefix    allow tftp access to files starting with prefix [-user-net]\n"
+#ifndef _WIN32
+           "-smb dir        allow SMB access to files in 'dir' [-user-net]\n"
+#endif
+           "-redir [tcp|udp]:host-port:[guest-host]:guest-port\n"
+           "                redirect TCP or UDP connections from host to guest [-user-net]\n"
+#endif
+           "-dummy-net      use dummy network stack\n"
+           "\n"
+           "Linux boot specific:\n"
+           "-kernel bzImage use 'bzImage' as kernel image\n"
+           "-append cmdline use 'cmdline' as kernel command line\n"
+           "-initrd file    use 'file' as initial ram disk\n"
+           "\n"
+           "Debug/Expert options:\n"
+           "-monitor dev    redirect the monitor to char device 'dev'\n"
+           "-serial dev     redirect the serial port to char device 'dev'\n"
+           "-S              freeze CPU at startup (use 'c' to start execution)\n"
+           "-s              wait gdb connection to port %d\n"
+           "-p port         ioreq port for xen\n"
+           "-d domain      domain that we're serving\n"
+           "-hdachs c,h,s   force hard disk 0 geometry (usually qemu can guess it)\n"
+           "-L path         set the directory for the BIOS and VGA BIOS\n"
+#ifdef USE_CODE_COPY
+           "-no-code-copy   disable code copy acceleration\n"
+#endif
+#ifdef TARGET_I386
+           "-isa            simulate an ISA-only system (default is PCI system)\n"
+           "-std-vga        simulate a standard VGA card with VESA Bochs Extensions\n"
+           "                (default is CL-GD5446 PCI VGA)\n"
+#endif
+           "-loadvm file    start right away with a saved state (loadvm in monitor)\n"
+           "\n"
+           "During emulation, the following keys are useful:\n"
+           "ctrl-alt-f      toggle full screen\n"
+           "ctrl-alt-n      switch to virtual console 'n'\n"
+           "ctrl-alt        toggle mouse and keyboard grab\n"
+           "\n"
+           "When using -nographic, press 'ctrl-a h' to get some help.\n"
+           ,
+#ifdef CONFIG_SOFTMMU
+           "qemu",
+#else
+           "qemu-fast",
+#endif
+           DEFAULT_RAM_SIZE,
+           DEFAULT_NETWORK_SCRIPT,
+           DEFAULT_GDBSTUB_PORT);
+#ifndef CONFIG_SOFTMMU
+    printf("\n"
+           "NOTE: this version of QEMU is faster but it needs slightly patched OSes to\n"
+           "work. Please use the 'qemu' executable to have a more accurate (but slower)\n"
+           "PC emulation.\n");
+#endif
+    exit(1);
+}
+
+#define HAS_ARG 0x0001
+
+enum {
+    QEMU_OPTION_h,
+
+    QEMU_OPTION_fda,
+    QEMU_OPTION_fdb,
+    QEMU_OPTION_hda,
+    QEMU_OPTION_hdb,
+    QEMU_OPTION_hdc,
+    QEMU_OPTION_hdd,
+    QEMU_OPTION_cdrom,
+    QEMU_OPTION_boot,
+    QEMU_OPTION_snapshot,
+    QEMU_OPTION_m,
+    QEMU_OPTION_nographic,
+#ifdef CONFIG_VNC
+    QEMU_OPTION_vnc,
+#ifdef CONFIG_SDL
+    QEMU_OPTION_vnc_and_sdl,
+#endif
+#endif
+    QEMU_OPTION_enable_audio,
+
+    QEMU_OPTION_nics,
+    QEMU_OPTION_macaddr,
+    QEMU_OPTION_n,
+    QEMU_OPTION_tun_fd,
+    QEMU_OPTION_user_net,
+    QEMU_OPTION_tftp,
+    QEMU_OPTION_smb,
+    QEMU_OPTION_redir,
+    QEMU_OPTION_dummy_net,
+
+    QEMU_OPTION_kernel,
+    QEMU_OPTION_append,
+    QEMU_OPTION_initrd,
+
+    QEMU_OPTION_S,
+    QEMU_OPTION_s,
+    QEMU_OPTION_p,
+    QEMU_OPTION_d,
+    QEMU_OPTION_l,
+    QEMU_OPTION_hdachs,
+    QEMU_OPTION_L,
+    QEMU_OPTION_no_code_copy,
+    QEMU_OPTION_pci,
+    QEMU_OPTION_isa,
+    QEMU_OPTION_prep,
+    QEMU_OPTION_k,
+    QEMU_OPTION_localtime,
+    QEMU_OPTION_cirrusvga,
+    QEMU_OPTION_g,
+    QEMU_OPTION_std_vga,
+    QEMU_OPTION_monitor,
+    QEMU_OPTION_serial,
+    QEMU_OPTION_loadvm,
+    QEMU_OPTION_full_screen,
+};
+
+typedef struct QEMUOption {
+    const char *name;
+    int flags;
+    int index;
+} QEMUOption;
+
+const QEMUOption qemu_options[] = {
+    { "h", 0, QEMU_OPTION_h },
+
+    { "fda", HAS_ARG, QEMU_OPTION_fda },
+    { "fdb", HAS_ARG, QEMU_OPTION_fdb },
+    { "hda", HAS_ARG, QEMU_OPTION_hda },
+    { "hdb", HAS_ARG, QEMU_OPTION_hdb },
+    { "hdc", HAS_ARG, QEMU_OPTION_hdc },
+    { "hdd", HAS_ARG, QEMU_OPTION_hdd },
+    { "cdrom", HAS_ARG, QEMU_OPTION_cdrom },
+    { "boot", HAS_ARG, QEMU_OPTION_boot },
+    { "snapshot", 0, QEMU_OPTION_snapshot },
+    { "m", HAS_ARG, QEMU_OPTION_m },
+    { "nographic", 0, QEMU_OPTION_nographic },
+#ifdef CONFIG_VNC
+    { "vnc", 0, QEMU_OPTION_vnc },
+#ifdef CONFIG_SDL
+    { "vnc-and-sdl", 0, QEMU_OPTION_vnc_and_sdl },
+#endif
+#endif
+    { "k", HAS_ARG, QEMU_OPTION_k },
+    { "enable-audio", 0, QEMU_OPTION_enable_audio },
+
+    { "nics", HAS_ARG, QEMU_OPTION_nics},
+    { "macaddr", HAS_ARG, QEMU_OPTION_macaddr},
+    { "n", HAS_ARG, QEMU_OPTION_n },
+    { "tun-fd", HAS_ARG, QEMU_OPTION_tun_fd },
+#ifdef CONFIG_SLIRP
+    { "user-net", 0, QEMU_OPTION_user_net },
+    { "tftp", HAS_ARG, QEMU_OPTION_tftp },
+#ifndef _WIN32
+    { "smb", HAS_ARG, QEMU_OPTION_smb },
+#endif
+    { "redir", HAS_ARG, QEMU_OPTION_redir },
+#endif
+    { "dummy-net", 0, QEMU_OPTION_dummy_net },
+
+    { "kernel", HAS_ARG, QEMU_OPTION_kernel },
+    { "append", HAS_ARG, QEMU_OPTION_append },
+    { "initrd", HAS_ARG, QEMU_OPTION_initrd },
+
+    { "S", 0, QEMU_OPTION_S },
+    { "s", 0, QEMU_OPTION_s },
+    { "p", HAS_ARG, QEMU_OPTION_p },
+    { "d", HAS_ARG, QEMU_OPTION_d },
+    { "l", HAS_ARG, QEMU_OPTION_l },
+    { "hdachs", HAS_ARG, QEMU_OPTION_hdachs },
+    { "L", HAS_ARG, QEMU_OPTION_L },
+    { "no-code-copy", 0, QEMU_OPTION_no_code_copy },
+#ifdef TARGET_PPC
+    { "prep", 0, QEMU_OPTION_prep },
+    { "g", 1, QEMU_OPTION_g },
+#endif
+    { "localtime", 0, QEMU_OPTION_localtime },
+    { "isa", 0, QEMU_OPTION_isa },
+    { "std-vga", 0, QEMU_OPTION_std_vga },
+    { "monitor", 1, QEMU_OPTION_monitor },
+    { "serial", 1, QEMU_OPTION_serial },
+    { "loadvm", HAS_ARG, QEMU_OPTION_loadvm },
+    { "full-screen", 0, QEMU_OPTION_full_screen },
+    
+    /* temporary options */
+    { "pci", 0, QEMU_OPTION_pci },
+    { "cirrusvga", 0, QEMU_OPTION_cirrusvga },
+    { NULL },
+};
+
+#if defined (TARGET_I386) && defined(USE_CODE_COPY)
+
+/* this stack is only used during signal handling */
+#define SIGNAL_STACK_SIZE 32768
+
+static uint8_t *signal_stack;
+
+#endif
+
+#define NET_IF_TUN   0
+#define NET_IF_USER  1
+#define NET_IF_DUMMY 2
+
+int main(int argc, char **argv)
+{
+#ifdef CONFIG_GDBSTUB
+    int use_gdbstub, gdbstub_port;
+#endif
+    int i, has_cdrom;
+    int snapshot, linux_boot;
+    CPUState *env;
+    const char *initrd_filename;
+    const char *hd_filename[MAX_DISKS], *fd_filename[MAX_FD];
+    const char *kernel_filename, *kernel_cmdline;
+    DisplayState *ds = &display_state;
+    int cyls, heads, secs;
+    int start_emulation = 1;
+    uint8_t macaddr[6];
+    int net_if_type, nb_tun_fds, tun_fds[MAX_NICS];
+    int optind;
+    const char *r, *optarg;
+    CharDriverState *monitor_hd;
+    char monitor_device[128];
+    char serial_devices[MAX_SERIAL_PORTS][128];
+    int serial_device_index;
+    const char *loadvm = NULL;
+    unsigned long nr_pages, *page_array;
+    extern void *shared_page;
+    /* change the qemu-dm to daemon, just like bochs dm */
+//    daemon(0, 0);
+    
+#if !defined(CONFIG_SOFTMMU)
+    /* we never want that malloc() uses mmap() */
+    mallopt(M_MMAP_THRESHOLD, 4096 * 1024);
+#endif
+    initrd_filename = NULL;
+    for(i = 0; i < MAX_FD; i++)
+        fd_filename[i] = NULL;
+    for(i = 0; i < MAX_DISKS; i++)
+        hd_filename[i] = NULL;
+    ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
+    vga_ram_size = VGA_RAM_SIZE;
+    bios_size = BIOS_SIZE;
+    pstrcpy(network_script, sizeof(network_script), DEFAULT_NETWORK_SCRIPT);
+#ifdef CONFIG_GDBSTUB
+    use_gdbstub = 0;
+    gdbstub_port = DEFAULT_GDBSTUB_PORT;
+#endif
+    snapshot = 0;
+    nographic = 0;
+    usevnc = 0;
+    kernel_filename = NULL;
+    kernel_cmdline = "";
+    has_cdrom = 1;
+    cyls = heads = secs = 0;
+    pstrcpy(monitor_device, sizeof(monitor_device), "vc");
+
+    pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "vc");
+    for(i = 1; i < MAX_SERIAL_PORTS; i++)
+        serial_devices[i][0] = '\0';
+    serial_device_index = 0;
+    
+    nb_tun_fds = 0;
+    net_if_type = -1;
+    nb_nics = 1;
+    /* default mac address of the first network interface */
+    macaddr[0] = 0x52;
+    macaddr[1] = 0x54;
+    macaddr[2] = 0x00;
+    macaddr[3] = 0x12;
+    macaddr[4] = 0x34;
+    macaddr[5] = 0x56;
+    
+    optind = 1;
+    for(;;) {
+        if (optind >= argc)
+            break;
+        r = argv[optind];
+        if (r[0] != '-') {
+            hd_filename[0] = argv[optind++];
+        } else {
+            const QEMUOption *popt;
+
+            optind++;
+            popt = qemu_options;
+            for(;;) {
+                if (!popt->name) {
+                    fprintf(stderr, "%s: invalid option -- '%s'\n", 
+                            argv[0], r);
+                    exit(1);
+                }
+                if (!strcmp(popt->name, r + 1))
+                    break;
+                popt++;
+            }
+            if (popt->flags & HAS_ARG) {
+                if (optind >= argc) {
+                    fprintf(stderr, "%s: option '%s' requires an argument\n",
+                            argv[0], r);
+                    exit(1);
+                }
+                optarg = argv[optind++];
+            } else {
+                optarg = NULL;
+            }
+
+            switch(popt->index) {
+            case QEMU_OPTION_initrd:
+                initrd_filename = optarg;
+                break;
+            case QEMU_OPTION_hda:
+                hd_filename[0] = optarg;
+                break;
+            case QEMU_OPTION_hdb:
+                hd_filename[1] = optarg;
+                break;
+            case QEMU_OPTION_snapshot:
+                snapshot = 1;
+                break;
+            case QEMU_OPTION_hdachs:
+                {
+                    const char *p;
+                    p = optarg;
+                    cyls = strtol(p, (char **)&p, 0);
+                    if (*p != ',')
+                        goto chs_fail;
+                    p++;
+                    heads = strtol(p, (char **)&p, 0);
+                    if (*p != ',')
+                        goto chs_fail;
+                    p++;
+                    secs = strtol(p, (char **)&p, 0);
+                    if (*p != '\0') {
+                    chs_fail:
+                        cyls = 0;
+                    }
+                }
+                break;
+            case QEMU_OPTION_nographic:
+                pstrcpy(monitor_device, sizeof(monitor_device), "stdio");
+                pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "stdio");
+                nographic = 1;
+                break;
+#ifdef CONFIG_VNC
+           case QEMU_OPTION_vnc:
+               usevnc = 1;
+               break;
+#ifdef CONFIG_SDL
+           case QEMU_OPTION_vnc_and_sdl:
+               usevnc = 2;
+               break;
+#endif
+#endif
+            case QEMU_OPTION_kernel:
+                kernel_filename = optarg;
+                break;
+            case QEMU_OPTION_append:
+                kernel_cmdline = optarg;
+                break;
+           case QEMU_OPTION_tun_fd:
+                {
+                    const char *p;
+                    int fd;
+                    net_if_type = NET_IF_TUN;
+                    if (nb_tun_fds < MAX_NICS) {
+                        fd = strtol(optarg, (char **)&p, 0);
+                        if (*p != '\0') {
+                            fprintf(stderr, "qemu: invalid fd for network interface %d\n", nb_tun_fds);
+                            exit(1);
+                        }
+                        tun_fds[nb_tun_fds++] = fd;
+                    }
+                }
+               break;
+            case QEMU_OPTION_hdc:
+                hd_filename[2] = optarg;
+                has_cdrom = 0;
+                break;
+            case QEMU_OPTION_hdd:
+                hd_filename[3] = optarg;
+                break;
+            case QEMU_OPTION_cdrom:
+                hd_filename[2] = optarg;
+                has_cdrom = 1;
+                break;
+            case QEMU_OPTION_boot:
+                boot_device = optarg[0];
+                if (boot_device != 'a' && 
+                    boot_device != 'c' && boot_device != 'd') {
+                    fprintf(stderr, "qemu: invalid boot device '%c'\n", boot_device);
+                    exit(1);
+                }
+                break;
+            case QEMU_OPTION_fda:
+                fd_filename[0] = optarg;
+                break;
+            case QEMU_OPTION_fdb:
+                fd_filename[1] = optarg;
+                break;
+            case QEMU_OPTION_nics:
+                nb_nics = atoi(optarg);
+                if (nb_nics < 0 || nb_nics > MAX_NICS) {
+                    fprintf(stderr, "qemu: invalid number of network interfaces\n");
+                    exit(1);
+                }
+                break;
+            case QEMU_OPTION_macaddr:
+                {
+                    const char *p;
+                    int i;
+                    p = optarg;
+                    for(i = 0; i < 6; i++) {
+                        macaddr[i] = strtol(p, (char **)&p, 16);
+                        if (i == 5) {
+                            if (*p != '\0') 
+                                goto macaddr_error;
+                        } else {
+                            if (*p != ':') {
+                            macaddr_error:
+                                fprintf(stderr, "qemu: invalid syntax for ethernet address\n");
+                                exit(1);
+                            }
+                            p++;
+                        }
+                    }
+                }
+                break;
+#ifdef CONFIG_SLIRP
+            case QEMU_OPTION_tftp:
+               tftp_prefix = optarg;
+                break;
+#ifndef _WIN32
+            case QEMU_OPTION_smb:
+               net_slirp_smb(optarg);
+                break;
+#endif
+            case QEMU_OPTION_user_net:
+                net_if_type = NET_IF_USER;
+                break;
+            case QEMU_OPTION_redir:
+                net_slirp_redir(optarg);                
+                break;
+#endif
+            case QEMU_OPTION_dummy_net:
+                net_if_type = NET_IF_DUMMY;
+                break;
+            case QEMU_OPTION_enable_audio:
+                audio_enabled = 1;
+                break;
+            case QEMU_OPTION_h:
+                help();
+                break;
+            case QEMU_OPTION_m:
+                ram_size = atoi(optarg) * 1024 * 1024;
+                if (ram_size <= 0)
+                    help();
+                break;
+            case QEMU_OPTION_d:
+                {
+                  domid = atoi(optarg);
+                  printf("domid: %d\n", domid);
+                }
+                break;
+
+            case QEMU_OPTION_p:
+                {
+                  extern short ioreq_port;
+                  ioreq_port = atoi(optarg);
+                  printf("port: %d\n", ioreq_port);
+                }
+                break;
+            case QEMU_OPTION_l:
+                {
+                  int mask;
+                  mask = cpu_str_to_log_mask(optarg);
+                  printf("mask: %x\n", mask);
+                  cpu_set_log(mask);
+                }
+                break;
+            case QEMU_OPTION_n:
+                pstrcpy(network_script, sizeof(network_script), optarg);
+                break;
+#ifdef CONFIG_GDBSTUB
+            case QEMU_OPTION_s:
+                use_gdbstub = 1;
+                break;
+#endif
+            case QEMU_OPTION_L:
+                bios_dir = optarg;
+                break;
+            case QEMU_OPTION_S:
+                start_emulation = 0;
+                break;
+            case QEMU_OPTION_pci:
+                pci_enabled = 1;
+                break;
+            case QEMU_OPTION_isa:
+                pci_enabled = 0;
+                break;
+            case QEMU_OPTION_prep:
+                prep_enabled = 1;
+                break;
+           case QEMU_OPTION_k:
+               keyboard_layout = optarg;
+               break;
+            case QEMU_OPTION_localtime:
+                rtc_utc = 0;
+                break;
+            case QEMU_OPTION_cirrusvga:
+                cirrus_vga_enabled = 1;
+                break;
+            case QEMU_OPTION_std_vga:
+                cirrus_vga_enabled = 0;
+                break;
+            case QEMU_OPTION_g:
+                {
+                    const char *p;
+                    int w, h, depth;
+                    p = optarg;
+                    w = strtol(p, (char **)&p, 10);
+                    if (w <= 0) {
+                    graphic_error:
+                        fprintf(stderr, "qemu: invalid resolution or depth\n");
+                        exit(1);
+                    }
+                    if (*p != 'x')
+                        goto graphic_error;
+                    p++;
+                    h = strtol(p, (char **)&p, 10);
+                    if (h <= 0)
+                        goto graphic_error;
+                    if (*p == 'x') {
+                        p++;
+                        depth = strtol(p, (char **)&p, 10);
+                        if (depth != 8 && depth != 15 && depth != 16 && 
+                            depth != 24 && depth != 32)
+                            goto graphic_error;
+                    } else if (*p == '\0') {
+                        depth = graphic_depth;
+                    } else {
+                        goto graphic_error;
+                    }
+                    
+                    graphic_width = w;
+                    graphic_height = h;
+                    graphic_depth = depth;
+                }
+                break;
+            case QEMU_OPTION_monitor:
+                pstrcpy(monitor_device, sizeof(monitor_device), optarg);
+                break;
+            case QEMU_OPTION_serial:
+                if (serial_device_index >= MAX_SERIAL_PORTS) {
+                    fprintf(stderr, "qemu: too many serial ports\n");
+                    exit(1);
+                }
+                pstrcpy(serial_devices[serial_device_index], 
+                        sizeof(serial_devices[0]), optarg);
+                serial_device_index++;
+                break;
+           case QEMU_OPTION_loadvm:
+               loadvm = optarg;
+               break;
+            case QEMU_OPTION_full_screen:
+                full_screen = 1;
+                break;
+            }
+        }
+    }
+
+    linux_boot = (kernel_filename != NULL);
+        
+    if (!linux_boot && hd_filename[0] == '\0' && hd_filename[2] == '\0' &&
+        fd_filename[0] == '\0')
+        help();
+    
+    /* boot to cd by default if no hard disk */
+    if (hd_filename[0] == '\0' && boot_device == 'c') {
+        if (fd_filename[0] != '\0')
+            boot_device = 'a';
+        else
+            boot_device = 'd';
+    }
+
+#if !defined(CONFIG_SOFTMMU)
+    /* must avoid mmap() usage of glibc by setting a buffer "by hand" */
+    {
+        static uint8_t stdout_buf[4096];
+        setvbuf(stdout, stdout_buf, _IOLBF, sizeof(stdout_buf));
+    }
+#else
+    setvbuf(stdout, NULL, _IOLBF, 0);
+#endif
+
+    /* init host network redirectors */
+    if (net_if_type == -1) {
+        net_if_type = NET_IF_TUN;
+#if defined(CONFIG_SLIRP)
+        if (access(network_script, R_OK) < 0) {
+            net_if_type = NET_IF_USER;
+        }
+#endif
+    }
+
+    for(i = 0; i < nb_nics; i++) {
+        NetDriverState *nd = &nd_table[i];
+        nd->index = i;
+        /* init virtual mac address */
+        nd->macaddr[0] = macaddr[0];
+        nd->macaddr[1] = macaddr[1];
+        nd->macaddr[2] = macaddr[2];
+        nd->macaddr[3] = macaddr[3];
+        nd->macaddr[4] = macaddr[4];
+        nd->macaddr[5] = macaddr[5] + i;
+        switch(net_if_type) {
+#if defined(CONFIG_SLIRP)
+        case NET_IF_USER:
+            net_slirp_init(nd);
+            break;
+#endif
+#if !defined(_WIN32)
+        case NET_IF_TUN:
+            if (i < nb_tun_fds) {
+                net_fd_init(nd, tun_fds[i]);
+            } else {
+                if (net_tun_init(nd) < 0)
+                    net_dummy_init(nd);
+            }
+            break;
+#endif
+        case NET_IF_DUMMY:
+        default:
+            net_dummy_init(nd);
+            break;
+        }
+    }
+
+    /* init the memory */
+    phys_ram_size = ram_size + vga_ram_size + bios_size;
+
+    #define PAGE_SHIFT 12
+    #define PAGE_SIZE  (1 << PAGE_SHIFT)
+
+    nr_pages = ram_size/PAGE_SIZE;
+    xc_handle = xc_interface_open();
+    
+    if ( (page_array = (unsigned long *)
+         malloc(nr_pages * sizeof(unsigned long))) == NULL)
+    {
+           perror("malloc");
+           exit(-1);
+    }
+
+    if ( xc_get_pfn_list(xc_handle, domid, page_array, nr_pages) != nr_pages )
+    {
+           perror("xc_get_pfn_list");
+           exit(-1);
+    }
+
+    if ((phys_ram_base =  xc_map_foreign_batch(xc_handle, domid,
+                                                PROT_READ|PROT_WRITE,
+                                                page_array,
+                                                nr_pages - 1)) == 0) {
+           perror("xc_map_foreign_batch");
+           exit(-1);
+    }
+
+
+    shared_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
+                                      PROT_READ|PROT_WRITE,
+                                      page_array[nr_pages - 1]);
+
+    /* we always create the cdrom drive, even if no disk is there */
+    bdrv_init();
+    if (has_cdrom) {
+        bs_table[2] = bdrv_new("cdrom");
+        bdrv_set_type_hint(bs_table[2], BDRV_TYPE_CDROM);
+    }
+
+    /* open the virtual block devices */
+    for(i = 0; i < MAX_DISKS; i++) {
+        if (hd_filename[i]) {
+            if (!bs_table[i]) {
+                char buf[64];
+                snprintf(buf, sizeof(buf), "hd%c", i + 'a');
+                bs_table[i] = bdrv_new(buf);
+            }
+            if (bdrv_open(bs_table[i], hd_filename[i], snapshot) < 0) {
+                fprintf(stderr, "qemu: could not open hard disk image '%s'\n",
+                        hd_filename[i]);
+                exit(1);
+            }
+            if (i == 0 && cyls != 0) 
+                bdrv_set_geometry_hint(bs_table[i], cyls, heads, secs);
+        }
+    }
+
+    /* we always create at least one floppy disk */
+    fd_table[0] = bdrv_new("fda");
+    bdrv_set_type_hint(fd_table[0], BDRV_TYPE_FLOPPY);
+
+    for(i = 0; i < MAX_FD; i++) {
+        if (fd_filename[i]) {
+            if (!fd_table[i]) {
+                char buf[64];
+                snprintf(buf, sizeof(buf), "fd%c", i + 'a');
+                fd_table[i] = bdrv_new(buf);
+                bdrv_set_type_hint(fd_table[i], BDRV_TYPE_FLOPPY);
+            }
+            if (fd_filename[i] != '\0') {
+                if (bdrv_open(fd_table[i], fd_filename[i], snapshot) < 0) {
+                    fprintf(stderr, "qemu: could not open floppy disk image '%s'\n",
+                            fd_filename[i]);
+                    exit(1);
+                }
+            }
+        }
+    }
+
+    /* init CPU state */
+    env = cpu_init();
+    global_env = env;
+    cpu_single_env = env;
+
+    init_ioports();
+    cpu_calibrate_ticks();
+
+    /* terminal init */
+    if (nographic) {
+        dumb_display_init(ds);
+    } else {
+       if (usevnc) {
+#ifdef CONFIG_VNC
+           vnc_display_init(ds, (usevnc==2));
+#else
+           perror("qemu not configured with vnc support");
+#endif
+       } else {
+#ifdef CONFIG_SDL
+        sdl_display_init(ds, full_screen);
+#else
+        dumb_display_init(ds);
+#endif
+    }
+    }
+
+    vga_console = graphic_console_init(ds);
+    
+    monitor_hd = qemu_chr_open(monitor_device);
+    if (!monitor_hd) {
+        fprintf(stderr, "qemu: could not open monitor device '%s'\n", monitor_device);
+        exit(1);
+    }
+    monitor_init(monitor_hd, !nographic);
+
+    for(i = 0; i < MAX_SERIAL_PORTS; i++) {
+        if (serial_devices[i][0] != '\0') {
+            serial_hds[i] = qemu_chr_open(serial_devices[i]);
+            if (!serial_hds[i]) {
+                fprintf(stderr, "qemu: could not open serial device '%s'\n", 
+                        serial_devices[i]);
+                exit(1);
+            }
+            if (!strcmp(serial_devices[i], "vc"))
+                qemu_chr_printf(serial_hds[i], "serial%d console\n", i);
+        }
+    }
+
+    /* setup cpu signal handlers for MMU / self modifying code handling */
+#if !defined(CONFIG_SOFTMMU)
+    
+#if defined (TARGET_I386) && defined(USE_CODE_COPY)
+    {
+        stack_t stk;
+        signal_stack = memalign(16, SIGNAL_STACK_SIZE);
+        stk.ss_sp = signal_stack;
+        stk.ss_size = SIGNAL_STACK_SIZE;
+        stk.ss_flags = 0;
+
+        if (sigaltstack(&stk, NULL) < 0) {
+            perror("sigaltstack");
+            exit(1);
+        }
+    }
+#endif
+    {
+        struct sigaction act;
+        
+        sigfillset(&act.sa_mask);
+        act.sa_flags = SA_SIGINFO;
+#if defined (TARGET_I386) && defined(USE_CODE_COPY)
+        act.sa_flags |= SA_ONSTACK;
+#endif
+        act.sa_sigaction = host_segv_handler;
+        sigaction(SIGSEGV, &act, NULL);
+        sigaction(SIGBUS, &act, NULL);
+#if defined (TARGET_I386) && defined(USE_CODE_COPY)
+        sigaction(SIGFPE, &act, NULL);
+#endif
+    }
+#endif
+
+#ifndef _WIN32
+    {
+        struct sigaction act;
+        sigfillset(&act.sa_mask);
+        act.sa_flags = 0;
+        act.sa_handler = SIG_IGN;
+        sigaction(SIGPIPE, &act, NULL);
+    }
+#endif
+    init_timers();
+
+#if defined(TARGET_I386)
+    pc_init(ram_size, vga_ram_size, boot_device,
+            ds, fd_filename, snapshot,
+            kernel_filename, kernel_cmdline, initrd_filename);
+#elif defined(TARGET_PPC)
+    ppc_init(ram_size, vga_ram_size, boot_device,
+            ds, fd_filename, snapshot,
+            kernel_filename, kernel_cmdline, initrd_filename);
+#elif defined(TARGET_SPARC)
+    sun4m_init(ram_size, vga_ram_size, boot_device,
+            ds, fd_filename, snapshot,
+            kernel_filename, kernel_cmdline, initrd_filename);
+#endif
+
+    gui_timer = qemu_new_timer(rt_clock, gui_update, NULL);
+    qemu_mod_timer(gui_timer, qemu_get_clock(rt_clock));
+
+    polling_timer = qemu_new_timer(rt_clock, polling_handler, NULL);
+    qemu_mod_timer(polling_timer, qemu_get_clock(rt_clock));
+
+#ifdef CONFIG_GDBSTUB
+    if (use_gdbstub) {
+        if (gdbserver_start(gdbstub_port) < 0) {
+            fprintf(stderr, "Could not open gdbserver socket on port %d\n", 
+                    gdbstub_port);
+            exit(1);
+        } else {
+            printf("Waiting gdb connection on port %d\n", gdbstub_port);
+        }
+    } else 
+#endif
+    if (loadvm)
+        qemu_loadvm(loadvm);
+
+    {
+        /* XXX: simplify init */
+        if (start_emulation) {
+            vm_start();
+        }
+    }
+    main_loop();
+    quit_timers();
+    return 0;
+}
diff --git a/tools/ioemu/vl.h b/tools/ioemu/vl.h
new file mode 100644 (file)
index 0000000..0e1cb92
--- /dev/null
@@ -0,0 +1,786 @@
+/*
+ * QEMU System Emulator header
+ * 
+ * Copyright (c) 2003 Fabrice Bellard
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#ifndef VL_H
+#define VL_H
+
+/* we put basic includes here to avoid repeating them in device drivers */
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <time.h>
+#include <ctype.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#ifndef O_LARGEFILE
+#define O_LARGEFILE 0
+#endif
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+#ifdef _WIN32
+#define lseek _lseeki64
+#define ENOTSUP 4096
+/* XXX: find 64 bit version */
+#define ftruncate chsize
+
+static inline char *realpath(const char *path, char *resolved_path)
+{
+    _fullpath(resolved_path, path, _MAX_PATH);
+    return resolved_path;
+}
+#endif
+
+#ifdef QEMU_TOOL
+
+/* we use QEMU_TOOL in the command line tools which do not depend on
+   the target CPU type */
+#include "config-host.h"
+#include <setjmp.h>
+#include "osdep.h"
+#include "bswap.h"
+
+#else
+
+#include "cpu.h"
+
+#endif /* !defined(QEMU_TOOL) */
+
+#ifndef glue
+#define xglue(x, y) x ## y
+#define glue(x, y) xglue(x, y)
+#define stringify(s)   tostring(s)
+#define tostring(s)    #s
+#endif
+
+/* vl.c */
+uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c);
+
+void hw_error(const char *fmt, ...);
+
+int get_image_size(const char *filename);
+int load_image(const char *filename, uint8_t *addr);
+extern const char *bios_dir;
+
+void pstrcpy(char *buf, int buf_size, const char *str);
+char *pstrcat(char *buf, int buf_size, const char *s);
+int strstart(const char *str, const char *val, const char **ptr);
+
+extern int vm_running;
+
+typedef void VMStopHandler(void *opaque, int reason);
+
+int qemu_add_vm_stop_handler(VMStopHandler *cb, void *opaque);
+void qemu_del_vm_stop_handler(VMStopHandler *cb, void *opaque);
+
+void vm_start(void);
+void vm_stop(int reason);
+
+typedef void QEMUResetHandler(void *opaque);
+
+void qemu_register_reset(QEMUResetHandler *func, void *opaque);
+void qemu_system_reset_request(void);
+void qemu_system_shutdown_request(void);
+
+void main_loop_wait(int timeout);
+
+extern int audio_enabled;
+extern int sb16_enabled;
+extern int adlib_enabled;
+extern int gus_enabled;
+extern int ram_size;
+extern int bios_size;
+extern int rtc_utc;
+extern int cirrus_vga_enabled;
+extern int graphic_width;
+extern int graphic_height;
+extern int graphic_depth;
+
+/* XXX: make it dynamic */
+#if defined (TARGET_PPC)
+#define BIOS_SIZE (512 * 1024)
+#else
+#define BIOS_SIZE ((256 + 64) * 1024)
+#endif
+
+/* keyboard/mouse support */
+
+#define MOUSE_EVENT_LBUTTON 0x01
+#define MOUSE_EVENT_RBUTTON 0x02
+#define MOUSE_EVENT_MBUTTON 0x04
+
+typedef void QEMUPutKBDEvent(void *opaque, int keycode);
+typedef void QEMUPutMouseEvent(void *opaque, int dx, int dy, int dz, int buttons_state);
+
+void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque);
+void qemu_add_mouse_event_handler(QEMUPutMouseEvent *func, void *opaque);
+
+void kbd_put_keycode(int keycode);
+void kbd_mouse_event(int dx, int dy, int dz, int buttons_state);
+
+/* keysym is a unicode code except for special keys (see QEMU_KEY_xxx
+   constants) */
+#define QEMU_KEY_ESC1(c) ((c) | 0xe100)
+#define QEMU_KEY_BACKSPACE  0x007f
+#define QEMU_KEY_UP         QEMU_KEY_ESC1('A')
+#define QEMU_KEY_DOWN       QEMU_KEY_ESC1('B')
+#define QEMU_KEY_RIGHT      QEMU_KEY_ESC1('C')
+#define QEMU_KEY_LEFT       QEMU_KEY_ESC1('D')
+#define QEMU_KEY_HOME       QEMU_KEY_ESC1(1)
+#define QEMU_KEY_END        QEMU_KEY_ESC1(4)
+#define QEMU_KEY_PAGEUP     QEMU_KEY_ESC1(5)
+#define QEMU_KEY_PAGEDOWN   QEMU_KEY_ESC1(6)
+#define QEMU_KEY_DELETE     QEMU_KEY_ESC1(3)
+
+#define QEMU_KEY_CTRL_UP         0xe400
+#define QEMU_KEY_CTRL_DOWN       0xe401
+#define QEMU_KEY_CTRL_LEFT       0xe402
+#define QEMU_KEY_CTRL_RIGHT      0xe403
+#define QEMU_KEY_CTRL_HOME       0xe404
+#define QEMU_KEY_CTRL_END        0xe405
+#define QEMU_KEY_CTRL_PAGEUP     0xe406
+#define QEMU_KEY_CTRL_PAGEDOWN   0xe407
+
+void kbd_put_keysym(int keysym);
+
+/* async I/O support */
+
+typedef void IOReadHandler(void *opaque, const uint8_t *buf, int size);
+typedef int IOCanRWHandler(void *opaque);
+
+int qemu_add_fd_read_handler(int fd, IOCanRWHandler *fd_can_read, 
+                             IOReadHandler *fd_read, void *opaque);
+void qemu_del_fd_read_handler(int fd);
+
+/* character device */
+
+#define CHR_EVENT_BREAK 0 /* serial break char */
+#define CHR_EVENT_FOCUS 1 /* focus to this terminal (modal input needed) */
+
+typedef void IOEventHandler(void *opaque, int event);
+
+typedef struct CharDriverState {
+    int (*chr_write)(struct CharDriverState *s, const uint8_t *buf, int len);
+    void (*chr_add_read_handler)(struct CharDriverState *s, 
+                                 IOCanRWHandler *fd_can_read, 
+                                 IOReadHandler *fd_read, void *opaque);
+    IOEventHandler *chr_event;
+    void (*chr_send_event)(struct CharDriverState *chr, int event);
+    void *opaque;
+} CharDriverState;
+
+void qemu_chr_printf(CharDriverState *s, const char *fmt, ...);
+int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len);
+void qemu_chr_send_event(CharDriverState *s, int event);
+void qemu_chr_add_read_handler(CharDriverState *s, 
+                               IOCanRWHandler *fd_can_read, 
+                               IOReadHandler *fd_read, void *opaque);
+void qemu_chr_add_event_handler(CharDriverState *s, IOEventHandler *chr_event);
+                               
+/* consoles */
+
+typedef struct DisplayState DisplayState;
+typedef struct TextConsole TextConsole;
+
+extern TextConsole *vga_console;
+
+TextConsole *graphic_console_init(DisplayState *ds);
+int is_active_console(TextConsole *s);
+CharDriverState *text_console_init(DisplayState *ds);
+void console_select(unsigned int index);
+
+/* serial ports */
+
+#define MAX_SERIAL_PORTS 4
+
+extern CharDriverState *serial_hds[MAX_SERIAL_PORTS];
+
+/* network redirectors support */
+
+#define MAX_NICS 8
+
+typedef struct NetDriverState {
+    int index; /* index number in QEMU */
+    uint8_t macaddr[6];
+    char ifname[16];
+    void (*send_packet)(struct NetDriverState *nd, 
+                        const uint8_t *buf, int size);
+    void (*add_read_packet)(struct NetDriverState *nd, 
+                            IOCanRWHandler *fd_can_read, 
+                            IOReadHandler *fd_read, void *opaque);
+    /* tun specific data */
+    int fd;
+    /* slirp specific data */
+} NetDriverState;
+
+extern int nb_nics;
+extern NetDriverState nd_table[MAX_NICS];
+
+void qemu_send_packet(NetDriverState *nd, const uint8_t *buf, int size);
+void qemu_add_read_packet(NetDriverState *nd, IOCanRWHandler *fd_can_read, 
+                          IOReadHandler *fd_read, void *opaque);
+
+/* timers */
+
+typedef struct QEMUClock QEMUClock;
+typedef struct QEMUTimer QEMUTimer;
+typedef void QEMUTimerCB(void *opaque);
+
+/* The real time clock should be used only for stuff which does not
+   change the virtual machine state, as it is run even if the virtual
+   machine is stopped. The real time clock has a frequency of 1000
+   Hz. */
+extern QEMUClock *rt_clock;
+
+/* Rge virtual clock is only run during the emulation. It is stopped
+   when the virtual machine is stopped. Virtual timers use a high
+   precision clock, usually cpu cycles (use ticks_per_sec). */
+extern QEMUClock *vm_clock;
+
+int64_t qemu_get_clock(QEMUClock *clock);
+
+QEMUTimer *qemu_new_timer(QEMUClock *clock, QEMUTimerCB *cb, void *opaque);
+void qemu_free_timer(QEMUTimer *ts);
+void qemu_del_timer(QEMUTimer *ts);
+void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time);
+int qemu_timer_pending(QEMUTimer *ts);
+
+extern int64_t ticks_per_sec;
+extern int pit_min_timer_count;
+
+void cpu_enable_ticks(void);
+void cpu_disable_ticks(void);
+
+/* VM Load/Save */
+
+typedef FILE QEMUFile;
+
+void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size);
+void qemu_put_byte(QEMUFile *f, int v);
+void qemu_put_be16(QEMUFile *f, unsigned int v);
+void qemu_put_be32(QEMUFile *f, unsigned int v);
+void qemu_put_be64(QEMUFile *f, uint64_t v);
+int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size);
+int qemu_get_byte(QEMUFile *f);
+unsigned int qemu_get_be16(QEMUFile *f);
+unsigned int qemu_get_be32(QEMUFile *f);
+uint64_t qemu_get_be64(QEMUFile *f);
+
+static inline void qemu_put_be64s(QEMUFile *f, const uint64_t *pv)
+{
+    qemu_put_be64(f, *pv);
+}
+
+static inline void qemu_put_be32s(QEMUFile *f, const uint32_t *pv)
+{
+    qemu_put_be32(f, *pv);
+}
+
+static inline void qemu_put_be16s(QEMUFile *f, const uint16_t *pv)
+{
+    qemu_put_be16(f, *pv);
+}
+
+static inline void qemu_put_8s(QEMUFile *f, const uint8_t *pv)
+{
+    qemu_put_byte(f, *pv);
+}
+
+static inline void qemu_get_be64s(QEMUFile *f, uint64_t *pv)
+{
+    *pv = qemu_get_be64(f);
+}
+
+static inline void qemu_get_be32s(QEMUFile *f, uint32_t *pv)
+{
+    *pv = qemu_get_be32(f);
+}
+
+static inline void qemu_get_be16s(QEMUFile *f, uint16_t *pv)
+{
+    *pv = qemu_get_be16(f);
+}
+
+static inline void qemu_get_8s(QEMUFile *f, uint8_t *pv)
+{
+    *pv = qemu_get_byte(f);
+}
+
+int64_t qemu_ftell(QEMUFile *f);
+int64_t qemu_fseek(QEMUFile *f, int64_t pos, int whence);
+
+typedef void SaveStateHandler(QEMUFile *f, void *opaque);
+typedef int LoadStateHandler(QEMUFile *f, void *opaque, int version_id);
+
+int qemu_loadvm(const char *filename);
+int qemu_savevm(const char *filename);
+int register_savevm(const char *idstr, 
+                    int instance_id, 
+                    int version_id,
+                    SaveStateHandler *save_state,
+                    LoadStateHandler *load_state,
+                    void *opaque);
+void qemu_get_timer(QEMUFile *f, QEMUTimer *ts);
+void qemu_put_timer(QEMUFile *f, QEMUTimer *ts);
+
+/* block.c */
+typedef struct BlockDriverState BlockDriverState;
+typedef struct BlockDriver BlockDriver;
+
+extern BlockDriver bdrv_raw;
+extern BlockDriver bdrv_cow;
+extern BlockDriver bdrv_qcow;
+extern BlockDriver bdrv_vmdk;
+extern BlockDriver bdrv_cloop;
+
+void bdrv_init(void);
+BlockDriver *bdrv_find_format(const char *format_name);
+int bdrv_create(BlockDriver *drv, 
+                const char *filename, int64_t size_in_sectors,
+                const char *backing_file, int flags);
+BlockDriverState *bdrv_new(const char *device_name);
+void bdrv_delete(BlockDriverState *bs);
+int bdrv_open(BlockDriverState *bs, const char *filename, int snapshot);
+int bdrv_open2(BlockDriverState *bs, const char *filename, int snapshot,
+               BlockDriver *drv);
+void bdrv_close(BlockDriverState *bs);
+int bdrv_read(BlockDriverState *bs, int64_t sector_num, 
+              uint8_t *buf, int nb_sectors);
+int bdrv_write(BlockDriverState *bs, int64_t sector_num, 
+               const uint8_t *buf, int nb_sectors);
+void bdrv_get_geometry(BlockDriverState *bs, int64_t *nb_sectors_ptr);
+int bdrv_commit(BlockDriverState *bs);
+void bdrv_set_boot_sector(BlockDriverState *bs, const uint8_t *data, int size);
+
+#define BDRV_TYPE_HD     0
+#define BDRV_TYPE_CDROM  1
+#define BDRV_TYPE_FLOPPY 2
+
+void bdrv_set_geometry_hint(BlockDriverState *bs, 
+                            int cyls, int heads, int secs);
+void bdrv_set_type_hint(BlockDriverState *bs, int type);
+void bdrv_get_geometry_hint(BlockDriverState *bs, 
+                            int *pcyls, int *pheads, int *psecs);
+int bdrv_get_type_hint(BlockDriverState *bs);
+int bdrv_is_removable(BlockDriverState *bs);
+int bdrv_is_read_only(BlockDriverState *bs);
+int bdrv_is_inserted(BlockDriverState *bs);
+int bdrv_is_locked(BlockDriverState *bs);
+void bdrv_set_locked(BlockDriverState *bs, int locked);
+void bdrv_set_change_cb(BlockDriverState *bs, 
+                        void (*change_cb)(void *opaque), void *opaque);
+void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size);
+void bdrv_info(void);
+BlockDriverState *bdrv_find(const char *name);
+void bdrv_iterate(void (*it)(void *opaque, const char *name), void *opaque);
+int bdrv_is_encrypted(BlockDriverState *bs);
+int bdrv_set_key(BlockDriverState *bs, const char *key);
+void bdrv_iterate_format(void (*it)(void *opaque, const char *name), 
+                         void *opaque);
+const char *bdrv_get_device_name(BlockDriverState *bs);
+
+int qcow_get_cluster_size(BlockDriverState *bs);
+int qcow_compress_cluster(BlockDriverState *bs, int64_t sector_num,
+                          const uint8_t *buf);
+
+#ifndef QEMU_TOOL
+/* ISA bus */
+
+extern target_phys_addr_t isa_mem_base;
+
+typedef void (IOPortWriteFunc)(void *opaque, uint32_t address, uint32_t data);
+typedef uint32_t (IOPortReadFunc)(void *opaque, uint32_t address);
+
+int register_ioport_read(int start, int length, int size, 
+                         IOPortReadFunc *func, void *opaque);
+int register_ioport_write(int start, int length, int size, 
+                          IOPortWriteFunc *func, void *opaque);
+void isa_unassign_ioport(int start, int length);
+
+/* PCI bus */
+
+extern int pci_enabled;
+
+extern target_phys_addr_t pci_mem_base;
+
+typedef struct PCIBus PCIBus;
+typedef struct PCIDevice PCIDevice;
+
+typedef void PCIConfigWriteFunc(PCIDevice *pci_dev, 
+                                uint32_t address, uint32_t data, int len);
+typedef uint32_t PCIConfigReadFunc(PCIDevice *pci_dev, 
+                                   uint32_t address, int len);
+typedef void PCIMapIORegionFunc(PCIDevice *pci_dev, int region_num, 
+                                uint32_t addr, uint32_t size, int type);
+
+#define PCI_ADDRESS_SPACE_MEM          0x00
+#define PCI_ADDRESS_SPACE_IO           0x01
+#define PCI_ADDRESS_SPACE_MEM_PREFETCH 0x08
+
+typedef struct PCIIORegion {
+    uint32_t addr; /* current PCI mapping address. -1 means not mapped */
+    uint32_t size;
+    uint8_t type;
+    PCIMapIORegionFunc *map_func;
+} PCIIORegion;
+
+#define PCI_ROM_SLOT 6
+#define PCI_NUM_REGIONS 7
+struct PCIDevice {
+    /* PCI config space */
+    uint8_t config[256];
+
+    /* the following fields are read only */
+    PCIBus *bus;
+    int devfn;
+    char name[64];
+    PCIIORegion io_regions[PCI_NUM_REGIONS];
+    
+    /* do not access the following fields */
+    PCIConfigReadFunc *config_read;
+    PCIConfigWriteFunc *config_write;
+    int irq_index;
+};
+
+PCIDevice *pci_register_device(PCIBus *bus, const char *name,
+                               int instance_size, int devfn,
+                               PCIConfigReadFunc *config_read, 
+                               PCIConfigWriteFunc *config_write);
+
+void pci_register_io_region(PCIDevice *pci_dev, int region_num, 
+                            uint32_t size, int type, 
+                            PCIMapIORegionFunc *map_func);
+
+void pci_set_irq(PCIDevice *pci_dev, int irq_num, int level);
+
+uint32_t pci_default_read_config(PCIDevice *d, 
+                                 uint32_t address, int len);
+void pci_default_write_config(PCIDevice *d, 
+                              uint32_t address, uint32_t val, int len);
+void generic_pci_save(QEMUFile* f, void *opaque);
+int generic_pci_load(QEMUFile* f, void *opaque, int version_id);
+
+extern struct PIIX3State *piix3_state;
+
+PCIBus *i440fx_init(void);
+void piix3_init(PCIBus *bus);
+void pci_bios_init(void);
+void pci_info(void);
+
+/* temporary: will be moved in platform specific file */
+PCIBus *pci_prep_init(void);
+struct openpic_t;
+void pci_pmac_set_openpic(PCIBus *bus, struct openpic_t *openpic);
+PCIBus *pci_pmac_init(void);
+
+/* openpic.c */
+typedef struct openpic_t openpic_t;
+void openpic_set_irq (openpic_t *opp, int n_IRQ, int level);
+openpic_t *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus);
+
+/* vga.c */
+
+#define VGA_RAM_SIZE (4096 * 1024)
+
+struct DisplayState {
+    uint8_t *data;
+    int linesize;
+    int depth;
+    int width;
+    int height;
+    void (*dpy_update)(struct DisplayState *s, int x, int y, int w, int h);
+    void (*dpy_resize)(struct DisplayState *s, int w, int h);
+    void (*dpy_refresh)(struct DisplayState *s);
+};
+
+static inline void dpy_update(DisplayState *s, int x, int y, int w, int h)
+{
+    s->dpy_update(s, x, y, w, h);
+}
+
+static inline void dpy_resize(DisplayState *s, int w, int h)
+{
+    s->dpy_resize(s, w, h);
+}
+
+int vga_initialize(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base, 
+                   unsigned long vga_ram_offset, int vga_ram_size);
+void vga_update_display(void);
+void vga_invalidate_display(void);
+void vga_screen_dump(const char *filename);
+
+/* vnc.c */
+void vnc_display_init(DisplayState *ds, int useAlsoSDL);
+
+/* cirrus_vga.c */
+void pci_cirrus_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base, 
+                         unsigned long vga_ram_offset, int vga_ram_size);
+void isa_cirrus_vga_init(DisplayState *ds, uint8_t *vga_ram_base, 
+                         unsigned long vga_ram_offset, int vga_ram_size);
+
+/* sdl.c */
+void sdl_display_init(DisplayState *ds, int full_screen);
+
+/* ide.c */
+#define MAX_DISKS 4
+
+extern BlockDriverState *bs_table[MAX_DISKS];
+
+void isa_ide_init(int iobase, int iobase2, int irq,
+                  BlockDriverState *hd0, BlockDriverState *hd1);
+void pci_ide_init(PCIBus *bus, BlockDriverState **hd_table);
+void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table);
+int pmac_ide_init (BlockDriverState **hd_table,
+                   openpic_t *openpic, int irq);
+
+/* sb16.c */
+void SB16_init (void);
+
+/* adlib.c */
+void Adlib_init (void);
+
+/* gus.c */
+void GUS_init (void);
+
+/* dma.c */
+typedef int (*DMA_transfer_handler) (void *opaque, int nchan, int pos, int size);
+int DMA_get_channel_mode (int nchan);
+int DMA_read_memory (int nchan, void *buf, int pos, int size);
+int DMA_write_memory (int nchan, void *buf, int pos, int size);
+void DMA_hold_DREQ (int nchan);
+void DMA_release_DREQ (int nchan);
+void DMA_schedule(int nchan);
+void DMA_run (void);
+void DMA_init (int high_page_enable);
+void DMA_register_channel (int nchan,
+                           DMA_transfer_handler transfer_handler,
+                           void *opaque);
+/* fdc.c */
+#define MAX_FD 2
+extern BlockDriverState *fd_table[MAX_FD];
+
+typedef struct fdctrl_t fdctrl_t;
+
+fdctrl_t *fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped, 
+                       uint32_t io_base,
+                       BlockDriverState **fds);
+int fdctrl_get_drive_type(fdctrl_t *fdctrl, int drive_num);
+
+/* ne2000.c */
+
+void isa_ne2000_init(int base, int irq, NetDriverState *nd);
+void pci_ne2000_init(PCIBus *bus, NetDriverState *nd);
+
+/* pckbd.c */
+
+void kbd_init(void);
+extern const char* keyboard_layout;
+
+/* mc146818rtc.c */
+
+typedef struct RTCState RTCState;
+
+RTCState *rtc_init(int base, int irq);
+void rtc_set_memory(RTCState *s, int addr, int val);
+void rtc_set_date(RTCState *s, const struct tm *tm);
+
+/* serial.c */
+
+typedef struct SerialState SerialState;
+SerialState *serial_init(int base, int irq, CharDriverState *chr);
+
+/* i8259.c */
+
+void pic_set_irq(int irq, int level);
+void pic_init(void);
+uint32_t pic_intack_read(CPUState *env);
+void pic_info(void);
+void irq_info(void);
+int pic_irq2vec(int irq);
+
+/* i8254.c */
+
+#define PIT_FREQ 1193182
+
+typedef struct PITState PITState;
+
+PITState *pit_init(int base, int irq);
+void pit_set_gate(PITState *pit, int channel, int val);
+int pit_get_gate(PITState *pit, int channel);
+int pit_get_out(PITState *pit, int channel, int64_t current_time);
+
+/* pc.c */
+void pc_init(int ram_size, int vga_ram_size, int boot_device,
+             DisplayState *ds, const char **fd_filename, int snapshot,
+             const char *kernel_filename, const char *kernel_cmdline,
+             const char *initrd_filename);
+
+/* ppc.c */
+void ppc_init (int ram_size, int vga_ram_size, int boot_device,
+              DisplayState *ds, const char **fd_filename, int snapshot,
+              const char *kernel_filename, const char *kernel_cmdline,
+              const char *initrd_filename);
+void ppc_prep_init (int ram_size, int vga_ram_size, int boot_device,
+                   DisplayState *ds, const char **fd_filename, int snapshot,
+                   const char *kernel_filename, const char *kernel_cmdline,
+                   const char *initrd_filename);
+void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device,
+                  DisplayState *ds, const char **fd_filename, int snapshot,
+                  const char *kernel_filename, const char *kernel_cmdline,
+                  const char *initrd_filename);
+#ifdef TARGET_PPC
+ppc_tb_t *cpu_ppc_tb_init (CPUState *env, uint32_t freq);
+#endif
+void PREP_debug_write (void *opaque, uint32_t addr, uint32_t val);
+
+extern CPUWriteMemoryFunc *PPC_io_write[];
+extern CPUReadMemoryFunc *PPC_io_read[];
+extern int prep_enabled;
+
+/* sun4m.c */
+void sun4m_init(int ram_size, int vga_ram_size, int boot_device,
+             DisplayState *ds, const char **fd_filename, int snapshot,
+             const char *kernel_filename, const char *kernel_cmdline,
+             const char *initrd_filename);
+
+/* iommu.c */
+void iommu_init(uint32_t addr);
+uint32_t iommu_translate(uint32_t addr);
+
+/* lance.c */
+void lance_init(NetDriverState *nd, int irq, uint32_t leaddr, uint32_t ledaddr);
+
+/* tcx.c */
+void tcx_init(DisplayState *ds, uint32_t addr);
+
+/* sched.c */
+void sched_init();
+
+/* magic-load.c */
+void magic_init(const char *kfn, int kloadaddr, uint32_t addr);
+
+/* timer.c */
+void timer_init(uint32_t addr, int irq);
+
+/* NVRAM helpers */
+#include "hw/m48t59.h"
+
+void NVRAM_set_byte (m48t59_t *nvram, uint32_t addr, uint8_t value);
+uint8_t NVRAM_get_byte (m48t59_t *nvram, uint32_t addr);
+void NVRAM_set_word (m48t59_t *nvram, uint32_t addr, uint16_t value);
+uint16_t NVRAM_get_word (m48t59_t *nvram, uint32_t addr);
+void NVRAM_set_lword (m48t59_t *nvram, uint32_t addr, uint32_t value);
+uint32_t NVRAM_get_lword (m48t59_t *nvram, uint32_t addr);
+void NVRAM_set_string (m48t59_t *nvram, uint32_t addr,
+                       const unsigned char *str, uint32_t max);
+int NVRAM_get_string (m48t59_t *nvram, uint8_t *dst, uint16_t addr, int max);
+void NVRAM_set_crc (m48t59_t *nvram, uint32_t addr,
+                    uint32_t start, uint32_t count);
+int PPC_NVRAM_set_params (m48t59_t *nvram, uint16_t NVRAM_size,
+                          const unsigned char *arch,
+                          uint32_t RAM_size, int boot_device,
+                          uint32_t kernel_image, uint32_t kernel_size,
+                          const char *cmdline,
+                          uint32_t initrd_image, uint32_t initrd_size,
+                          uint32_t NVRAM_image,
+                          int width, int height, int depth);
+
+/* adb.c */
+
+#define MAX_ADB_DEVICES 16
+
+#define ADB_MAX_OUT_LEN 16
+
+typedef struct ADBDevice ADBDevice;
+
+/* buf = NULL means polling */
+typedef int ADBDeviceRequest(ADBDevice *d, uint8_t *buf_out,
+                              const uint8_t *buf, int len);
+typedef int ADBDeviceReset(ADBDevice *d);
+
+struct ADBDevice {
+    struct ADBBusState *bus;
+    int devaddr;
+    int handler;
+    ADBDeviceRequest *devreq;
+    ADBDeviceReset *devreset;
+    void *opaque;
+};
+
+typedef struct ADBBusState {
+    ADBDevice devices[MAX_ADB_DEVICES];
+    int nb_devices;
+    int poll_index;
+} ADBBusState;
+
+int adb_request(ADBBusState *s, uint8_t *buf_out,
+                const uint8_t *buf, int len);
+int adb_poll(ADBBusState *s, uint8_t *buf_out);
+
+ADBDevice *adb_register_device(ADBBusState *s, int devaddr, 
+                               ADBDeviceRequest *devreq, 
+                               ADBDeviceReset *devreset, 
+                               void *opaque);
+void adb_kbd_init(ADBBusState *bus);
+void adb_mouse_init(ADBBusState *bus);
+
+/* cuda.c */
+
+extern ADBBusState adb_bus;
+int cuda_init(openpic_t *openpic, int irq);
+
+#endif /* defined(QEMU_TOOL) */
+
+/* monitor.c */
+void monitor_init(CharDriverState *hd, int show_banner);
+void term_puts(const char *str);
+void term_vprintf(const char *fmt, va_list ap);
+void term_printf(const char *fmt, ...) __attribute__ ((__format__ (__printf__, 1, 2)));
+void term_flush(void);
+void term_print_help(void);
+
+/* readline.c */
+typedef void ReadLineFunc(void *opaque, const char *str);
+
+extern int completion_index;
+void add_completion(const char *str);
+void readline_handle_byte(int ch);
+void readline_find_completion(const char *cmdline);
+const char *readline_get_history(unsigned int index);
+void readline_start(const char *prompt, int is_password,
+                    ReadLineFunc *readline_func, void *opaque);
+
+/* gdbstub.c */
+
+#define DEFAULT_GDBSTUB_PORT 1234
+
+int gdbserver_start(int port);
+
+#endif /* VL_H */
diff --git a/tools/ioemu/vnc.c b/tools/ioemu/vnc.c
new file mode 100644 (file)
index 0000000..06601f3
--- /dev/null
@@ -0,0 +1,501 @@
+/*
+ * QEMU VNC display driver (uses LibVNCServer, based on QEMU SDL driver)
+ * 
+ * Copyright (c) 2003,2004 Fabrice Bellard, Matthew Mastracci,
+ * Johannes E. Schindelin
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+
+#include <rfb/rfb.h>
+
+/* keyboard stuff */
+#include <rfb/keysym.h>
+#include "keysym_adapter_vnc.h"
+#include "keyboard_rdesktop.c"
+
+
+#ifndef _WIN32
+#include <signal.h>
+#endif
+
+static rfbScreenInfoPtr screen;
+static DisplayState* ds_sdl=0;
+static void* kbd_layout=0; // TODO: move into rfbClient
+
+/* mouse stuff */
+
+typedef struct mouse_magic_t {
+       /* When calibrating, mouse_calibration contains a copy of the 
+        * current frame buffer. After a simulated mouse movement, the
+        * update function only gets (0,y1,width,y2) as bounding box 
+        * of the changed region, so we refine that with the help of
+        * this copy, and then update the copy. */
+       char* calibration;
+       /* Mouse handling using VNC used to be wrong, because if moving the
+        * mouse very fast, the pointer got even faster. The reason for this:
+        * when the mouse sends a delta of at least 4 (Windows: 3) pixels, 
+        * it is treated as if it were double the amount. I call this the
+        * sonic wall. */
+       int sonic_wall_x;
+       int sonic_wall_y;
+       /* Unfortunately, Windows and X behave differently, when the sonic
+        * wall was reached in one axis, but not the other: Windows treats
+        * them independently. I call this orthogonal. */
+       char sonic_wall_is_orthogonal;
+       /* last_dy contains the last delta sent on the y axis. We don't
+        * use the x axis (see mouse_calibration). */
+       //static int last_dy=0;
+} mouse_magic_t;
+
+mouse_magic_t* init_mouse_magic() {
+       mouse_magic_t* ret=(mouse_magic_t*)malloc(sizeof(mouse_magic_t));
+
+       ret->calibration=0;
+#ifdef EXPECT_WINDOWS_GUEST
+       ret->sonic_wall_x=3;
+       ret->sonic_wall_y=3;
+       ret->sonic_wall_is_orthogonal=1;
+#else
+       ret->sonic_wall_x=4;
+       ret->sonic_wall_y=4;
+       ret->sonic_wall_is_orthogonal=0;
+#endif
+       return ret;
+}
+
+static void vnc_save(QEMUFile* f,void* opaque)
+{
+       mouse_magic_t* s=(mouse_magic_t*)opaque;
+
+       qemu_put_be32s(f, &s->sonic_wall_x);
+       qemu_put_be32s(f, &s->sonic_wall_y);
+       qemu_put_8s(f, &s->sonic_wall_is_orthogonal);
+}
+
+static int vnc_load(QEMUFile* f,void* opaque,int version_id)
+{
+       mouse_magic_t* s=(mouse_magic_t*)opaque;
+
+       if (version_id != 1)
+               return -EINVAL;
+
+       qemu_get_be32s(f, &s->sonic_wall_x);
+       qemu_get_be32s(f, &s->sonic_wall_y);
+       qemu_get_8s(f, &s->sonic_wall_is_orthogonal);
+
+       return 0;
+}
+
+static mouse_magic_t* mouse_magic;
+
+typedef struct {
+       int x,y,w,h;
+} rectangle_t;
+/* In order to calibrate the mouse, we have to know about the bounding boxes
+ * of the last changes. */
+static rectangle_t last_update, before_update;
+static int updates_since_mouse=0;
+
+static int mouse_x,mouse_y;
+static int new_mouse_x,new_mouse_y,new_mouse_z,new_mouse_buttons;
+
+static void init_mouse(int initial_x,int initial_y) {
+       mouse_x=new_mouse_x=initial_x;
+       mouse_y=new_mouse_y=initial_y;
+       new_mouse_z=new_mouse_buttons=0;
+       mouse_magic->calibration = 0;
+}
+
+static void mouse_refresh() {
+       int dx=0,dy=0,dz=new_mouse_z;
+       static int counter=1;
+
+       counter++;
+       if(!mouse_magic->calibration && counter>=2) { counter=0; return; }
+
+       dx=new_mouse_x-mouse_x;
+       dy=new_mouse_y-mouse_y;
+
+       if(mouse_magic->sonic_wall_is_orthogonal) {
+               if(abs(dx)>=mouse_magic->sonic_wall_x) { dx/=2; mouse_x+=dx; }
+               if(abs(dy)>=mouse_magic->sonic_wall_y) { dy/=2; mouse_y+=dy; }
+       } else {
+               if(abs(dx)>=mouse_magic->sonic_wall_x || abs(dy)>=mouse_magic->sonic_wall_y) {
+                       dx/=2; mouse_x+=dx;
+                       dy/=2; mouse_y+=dy;
+               }
+       }
+       //fprintf(stderr,"sending mouse event %d,%d\n",dx,dy);
+       kbd_mouse_event(dx,dy,dz,new_mouse_buttons);
+       mouse_x+=dx;
+       mouse_y+=dy;
+               
+       updates_since_mouse=0;
+}
+
+static int calibration_step=0;
+//static int calibration_count=0;
+
+static void mouse_find_bounding_box_of_difference(int* x,int* y,int* w,int* h) {
+       int i,j,X=*x,Y=*y,W=*w,H=*h;
+       int bpp=screen->depth/8;
+
+       *x=screen->width; *w=-*x;
+       *y=screen->height; *h=-*y;
+       for(i=X;i<X+W;i++)
+               for(j=Y;j<Y+H;j++) {
+                       int offset=i*bpp+j*screen->paddedWidthInBytes;
+                       if(memcmp(mouse_magic->calibration+offset,screen->frameBuffer+offset,bpp)) {
+                               if(i<((*x))) { (*w)+=(*x)-i; (*x)=i; }
+                               if(i>(*x)+(*w)) (*w)=i-(*x);
+                               if(j<(*y)) { (*h)+=(*y)-j; (*y)=j; }
+                               if(j>(*y)+(*h)) (*h)=j-(*y); 
+                       }
+               }
+       if(h>0)
+               memcpy(mouse_magic->calibration+Y*screen->paddedWidthInBytes,
+                               screen->frameBuffer+Y*screen->paddedWidthInBytes,
+                               H*screen->paddedWidthInBytes);
+}
+
+static void start_mouse_calibration() {
+       int size = screen->height*screen->paddedWidthInBytes;
+       if(mouse_magic->calibration)
+               free(mouse_magic->calibration);
+       mouse_magic->calibration = malloc(size);
+       memcpy(mouse_magic->calibration, screen->frameBuffer, size);
+       calibration_step=0;
+       // calibration_count=-1;
+       //calibration_count=1000; updates_since_mouse=1;
+       fprintf(stderr,"Starting mouse calibration:\n");
+}
+
+static void stop_mouse_calibration() {
+       if(mouse_magic->calibration)
+               free(mouse_magic->calibration);
+       mouse_magic->calibration = 0;
+}
+
+static void mouse_calibration_update(int x,int y,int w,int h) {
+       mouse_find_bounding_box_of_difference(&x,&y,&w,&h);
+       if(w<=0 || h<=0)
+               return;
+       last_update.x=x;
+       last_update.y=y;
+       last_update.w=w;
+       last_update.h=h;
+       updates_since_mouse++;
+}
+
+static void mouse_calibration_refresh() {
+       static rectangle_t cursor;
+       static int x,y;
+       static int idle_counter;
+
+       if(calibration_step==0)
+               idle_counter=0;
+       else {
+               if(updates_since_mouse==0) {
+                       idle_counter++;
+                       if(idle_counter>5) {
+                               fprintf(stderr, "Calibration failed: no update for 5 cycles\n");
+                               stop_mouse_calibration();
+                       }
+                       return;
+               }
+               if(updates_since_mouse!=1) {
+                       fprintf(stderr,"Calibration failed: updates=%d\n",updates_since_mouse);
+                       stop_mouse_calibration();
+                       return;
+               }
+       }
+       
+       if(calibration_step==0) {
+               x=0; y=1;
+               kbd_mouse_event(0,-1,0,0);
+               calibration_step++;
+       } else if(calibration_step==1) {
+               // find out the initial position of the cursor
+               cursor=last_update;
+               cursor.h--;
+               calibration_step++;
+               mouse_magic->sonic_wall_y=-1;
+               last_update=cursor;
+               x=0; y=2;
+               goto move_calibrate;
+       } else if(calibration_step==2) {
+               // find out the sonic_wall
+               if(last_update.y==before_update.y-2*y) {
+                       mouse_magic->sonic_wall_y=y;
+                       // test orthogonality
+                       calibration_step++;
+                       x=mouse_magic->sonic_wall_y+1; y=1;
+                       goto move_calibrate;
+               } else if(last_update.y<=2) {
+                       if(y<6)
+                               fprintf(stderr,"Calibration failed: not enough head room!\n");
+                       else
+                               fprintf(stderr,"Calibration finished.\n");
+                       mouse_magic->sonic_wall_x=mouse_magic->sonic_wall_y=32768;
+                       goto stop_calibration;
+               } else if(last_update.y!=before_update.y-y) {
+                       fprintf(stderr,"Calibration failed: delta=%d (expected: %d)\n",last_update.y-before_update.y,-y);
+                       goto stop_calibration;
+               } else {
+                       y++;
+move_calibrate:
+                       kbd_mouse_event(-x,-y,0,0);
+                       before_update=last_update;
+               }
+       } else if(calibration_step==3) {
+               if(last_update.y==before_update.y-2)
+                       mouse_magic->sonic_wall_is_orthogonal=0;
+               else if(last_update.y==before_update.y-1)
+                       mouse_magic->sonic_wall_is_orthogonal=-1;
+               else
+                       fprintf(stderr,"Calibration failed: no clue of orthogonal.\n");
+               mouse_magic->sonic_wall_x=mouse_magic->sonic_wall_y;
+               if(last_update.x==before_update.x-mouse_magic->sonic_wall_x)
+                       mouse_magic->sonic_wall_x++;
+               else if(last_update.x!=before_update.x-x*2)
+                       fprintf(stderr,"Calibration failed: could not determine horizontal sonic wall x\n");
+               fprintf(stderr,"Calibration finished\n");
+stop_calibration:
+               mouse_x=last_update.x;
+               mouse_y=last_update.y;
+               stop_mouse_calibration();
+       }
+       updates_since_mouse=0;
+}
+
+/* end of mouse stuff */
+
+static void vnc_update(DisplayState *ds, int x, int y, int w, int h)
+{
+       if(ds_sdl)
+               ds_sdl->dpy_update(ds_sdl,x,y,w,h);
+       if(0) fprintf(stderr,"updating x=%d y=%d w=%d h=%d\n", x, y, w, h);
+       rfbMarkRectAsModified(screen,x,y,x+w,y+h);
+       if(mouse_magic->calibration) {
+               mouse_calibration_update(x,y,w,h);
+       }
+}
+
+#include <SDL/SDL_video.h>
+extern SDL_PixelFormat* sdl_get_format();
+
+static void vnc_resize(DisplayState *ds, int w, int h)
+{
+       int depth = screen->bitsPerPixel;
+       rfbClientIteratorPtr iter;
+       rfbClientPtr cl;
+
+       if(w==screen->width && h==screen->height)
+               return;
+
+       if(ds_sdl) {
+               SDL_PixelFormat* sdl_format;
+               ds_sdl->dpy_resize(ds_sdl,w,h);
+               ds->data = ds_sdl->data;
+               ds->linesize = screen->paddedWidthInBytes = ds_sdl->linesize;
+               screen->serverFormat.bitsPerPixel = screen->serverFormat.depth
+                       = screen->bitsPerPixel = depth = ds->depth = ds_sdl->depth;
+               w = ds->width = ds_sdl->width;
+               h = ds->height = ds_sdl->height;
+               sdl_format=sdl_get_format();
+               if(sdl_format->palette==0) {
+                       screen->serverFormat.trueColour=TRUE;
+                       screen->serverFormat.redShift=sdl_format->Rshift;
+                       screen->serverFormat.greenShift=sdl_format->Gshift;
+                       screen->serverFormat.blueShift=sdl_format->Bshift;
+                       screen->serverFormat.redMax=sdl_format->Rmask>>screen->serverFormat.redShift;
+                       screen->serverFormat.greenMax=sdl_format->Gmask>>screen->serverFormat.greenShift;
+                       screen->serverFormat.blueMax=sdl_format->Bmask>>screen->serverFormat.blueShift;
+               } else {
+                       rfbColourMap* cmap=&(screen->colourMap);
+                       int i;
+                       screen->serverFormat.trueColour=FALSE;
+                       cmap->is16=FALSE;
+                       cmap->count=sdl_format->palette->ncolors;
+                       if(cmap->data.bytes==0)
+                               cmap->data.bytes=malloc(256*3);
+                       for(i=0;i<cmap->count;i++) {
+                               cmap->data.bytes[3*i+0]=sdl_format->palette->colors[i].r;
+                               cmap->data.bytes[3*i+1]=sdl_format->palette->colors[i].g;
+                               cmap->data.bytes[3*i+2]=sdl_format->palette->colors[i].b;
+                       }
+               }
+       } else {
+               ds->data = (unsigned char*)realloc(ds->data, w*h*depth/8);
+               ds->linesize = screen->paddedWidthInBytes = w*2;
+               ds->width = w;
+               ds->height = h;
+               ds->depth = depth;
+               screen->paddedWidthInBytes = w*depth/8;
+       }
+       screen->frameBuffer = ds->data;
+
+       screen->width = w;
+       screen->height = h;
+
+       iter=rfbGetClientIterator(screen);
+       while((cl=rfbClientIteratorNext(iter)))
+               if(cl->useNewFBSize)
+                       cl->newFBSizePending = TRUE;
+               else
+                       rfbLog("Warning: Client %s does not support NewFBSize!\n",cl->host);
+       rfbReleaseClientIterator(iter);
+
+       if(mouse_magic->calibration) {
+               fprintf(stderr,"Warning: mouse calibration interrupted by video mode change\n");
+               stop_mouse_calibration();
+       }
+       init_mouse(w/2,h/2);
+}
+
+static void vnc_process_key(rfbBool down, rfbKeySym keySym, rfbClientPtr cl)
+{
+       static int magic=0; // Ctrl+Alt starts calibration
+
+       if(is_active_console(vga_console)) {
+               WORD keycode=keysym2scancode(kbd_layout, keySym);
+               if(keycode>=0x80)
+                       keycode=(keycode<<8)^0x80e0;
+               while(keycode!=0) {
+                       kbd_put_keycode((keycode&0xff)|(down?0:0x80));
+                       keycode>>=8;
+               }
+       } else if(down) {
+               kbd_put_keysym(keySym);
+       }
+       if(down) {
+               if(keySym==XK_Control_L)
+                       magic|=1;
+               else if(keySym==XK_Alt_L)
+                       magic|=2;
+       } else {
+               if((magic&3)==3) {
+                       switch(keySym) {
+                               case XK_Control_L:
+                                       magic&=~1;
+                                       break;
+                               case XK_Alt_L:
+                                       magic&=~2;
+                                       break;
+                               case XK_m:
+                                       magic=0;
+                                       start_mouse_calibration();
+                                       break;
+                               case XK_1 ... XK_9:
+                                       magic=0;
+                                       fprintf(stderr,"switch to %d\n",keySym-XK_1);
+                                       console_select(keySym - XK_1);
+                                       if (is_active_console(vga_console)) {
+                                               /* tell the vga console to redisplay itself */
+                                               vga_invalidate_display();
+                                               vnc_update(0,0,0,screen->width,screen->height);
+                                       }
+                                       break;
+                       }
+               }
+       }
+}
+
+static void vnc_process_mouse(int buttonMask, int x, int y, rfbClientPtr cl)
+{
+       new_mouse_x=x; new_mouse_y=y; new_mouse_buttons=0;
+       if(buttonMask&1) new_mouse_buttons|=MOUSE_EVENT_LBUTTON;
+       if(buttonMask&2) new_mouse_buttons|=MOUSE_EVENT_MBUTTON;
+       if(buttonMask&4) new_mouse_buttons|=MOUSE_EVENT_RBUTTON;
+       if(buttonMask&8) new_mouse_z--;
+       if(buttonMask&16) new_mouse_z++;
+}
+
+       static void vnc_refresh(DisplayState *ds) {
+               if(ds_sdl)
+                       ds_sdl->dpy_refresh(ds_sdl);
+               else
+                       vga_update_display();
+               rfbProcessEvents(screen,0);
+               if(mouse_magic->calibration) {
+                       mouse_calibration_refresh();
+               } else {
+                       mouse_refresh();
+               }
+       }
+
+static void vnc_cleanup(void) 
+{
+       rfbScreenCleanup(screen);
+}
+
+void vnc_display_init(DisplayState *ds, int useAlsoSDL)
+{
+       if(!keyboard_layout) {
+               fprintf(stderr, "No keyboard language specified\n");
+               exit(1);
+       }
+
+       kbd_layout=init_keyboard_layout(keyboard_layout);
+       if(!kbd_layout) {
+               fprintf(stderr, "Could not initialize keyboard\n");
+               exit(1);
+       }
+
+       mouse_magic=init_mouse_magic();
+       register_savevm("vnc", 0, 1, vnc_save, vnc_load, mouse_magic);
+
+       rfbLog=rfbErr=term_printf;
+       screen=rfbGetScreen(0,0,0,0,5,3,2);
+       if(screen==0) {
+               fprintf(stderr, "Could not initialize VNC - exiting\n");
+               exit(1);
+       }
+
+       screen->serverFormat.redShift = 11;
+       screen->serverFormat.greenShift = 5;
+       screen->serverFormat.blueShift = 0;
+       screen->serverFormat.redMax = 31;
+       screen->serverFormat.greenMax = 63;
+       screen->serverFormat.blueMax = 31;
+
+       if(useAlsoSDL) {
+               ds_sdl=(DisplayState*)malloc(sizeof(DisplayState));
+               sdl_display_init(ds_sdl,0);
+               screen->frameBuffer = ds_sdl->data;
+       } else
+               screen->frameBuffer = malloc(640*400*2);
+
+       screen->desktopName = "QEMU/VNC";
+       screen->cursor = 0;
+       screen->kbdAddEvent = vnc_process_key;
+       screen->ptrAddEvent = vnc_process_mouse;
+       rfbInitServer(screen);
+
+       vnc_resize(ds,640,400);
+
+       ds->dpy_update = vnc_update;
+       ds->dpy_resize = vnc_resize;
+       ds->dpy_refresh = vnc_refresh;
+
+       atexit(vnc_cleanup);
+}
+